You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/01/30 19:32:14 UTC

[3/9] guacamole-client git commit: GUACAMOLE-96: Invoke decorate() for all AuthenticationProviders when creating or updating the UserContext.

GUACAMOLE-96: Invoke decorate() for all AuthenticationProviders when creating or updating the UserContext.


Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/a745569f
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/a745569f
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/a745569f

Branch: refs/heads/master
Commit: a745569f1303dd2f1f4a16190096680d53dbc9cd
Parents: 41059f5
Author: Michael Jumper <mj...@apache.org>
Authored: Fri Oct 27 14:30:42 2017 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Sat Jan 13 17:23:08 2018 -0800

----------------------------------------------------------------------
 .../org/apache/guacamole/GuacamoleSession.java  |  13 +-
 .../rest/auth/AuthenticationService.java        |  25 ++--
 .../rest/auth/DecoratedUserContext.java         | 147 +++++++++++++++++++
 .../guacamole/rest/auth/TokenRESTService.java   |   2 +-
 4 files changed, 170 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/a745569f/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java b/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java
index e723c0a..24ea196 100644
--- a/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java
+++ b/guacamole/src/main/java/org/apache/guacamole/GuacamoleSession.java
@@ -28,6 +28,7 @@ import org.apache.guacamole.net.GuacamoleTunnel;
 import org.apache.guacamole.net.auth.AuthenticatedUser;
 import org.apache.guacamole.net.auth.AuthenticationProvider;
 import org.apache.guacamole.net.auth.UserContext;
