diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java index 29782788a..7b7322b8e 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/RESTServiceModule.java @@ -39,6 +39,7 @@ import org.apache.guacamole.rest.connectiongroup.ConnectionGroupModule; import org.apache.guacamole.rest.language.LanguageRESTService; import org.apache.guacamole.rest.patch.PatchRESTService; import org.apache.guacamole.rest.session.SessionResourceFactory; +import org.apache.guacamole.rest.sharingprofile.SharingProfileModule; import org.apache.guacamole.rest.user.UserModule; /** @@ -96,6 +97,7 @@ public class RESTServiceModule extends ServletModule { install(new ActiveConnectionModule()); install(new ConnectionModule()); install(new ConnectionGroupModule()); + install(new SharingProfileModule()); install(new UserModule()); // Set up the servlet and JSON mappings diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java index b1a796e16..36e639cf3 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/history/APIConnectionRecord.java @@ -39,6 +39,16 @@ public class APIConnectionRecord { */ private final String connectionName; + /** + * The identifier of the sharing profile associated with this record. + */ + private final String sharingProfileIdentifier; + + /** + * The identifier of the sharing profile associated with this record. + */ + private final String sharingProfileName; + /** * The date and time the connection began. */ @@ -73,13 +83,15 @@ public class APIConnectionRecord { * The record to copy data from. */ public APIConnectionRecord(ConnectionRecord record) { - this.connectionIdentifier = record.getConnectionIdentifier(); - this.connectionName = record.getConnectionName(); - this.startDate = record.getStartDate(); - this.endDate = record.getEndDate(); - this.remoteHost = record.getRemoteHost(); - this.username = record.getUsername(); - this.active = record.isActive(); + this.connectionIdentifier = record.getConnectionIdentifier(); + this.connectionName = record.getConnectionName(); + this.sharingProfileIdentifier = record.getSharingProfileIdentifier(); + this.sharingProfileName = record.getSharingProfileName(); + this.startDate = record.getStartDate(); + this.endDate = record.getEndDate(); + this.remoteHost = record.getRemoteHost(); + this.username = record.getUsername(); + this.active = record.isActive(); } /** @@ -103,6 +115,32 @@ public class APIConnectionRecord { return connectionName; } + /** + * Returns the identifier of the sharing profile associated with this + * record. If the connection was not being used via a sharing profile, this + * will be null. + * + * @return + * The identifier of the sharing profile associated with this record, + * or null if no sharing profile was used. + */ + public String getSharingProfileIdentifier() { + return sharingProfileIdentifier; + } + + /** + * Returns the name of the sharing profile associated with this record. If + * the connection was not being used via a sharing profile, this will be + * null. + * + * @return + * The name of the sharing profile associated with this record, or null + * if no sharing profile was used. + */ + public String getSharingProfileName() { + return sharingProfileName; + } + /** * Returns the date and time the connection began. * diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/permission/APIPermissionSet.java b/guacamole/src/main/java/org/apache/guacamole/rest/permission/APIPermissionSet.java index 7439401b7..5c15a2b9f 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/permission/APIPermissionSet.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/permission/APIPermissionSet.java @@ -53,6 +53,12 @@ public class APIPermissionSet { private Map> connectionGroupPermissions = new HashMap>(); + /** + * Map of sharing profile ID to the set of granted permissions. + */ + private Map> sharingProfilePermissions = + new HashMap>(); + /** * Map of active connection ID to the set of granted permissions. */ @@ -155,6 +161,7 @@ public class APIPermissionSet { addSystemPermissions(systemPermissions, user.getSystemPermissions()); addObjectPermissions(connectionPermissions, user.getConnectionPermissions()); addObjectPermissions(connectionGroupPermissions, user.getConnectionGroupPermissions()); + addObjectPermissions(sharingProfilePermissions, user.getSharingProfilePermissions()); addObjectPermissions(activeConnectionPermissions, user.getActiveConnectionPermissions()); addObjectPermissions(userPermissions, user.getUserPermissions()); @@ -190,6 +197,21 @@ public class APIPermissionSet { return connectionGroupPermissions; } + /** + * Returns a map of sharing profile identifiers to the set of permissions + * granted for that sharing profile. If no permissions are granted to a + * particular sharing profile, its identifier will not be present as a key + * in the map. This map is mutable, and changes to this map will affect the + * permission set directly. + * + * @return + * A map of sharing profile identifiers to the set of permissions + * granted for that sharing profile. + */ + public Map> getSharingProfilePermissions() { + return sharingProfilePermissions; + } + /** * Returns a map of active connection IDs to the set of permissions granted * for that active connection. If no permissions are granted to a particular @@ -257,6 +279,19 @@ public class APIPermissionSet { this.connectionGroupPermissions = connectionGroupPermissions; } + /** + * Replaces the current map of sharing profile permissions with the given + * map, which must map each sharing profile identifier to its corresponding + * set of granted permissions. If a sharing profile has no permissions, its + * identifier must not be present as a key in the map. + * + * @param sharingProfilePermissions + * The map which must replace the currently-stored map of permissions. + */ + public void setSharingProfilePermissions(Map> sharingProfilePermissions) { + this.sharingProfilePermissions = sharingProfilePermissions; + } + /** * Replaces the current map of active connection permissions with the give * map, which must map active connection ID to its corresponding set of diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java index e75460ccc..3ad005c42 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/permission/PermissionSetResource.java @@ -55,6 +55,12 @@ public class PermissionSetResource { */ private static final String CONNECTION_GROUP_PERMISSION_PATCH_PATH_PREFIX = "/connectionGroupPermissions/"; + /** + * The prefix of any path within an operation of a JSON patch which + * modifies the permissions of a user regarding a specific sharing profile. + */ + private static final String SHARING_PROFILE_PERMISSION_PATCH_PATH_PREFIX = "/sharingProfilePermissions/"; + /** * The prefix of any path within an operation of a JSON patch which * modifies the permissions of a user regarding a specific active connection. @@ -170,6 +176,7 @@ public class PermissionSetResource { // Permission patches for all types of permissions PermissionSetPatch connectionPermissionPatch = new PermissionSetPatch(); PermissionSetPatch connectionGroupPermissionPatch = new PermissionSetPatch(); + PermissionSetPatch sharingProfilePermissionPatch = new PermissionSetPatch(); PermissionSetPatch activeConnectionPermissionPatch = new PermissionSetPatch(); PermissionSetPatch userPermissionPatch = new PermissionSetPatch(); PermissionSetPatch systemPermissionPatch = new PermissionSetPatch(); @@ -205,6 +212,19 @@ public class PermissionSetResource { } + // Create sharing profile permission if path has sharing profileprefix + else if (path.startsWith(SHARING_PROFILE_PERMISSION_PATCH_PATH_PREFIX)) { + + // Get identifier and type from patch operation + String identifier = path.substring(SHARING_PROFILE_PERMISSION_PATCH_PATH_PREFIX.length()); + ObjectPermission.Type type = ObjectPermission.Type.valueOf(patch.getValue()); + + // Create and update corresponding permission + ObjectPermission permission = new ObjectPermission(type, identifier); + updatePermissionSet(patch.getOp(), sharingProfilePermissionPatch, permission); + + } + // Create active connection permission if path has active connection prefix else if (path.startsWith(ACTIVE_CONNECTION_PERMISSION_PATCH_PATH_PREFIX)) { @@ -252,6 +272,7 @@ public class PermissionSetResource { // Save the permission changes connectionPermissionPatch.apply(user.getConnectionPermissions()); connectionGroupPermissionPatch.apply(user.getConnectionGroupPermissions()); + sharingProfilePermissionPatch.apply(user.getSharingProfilePermissions()); activeConnectionPermissionPatch.apply(user.getActiveConnectionPermissions()); userPermissionPatch.apply(user.getUserPermissions()); systemPermissionPatch.apply(user.getSystemPermissions()); diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java index e0c88555e..31bb002dc 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java @@ -32,6 +32,7 @@ import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.net.auth.ActiveConnection; import org.apache.guacamole.net.auth.Connection; import org.apache.guacamole.net.auth.ConnectionGroup; +import org.apache.guacamole.net.auth.SharingProfile; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.UserContext; import org.apache.guacamole.rest.activeconnection.APIActiveConnection; @@ -39,6 +40,7 @@ import org.apache.guacamole.rest.connection.APIConnection; import org.apache.guacamole.rest.connectiongroup.APIConnectionGroup; import org.apache.guacamole.rest.history.HistoryResource; import org.apache.guacamole.rest.schema.SchemaResource; +import org.apache.guacamole.rest.sharingprofile.APISharingProfile; import org.apache.guacamole.rest.user.APIUser; /** @@ -79,6 +81,14 @@ public class UserContextResource { private DirectoryResourceFactory connectionGroupDirectoryResourceFactory; + /** + * Factory for creating DirectoryResources which expose a given + * SharingProfile Directory. + */ + @Inject + private DirectoryResourceFactory + sharingProfileDirectoryResourceFactory; + /** * Factory for creating DirectoryResources which expose a given * User Directory. @@ -153,6 +163,24 @@ public class UserContextResource { userContext.getConnectionGroupDirectory()); } + /** + * Returns a new resource which represents the SharingProfile Directory + * contained within the UserContext exposed by this UserContextResource. + * + * @return + * A new resource which represents the SharingProfile Directory + * contained within the UserContext exposed by this UserContextResource. + * + * @throws GuacamoleException + * If an error occurs while retrieving the SharingProfile Directory. + */ + @Path("sharingProfiles") + public DirectoryResource + getSharingProfileDirectoryResource() throws GuacamoleException { + return sharingProfileDirectoryResourceFactory.create(userContext, + userContext.getSharingProfileDirectory()); + } + /** * Returns a new resource which represents the User Directory contained * within the UserContext exposed by this UserContextResource. diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfile.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfile.java new file mode 100644 index 000000000..822bcee7f --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfile.java @@ -0,0 +1,207 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.guacamole.rest.sharingprofile; + +import java.util.Map; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.apache.guacamole.net.auth.SharingProfile; + +/** + * The external representation used by the REST API for sharing profiles. + * + * @author Michael Jumper + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class APISharingProfile { + + /** + * The human-readable name of this sharing profile. + */ + private String name; + + /** + * The unique string which identifies this sharing profile within its + * containing directory. + */ + private String identifier; + + /** + * The identifier of the primary connection that this sharing profile + * can be used to share. + */ + private String primaryConnectionIdentifier; + + /** + * Map of all associated connection parameter values which apply when the + * sharing profile is used, indexed by parameter name. + */ + private Map parameters; + + /** + * Map of all associated attributes by attribute identifier. + */ + private Map attributes; + + /** + * Creates an empty, uninitialized APISharingProfile. The properties of the + * created APISharingProfile will need to be set individually as necessary + * via their corresponding setters. + */ + public APISharingProfile() {} + + /** + * Creates a new APISharingProfile with its data populated from that of an + * existing SharingProfile. As the connection parameters of the + * SharingProfile are potentially sensitive, they will not be included in + * the new APISharingProfile. + * + * @param sharingProfile + * The sharing profile to use to populate the data of the new + * APISharingProfile. + */ + public APISharingProfile(SharingProfile sharingProfile) { + + // Set main information + this.name = sharingProfile.getName(); + this.identifier = sharingProfile.getIdentifier(); + this.primaryConnectionIdentifier = sharingProfile.getPrimaryConnectionIdentifier(); + + // Associate any attributes + this.attributes = sharingProfile.getAttributes(); + + } + + /** + * Returns the human-readable name of this sharing profile. + * + * @return + * The human-readable name of this sharing profile. + */ + public String getName() { + return name; + } + + /** + * Set the human-readable name of this sharing profile. + * + * @param name + * The human-readable name of this sharing profile. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the unique string which identifies this sharing profile within + * its containing directory. + * + * @return + * The unique string which identifies this sharing profile within its + * containing directory. + */ + public String getIdentifier() { + return identifier; + } + + /** + * Sets the unique string which identifies this sharing profile within + * its containing directory. + * + * @param identifier + * The unique string which identifies this sharing profile within its + * containing directory. + */ + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + /** + * Returns the identifier of the primary connection that this sharing + * profile can be used to share. + * + * @return + * The identifier of the primary connection that this sharing profile + * can be used to share. + */ + public String getPrimaryConnectionIdentifier() { + return primaryConnectionIdentifier; + } + + /** + * Sets the identifier of the primary connection that this sharing profile + * can be used to share. + * + * @param primaryConnectionIdentifier + * The identifier of the primary connection that this sharing profile + * can be used to share. + */ + public void setPrimaryConnectionIdentifier(String primaryConnectionIdentifier) { + this.primaryConnectionIdentifier = primaryConnectionIdentifier; + } + + /** + * Returns a map of all associated connection parameter values which apply + * when the sharing profile is used, indexed by parameter name. + * + * @return + * A map of all associated connection parameter values which apply when + * the sharing profile is used, indexed by parameter name. + */ + public Map getParameters() { + return parameters; + } + + /** + * Sets the map of all associated connection parameter values which apply + * when the sharing profile is used, indexed by parameter name. + * + * @param parameters + * The map of all associated connection parameter values which apply + * when the sharing profile is used, indexed by parameter name. + */ + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + /** + * Returns a map of all attributes associated with this sharing profile. + * Each entry key is the attribute identifier, while each value is the + * attribute value itself. + * + * @return + * The attribute map for this sharing profile. + */ + public Map getAttributes() { + return attributes; + } + + /** + * Sets the map of all attributes associated with this sharing profile. Each + * entry key is the attribute identifier, while each value is the attribute + * value itself. + * + * @param attributes + * The attribute map for this sharing profile. + */ + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfileWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfileWrapper.java new file mode 100644 index 000000000..effb1d43a --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/APISharingProfileWrapper.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.guacamole.rest.sharingprofile; + +import java.util.Map; +import org.apache.guacamole.net.auth.SharingProfile; + +/** + * Wrapper for APISharingProfile which provides a SharingProfile interface. + * Changes to the underlying APISharingProfile are reflected immediately in the + * values exposed by the SharingProfile interface, and changes made through the + * SharingProfile interface immediately affect the underlying APISharingProfile. + * + * @author Michael Jumper + */ +public class APISharingProfileWrapper implements SharingProfile { + + /** + * The wrapped APISharingProfile. + */ + private final APISharingProfile apiSharingProfile; + + /** + * Creates a new APISharingProfileWrapper which is backed by the given + * APISharingProfile. + * + * @param apiSharingProfile + * The APISharingProfile to wrap. + */ + public APISharingProfileWrapper(APISharingProfile apiSharingProfile) { + this.apiSharingProfile = apiSharingProfile; + } + + @Override + public String getName() { + return apiSharingProfile.getName(); + } + + @Override + public void setName(String name) { + apiSharingProfile.setName(name); + } + + @Override + public String getIdentifier() { + return apiSharingProfile.getIdentifier(); + } + + @Override + public void setIdentifier(String identifier) { + apiSharingProfile.setIdentifier(identifier); + } + + @Override + public String getPrimaryConnectionIdentifier() { + return apiSharingProfile.getPrimaryConnectionIdentifier(); + } + + @Override + public void setPrimaryConnectionIdentifier(String primaryConnectionIdentifier) { + apiSharingProfile.setPrimaryConnectionIdentifier(primaryConnectionIdentifier); + } + + @Override + public Map getParameters() { + return apiSharingProfile.getParameters(); + } + + @Override + public void setParameters(Map parameters) { + apiSharingProfile.setParameters(parameters); + } + + @Override + public Map getAttributes() { + return apiSharingProfile.getAttributes(); + } + + @Override + public void setAttributes(Map attributes) { + apiSharingProfile.setAttributes(attributes); + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileDirectoryResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileDirectoryResource.java new file mode 100644 index 000000000..3371fdb16 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileDirectoryResource.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.guacamole.rest.sharingprofile; + +import com.google.inject.assistedinject.Assisted; +import com.google.inject.assistedinject.AssistedInject; +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.apache.guacamole.net.auth.Directory; +import org.apache.guacamole.net.auth.SharingProfile; +import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.rest.directory.DirectoryObjectResourceFactory; +import org.apache.guacamole.rest.directory.DirectoryObjectTranslator; +import org.apache.guacamole.rest.directory.DirectoryResource; + +/** + * A REST resource which abstracts the operations available on a Directory of + * SharingProfiles. + * + * @author Michael Jumper + */ +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class SharingProfileDirectoryResource + extends DirectoryResource { + + /** + * Creates a new SharingProfileDirectoryResource which exposes the + * operations and subresources available for the given SharingProfile + * Directory. + * + * @param userContext + * The UserContext associated with the given Directory. + * + * @param directory + * The Directory being exposed. + * + * @param translator + * A DirectoryObjectTranslator implementation which handles + * SharingProfiles. + * + * @param resourceFactory + * A factory which can be used to create instances of resources + * representing SharingProfiles. + */ + @AssistedInject + public SharingProfileDirectoryResource(@Assisted UserContext userContext, + @Assisted Directory directory, + DirectoryObjectTranslator translator, + DirectoryObjectResourceFactory resourceFactory) { + super(userContext, directory, translator, resourceFactory); + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileModule.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileModule.java new file mode 100644 index 000000000..dabec70f5 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileModule.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.guacamole.rest.sharingprofile; + +import com.google.inject.AbstractModule; +import org.apache.guacamole.rest.directory.DirectoryObjectResourceFactory; +import org.apache.guacamole.rest.directory.DirectoryObjectResource; +import com.google.inject.TypeLiteral; +import com.google.inject.assistedinject.FactoryModuleBuilder; +import org.apache.guacamole.net.auth.SharingProfile; +import org.apache.guacamole.rest.directory.DirectoryObjectTranslator; +import org.apache.guacamole.rest.directory.DirectoryResource; +import org.apache.guacamole.rest.directory.DirectoryResourceFactory; + +/** + * Guice Module which configures injections required for handling SharingProfile + * resources via the REST API. + * + * @author Michael Jumper + */ +public class SharingProfileModule extends AbstractModule { + + @Override + protected void configure() { + + // Create the required DirectoryResourceFactory implementation + install(new FactoryModuleBuilder() + .implement( + new TypeLiteral>() {}, + SharingProfileDirectoryResource.class + ) + .build(new TypeLiteral>() {})); + + // Create the required DirectoryObjectResourceFactory implementation + install(new FactoryModuleBuilder() + .implement( + new TypeLiteral>() {}, + SharingProfileResource.class + ) + .build(new TypeLiteral>() {})); + + // Bind translator for converting between SharingProfile and APISharingProfile + bind(new TypeLiteral>() {}) + .to(SharingProfileObjectTranslator.class); + + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileObjectTranslator.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileObjectTranslator.java new file mode 100644 index 000000000..42dbc1cad --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileObjectTranslator.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.guacamole.rest.sharingprofile; + +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.net.auth.SharingProfile; +import org.apache.guacamole.rest.directory.DirectoryObjectTranslator; + +/** + * Translator which converts between SharingProfile objects and + * APISharingProfile objects. + * + * @author Michael Jumper + */ +public class SharingProfileObjectTranslator + implements DirectoryObjectTranslator { + + @Override + public APISharingProfile toExternalObject(SharingProfile object) + throws GuacamoleException { + return new APISharingProfile(object); + } + + @Override + public SharingProfile toInternalObject(APISharingProfile object) { + return new APISharingProfileWrapper(object); + } + + @Override + public void applyExternalChanges(SharingProfile existingObject, + APISharingProfile object) { + + // Update the sharing profile + existingObject.setPrimaryConnectionIdentifier(object.getPrimaryConnectionIdentifier()); + existingObject.setName(object.getName()); + existingObject.setParameters(object.getParameters()); + existingObject.setAttributes(object.getAttributes()); + + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileResource.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileResource.java new file mode 100644 index 000000000..debf804b2 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/SharingProfileResource.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.guacamole.rest.sharingprofile; + +import com.google.inject.assistedinject.Assisted; +import com.google.inject.assistedinject.AssistedInject; +import java.util.Map; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleSecurityException; +import org.apache.guacamole.net.auth.Directory; +import org.apache.guacamole.net.auth.SharingProfile; +import org.apache.guacamole.net.auth.User; +import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.net.auth.permission.ObjectPermission; +import org.apache.guacamole.net.auth.permission.ObjectPermissionSet; +import org.apache.guacamole.net.auth.permission.SystemPermission; +import org.apache.guacamole.net.auth.permission.SystemPermissionSet; +import org.apache.guacamole.rest.directory.DirectoryObjectResource; +import org.apache.guacamole.rest.directory.DirectoryObjectTranslator; + +/** + * A REST resource which abstracts the operations available on an existing + * SharingProfile. + * + * @author Michael Jumper + */ +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class SharingProfileResource + extends DirectoryObjectResource { + + /** + * The UserContext associated with the Directory which contains the + * SharingProfile exposed by this resource. + */ + private final UserContext userContext; + + /** + * The SharingProfile object represented by this SharingProfileResource. + */ + private final SharingProfile sharingProfile; + + /** + * Creates a new SharingProfileResource which exposes the operations and + * subresources available for the given SharingProfile. + * + * @param userContext + * The UserContext associated with the given Directory. + * + * @param directory + * The Directory which contains the given SharingProfile. + * + * @param sharingProfile + * The SharingProfile that this SharingProfileResource should represent. + * + * @param translator + * A DirectoryObjectTranslator implementation which handles the type of + * object given. + */ + @AssistedInject + public SharingProfileResource(@Assisted UserContext userContext, + @Assisted Directory directory, + @Assisted SharingProfile sharingProfile, + DirectoryObjectTranslator translator) { + super(directory, sharingProfile, translator); + this.userContext = userContext; + this.sharingProfile = sharingProfile; + } + + /** + * Retrieves the connection parameters associated with the SharingProfile + * exposed by this SharingProfile resource. + * + * @return + * A map of parameter name/value pairs. + * + * @throws GuacamoleException + * If an error occurs while retrieving the connection parameters of the + * SharingProfile. + */ + @GET + @Path("parameters") + public Map getParameters() + throws GuacamoleException { + + User self = userContext.self(); + + // Retrieve permission sets + SystemPermissionSet systemPermissions = self.getSystemPermissions(); + ObjectPermissionSet sharingProfilePermissions = self.getSharingProfilePermissions(); + + // Deny access if adminstrative or update permission is missing + String identifier = sharingProfile.getIdentifier(); + if (!systemPermissions.hasPermission(SystemPermission.Type.ADMINISTER) + && !sharingProfilePermissions.hasPermission(ObjectPermission.Type.UPDATE, identifier)) + throw new GuacamoleSecurityException("Permission to read sharing profile parameters denied."); + + // Return parameter map + return sharingProfile.getParameters(); + + } + +} diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/package-info.java b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/package-info.java new file mode 100644 index 000000000..53a76f710 --- /dev/null +++ b/guacamole/src/main/java/org/apache/guacamole/rest/sharingprofile/package-info.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Classes related to retrieving or manipulating sharing profiles using the + * Guacamole REST API. + */ +package org.apache.guacamole.rest.sharingprofile; + diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java b/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java index f9a05bb38..cef6aec88 100644 --- a/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java +++ b/guacamole/src/main/java/org/apache/guacamole/rest/user/APIUserWrapper.java @@ -97,6 +97,11 @@ public class APIUserWrapper implements User { throw new GuacamoleUnsupportedException("APIUserWrapper does not provide permission access."); } + @Override + public ObjectPermissionSet getSharingProfilePermissions() throws GuacamoleException { + throw new GuacamoleUnsupportedException("APIUserWrapper does not provide permission access."); + } + @Override public ObjectPermissionSet getUserPermissions() throws GuacamoleException {