+import org.apache.guacamole.rest.auth.DecoratedUserContext;
 import org.apache.guacamole.tunnel.UserTunnel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -52,7 +53,7 @@ public class GuacamoleSession {
      * All UserContexts associated with this session. Each
      * AuthenticationProvider may provide its own UserContext.
      */
-    private List<UserContext> userContexts;
+    private List<DecoratedUserContext> userContexts;
 
     /**
      * All currently-active tunnels, indexed by tunnel UUID.
@@ -84,7 +85,7 @@ public class GuacamoleSession {
      */
     public GuacamoleSession(Environment environment,
             AuthenticatedUser authenticatedUser,
-            List<UserContext> userContexts)
+            List<DecoratedUserContext> userContexts)
             throws GuacamoleException {
         this.lastAccessedTime = System.currentTimeMillis();
         this.authenticatedUser = authenticatedUser;
@@ -121,7 +122,7 @@ public class GuacamoleSession {
      *     An unmodifiable list of all UserContexts associated with this
      *     session.
      */
-    public List<UserContext> getUserContexts() {
+    public List<DecoratedUserContext> getUserContexts() {
         return Collections.unmodifiableList(userContexts);
     }
 
@@ -141,12 +142,12 @@ public class GuacamoleSession {
      * @throws GuacamoleException
      *     If no such UserContext exists.
      */
-    public UserContext getUserContext(String authProviderIdentifier)
+    public DecoratedUserContext getUserContext(String authProviderIdentifier)
             throws GuacamoleException {
 
         // Locate and return the UserContext associated with the
         // AuthenticationProvider having the given identifier, if any
-        for (UserContext userContext : getUserContexts()) {
+        for (DecoratedUserContext userContext : getUserContexts()) {
 
             // Get AuthenticationProvider associated with current UserContext
             AuthenticationProvider authProvider = userContext.getAuthenticationProvider();
@@ -170,7 +171,7 @@ public class GuacamoleSession {
      * @param userContexts
      *     The List of UserContexts to associate with this session.
      */
-    public void setUserContexts(List<UserContext> userContexts) {
+    public void setUserContexts(List<DecoratedUserContext> userContexts) {
         this.userContexts = userContexts;
     }
     

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/a745569f/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java
index fb118e1..b6572f8 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/AuthenticationService.java
@@ -343,26 +343,30 @@ public class AuthenticationService {
      * @throws GuacamoleException
      *     If an error occurs while creating or updating any UserContext.
      */
-    private List<UserContext> getUserContexts(GuacamoleSession existingSession,
+    private List<DecoratedUserContext> getUserContexts(GuacamoleSession existingSession,
             AuthenticatedUser authenticatedUser, Credentials credentials)
             throws GuacamoleException {
 
-        List<UserContext> userContexts = new ArrayList<UserContext>(authProviders.size());
+        List<DecoratedUserContext> userContexts =
+                new ArrayList<DecoratedUserContext>(authProviders.size());
 
         // If UserContexts already exist, update them and add to the list
         if (existingSession != null) {
 
             // Update all old user contexts
-            List<UserContext> oldUserContexts = existingSession.getUserContexts();
-            for (UserContext oldUserContext : oldUserContexts) {
+            List<DecoratedUserContext> oldUserContexts = existingSession.getUserContexts();
+            for (DecoratedUserContext userContext : oldUserContexts) {
+
+                UserContext oldUserContext = userContext.getOriginal();
 
                 // Update existing UserContext
                 AuthenticationProvider authProvider = oldUserContext.getAuthenticationProvider();
-                UserContext userContext = authProvider.updateUserContext(oldUserContext, authenticatedUser, credentials);
+                UserContext updatedUserContext = authProvider.updateUserContext(oldUserContext, authenticatedUser, credentials);
 
                 // Add to available data, if successful
-                if (userContext != null)
-                    userContexts.add(userContext);
+                if (updatedUserContext != null)
+                    userContexts.add(new DecoratedUserContext(updatedUserContext,
+                            authenticatedUser, credentials, authProviders));
 
                 // If unsuccessful, log that this happened, as it may be a bug
                 else
@@ -384,7 +388,8 @@ public class AuthenticationService {
 
                 // Add to available data, if successful
                 if (userContext != null)
-                    userContexts.add(userContext);
+                    userContexts.add(new DecoratedUserContext(userContext,
+                            authenticatedUser, credentials, authProviders));
 
             }
 
@@ -428,7 +433,7 @@ public class AuthenticationService {
 
         // Get up-to-date AuthenticatedUser and associated UserContexts
         AuthenticatedUser authenticatedUser = getAuthenticatedUser(existingSession, credentials);
-        List<UserContext> userContexts = getUserContexts(existingSession, authenticatedUser, credentials);
+        List<DecoratedUserContext> userContexts = getUserContexts(existingSession, authenticatedUser, credentials);
 
         // Update existing session, if it exists
         String authToken;
@@ -513,7 +518,7 @@ public class AuthenticationService {
      * @throws GuacamoleException
      *     If the auth token does not correspond to any logged in user.
      */
-    public List<UserContext> getUserContexts(String authToken)
+    public List<DecoratedUserContext> getUserContexts(String authToken)
             throws GuacamoleException {
         return getGuacamoleSession(authToken).getUserContexts();
     }

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/a745569f/guacamole/src/main/java/org/apache/guacamole/rest/auth/DecoratedUserContext.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/DecoratedUserContext.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/DecoratedUserContext.java
new file mode 100644
index 0000000..69b6846
--- /dev/null
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/DecoratedUserContext.java
@@ -0,0 +1,147 @@
+/*
+ * 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.auth;
+
+import java.util.List;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.AuthenticatedUser;
+import org.apache.guacamole.net.auth.AuthenticationProvider;
+import org.apache.guacamole.net.auth.Credentials;
+import org.apache.guacamole.net.auth.DelegatingUserContext;
+import org.apache.guacamole.net.auth.UserContext;
+
+/**
+ * A UserContext which has been decorated by all applicable
+ * AuthenticationProviders.
+ */
+public class DecoratedUserContext extends DelegatingUserContext {
+
+    /**
+     * The original, undecorated UserContext.
+     */
+    private final UserContext original;
+
+    /**
+     * Repeatedly decorates the given UserContext, invoking the decorate()
+     * function of each given AuthenticationProvider, wrapping the UserContext
+     * within successive layers of decoration. The AuthenticationProvider which
+     * originated the given UserContext will be ignored.
+     *
+     * @param userContext
+     *     The UserContext to decorate.
+     *
+     * @param authenticatedUser
+     *     The AuthenticatedUser identifying the user associated with the given
+     *     UserContext.
+     *
+     * @param credentials
+     *     The credentials associated with the request which produced the given
+     *     UserContext.
+     *
+     * @param authProviders
+     *     The AuthenticationProviders which should be used to decorate the
+     *     given UserContext. The order of this list dictates the order in
+     *     which each AuthenticationProvider's decorate() function will be
+     *     invoked.
+     *
+     * @return
+     *     A UserContext instance which has been decorated (wrapped) by all
+     *     applicable AuthenticationProviders.
+     *
+     * @throws GuacamoleException
+     *     If any of the given AuthenticationProviders fails while decorating
+     *     the UserContext.
+     */
+    private static UserContext decorate(UserContext userContext,
+            AuthenticatedUser authenticatedUser, Credentials credentials,
+            List<AuthenticationProvider> authProviders) throws GuacamoleException {
+
+        AuthenticationProvider owner = userContext.getAuthenticationProvider();
+
+        // Poll each AuthenticationProvider to decorate the given UserContext
+        for (AuthenticationProvider authProvider : authProviders) {
+
+            // Skip the AuthenticationProvider which produced the UserContext
+            // being decorated
+            if (authProvider == owner)
+                continue;
+
+            // Apply next layer of wrapping around UserContext
+            UserContext decorated = authProvider.decorate(userContext,
+                    authenticatedUser, credentials);
+
+            // Do not allow misbehaving extensions to wipe out the
+            // UserContext entirely
+            if (decorated != null)
+                userContext = decorated;
+
+        }
+
+        return userContext;
+
+    }
+
+    /**
+     * Creates a new DecoratedUserContext, invoking the the decorate() function
+     * of the given AuthenticationProviders to decorate the provided
+     * UserContext. Decoration by each AuthenticationProvider will occur in the
+     * order given. Only AuthenticationProviders which did not originate the
+     * given UserContext will be used.
+     *
+     * @param userContext
+     *     The UserContext to decorate.
+     *
+     * @param authenticatedUser
+     *     The AuthenticatedUser identifying the user associated with the given
+     *     UserContext.
+     *
+     * @param credentials
+     *     The credentials associated with the request which produced the given
+     *     UserContext.
+     *
+     * @param authProviders
+     *     The AuthenticationProviders which should be used to decorate the
+     *     given UserContext. The order of this list dictates the order in
+     *     which each AuthenticationProvider's decorate() function will be
+     *     invoked.
+     *
+     * @throws GuacamoleException
+     *     If any of the given AuthenticationProviders fails while decorating
+     *     the UserContext.
+     */
+    public DecoratedUserContext(UserContext userContext,
+            AuthenticatedUser authenticatedUser, Credentials credentials,
+            List<AuthenticationProvider> authProviders) throws GuacamoleException {
+        super(decorate(userContext, authenticatedUser, credentials, authProviders));
+        this.original = userContext;
+    }
+
+    /**
+     * Returns the original, undecorated UserContext, as provided to the
+     * constructor of this DecoratedUserContext.
+     *
+     * @return
+     *     The original, undecorated UserContext.
+     */
+    public UserContext getOriginal() {
+        return original;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/a745569f/guacamole/src/main/java/org/apache/guacamole/rest/auth/TokenRESTService.java
----------------------------------------------------------------------
diff --git a/guacamole/src/main/java/org/apache/guacamole/rest/auth/TokenRESTService.java b/guacamole/src/main/java/org/apache/guacamole/rest/auth/TokenRESTService.java
index 6366d28..cea0315 100644
--- a/guacamole/src/main/java/org/apache/guacamole/rest/auth/TokenRESTService.java
+++ b/guacamole/src/main/java/org/apache/guacamole/rest/auth/TokenRESTService.java
@@ -186,7 +186,7 @@ public class TokenRESTService {
             throw new GuacamoleResourceNotFoundException("No such token.");
 
         // Build list of all available auth providers
-        List<UserContext> userContexts = session.getUserContexts();
+        List<DecoratedUserContext> userContexts = session.getUserContexts();
         List<String> authProviderIdentifiers = new ArrayList<String>(userContexts.size());
         for (UserContext userContext : userContexts)
             authProviderIdentifiers.add(userContext.getAuthenticationProvider().getIdentifier());