You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ro...@apache.org on 2012/08/24 17:33:05 UTC

svn commit: r1376968 [6/7] - in /qpid/trunk/qpid/java: broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ broker-plugins...

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java Fri Aug 24 15:33:00 2012
@@ -32,7 +32,6 @@ import javax.naming.directory.DirContext
 import javax.naming.directory.InitialDirContext;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
-import javax.security.auth.Subject;
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.NameCallback;
@@ -47,7 +46,7 @@ import org.apache.log4j.Logger;
 import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
 import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
 import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
 import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback;
 
 public class SimpleLDAPAuthenticationManager implements AuthenticationManager
@@ -205,10 +204,10 @@ public class SimpleLDAPAuthenticationMan
 
             if (server.isComplete())
             {
-                final Subject subject = new Subject();
-                _logger.debug("Authenticated as " + server.getAuthorizationID());
-                subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID()));
-                return new AuthenticationResult(subject);
+                String authorizationID = server.getAuthorizationID();
+                _logger.debug("Authenticated as " + authorizationID);
+
+                return new AuthenticationResult(new UsernamePrincipal(authorizationID));
             }
             else
             {
@@ -249,9 +248,8 @@ public class SimpleLDAPAuthenticationMan
         env.put(Context.SECURITY_CREDENTIALS, password);
         DirContext ctx = new InitialDirContext(env);
         ctx.close();
-        final Subject subject = new Subject();
-        subject.getPrincipals().add(new UsernamePrincipal(username));
-        return new AuthenticationResult(subject);
+
+        return new AuthenticationResult(new UsernamePrincipal(username));
     }
 
     @Override

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java Fri Aug 24 15:33:00 2012
@@ -23,12 +23,11 @@ package org.apache.qpid.server.security.
 import java.net.SocketAddress;
 
 import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.SubjectCreator;
 import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
 
 import javax.management.remote.JMXAuthenticator;
-import javax.management.remote.JMXPrincipal;
 import javax.security.auth.Subject;
 
 public class RMIPasswordAuthenticator implements JMXAuthenticator
@@ -41,7 +40,7 @@ public class RMIPasswordAuthenticator im
     static final String CREDENTIALS_REQUIRED = "User details are required. " +
     		            "Please ensure you are using an up to date management console to connect.";
 
-    private AuthenticationManager _authenticationManager = null;
+    private SubjectCreator _subjectCreator = null;
     private SocketAddress _socketAddress;
 
     public RMIPasswordAuthenticator(SocketAddress socketAddress)
@@ -49,9 +48,9 @@ public class RMIPasswordAuthenticator im
         _socketAddress = socketAddress;
     }
 
-    public void setAuthenticationManager(final AuthenticationManager authenticationManager)
+    public void setSubjectCreator(final SubjectCreator subjectCreator)
     {
-        _authenticationManager = authenticationManager;
+        _subjectCreator = subjectCreator;
     }
 
     public Subject authenticate(Object credentials) throws SecurityException
@@ -85,14 +84,14 @@ public class RMIPasswordAuthenticator im
             throw new SecurityException(SHOULD_BE_NON_NULL);
         }
 
-        // Verify that an AuthenticationManager has been set.
-        if (_authenticationManager == null)
+        // Verify that an SubjectCreator has been set.
+        if (_subjectCreator == null)
         {
             try
             {
-                if(ApplicationRegistry.getInstance().getAuthenticationManager(_socketAddress) != null)
+                if(ApplicationRegistry.getInstance().getSubjectCreator(_socketAddress) != null)
                 {
-                    _authenticationManager = ApplicationRegistry.getInstance().getAuthenticationManager(_socketAddress);
+                    _subjectCreator = ApplicationRegistry.getInstance().getSubjectCreator(_socketAddress);
                 }
                 else
                 {
@@ -104,7 +103,7 @@ public class RMIPasswordAuthenticator im
                 throw new SecurityException(UNABLE_TO_LOOKUP);
             }
         }
-        final AuthenticationResult result = _authenticationManager.authenticate(username, password);
+        final SubjectAuthenticationResult result = _subjectCreator.authenticate(username, password);
 
         if (AuthenticationStatus.ERROR.equals(result.getStatus()))
         {
@@ -112,10 +111,7 @@ public class RMIPasswordAuthenticator im
         }
         else if (AuthenticationStatus.SUCCESS.equals(result.getStatus()))
         {
-            final Subject subject = result.getSubject();
-            subject.getPrincipals().add(new JMXPrincipal(username));
-            subject.setReadOnly();
-            return subject;
+            return result.getSubject();
         }
         else
         {

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java Fri Aug 24 15:33:00 2012
@@ -23,6 +23,7 @@ package org.apache.qpid.server.security.
 import org.apache.commons.configuration.Configuration;
 import org.apache.log4j.Logger;
 
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
 import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
 
 import javax.security.auth.callback.Callback;

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java Fri Aug 24 15:33:00 2012
@@ -23,6 +23,8 @@ package org.apache.qpid.server.security.
 import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslServer;
 
+import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager;
+
 
 public class AnonymousSaslServer implements SaslServer
 {
@@ -52,7 +54,7 @@ public class AnonymousSaslServer impleme
 
     public String getAuthorizationID()
     {
-        return null;
+        return AnonymousAuthenticationManager.ANONYMOUS_PRINCIPAL.getName();
     }
 
     public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException

Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java (added)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,265 @@
+/*
+ * 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.qpid.server.security.group;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+/**
+ * A group database that reads/writes the following file format:
+ *
+ * group1.users=user1,user2
+ * group2.users=user2,user3
+ */
+public class FileGroupDatabase implements GroupDatabase
+{
+    private static final Logger LOGGER = Logger.getLogger(FileGroupDatabase.class);
+
+    private Map<String, Set<String>> _groupToUserMap = new ConcurrentHashMap<String, Set<String>>();
+    private Map<String, Set<String>> _userToGroupMap = new ConcurrentHashMap<String, Set<String>>();
+    private String _groupFile;
+
+    @Override
+    public Set<String> getAllGroups()
+    {
+        return Collections.unmodifiableSet(_groupToUserMap.keySet());
+    }
+
+    public synchronized void setGroupFile(String groupFile) throws IOException
+    {
+        File file = new File(groupFile);
+
+        if (!file.canRead())
+        {
+            throw new FileNotFoundException(groupFile
+                    + " cannot be found or is not readable");
+        }
+
+        readGroupFile(groupFile);
+    }
+
+    @Override
+    public Set<String> getUsersInGroup(String group)
+    {
+        if (group == null)
+        {
+            LOGGER.warn("Requested user set for null group. Returning empty set.");
+            return Collections.emptySet();
+        }
+
+        Set<String> set = _groupToUserMap.get(group);
+        if (set == null)
+        {
+            return Collections.emptySet();
+        }
+        else
+        {
+            return Collections.unmodifiableSet(set);
+        }
+    }
+
+    @Override
+    public synchronized void addUserToGroup(String user, String group)
+    {
+        Set<String> users = _groupToUserMap.get(group);
+        if (users == null)
+        {
+            throw new IllegalArgumentException("Group " + group + " does not exist so could not add " + user + " to it");
+        }
+
+        users.add(user);
+
+        Set<String> groups = _userToGroupMap.get(user);
+        if (groups == null)
+        {
+            groups = new ConcurrentSkipListSet<String>();
+            _userToGroupMap.put(user, groups);
+        }
+        groups.add(group);
+
+        update();
+    }
+
+    @Override
+    public synchronized void removeUserFromGroup(String user, String group)
+    {
+        Set<String> users = _groupToUserMap.get(group);
+        if (users == null)
+        {
+            throw new IllegalArgumentException("Group " + group + " does not exist so could not remove " + user + " from it");
+        }
+
+        users.remove(user);
+
+        Set<String> groups = _userToGroupMap.get(user);
+        if (groups != null)
+        {
+            groups.remove(group);
+        }
+
+        update();
+    }
+
+    @Override
+    public Set<String> getGroupsForUser(String user)
+    {
+        if(user == null)
+        {
+            LOGGER.warn("Requested group set for null user. Returning empty set.");
+            return Collections.emptySet();
+        }
+
+        Set<String> groups = _userToGroupMap.get(user);
+        if (groups == null)
+        {
+            return Collections.emptySet();
+        }
+        else
+        {
+            return Collections.unmodifiableSet(groups);
+        }
+    }
+
+    @Override
+    public synchronized void createGroup(String group)
+    {
+        Set<String> users = new ConcurrentSkipListSet<String>();
+        _groupToUserMap.put(group, users);
+
+        update();
+    }
+
+    @Override
+    public synchronized void removeGroup(String group)
+    {
+        _groupToUserMap.remove(group);
+        for (Set<String> groupsForUser : _userToGroupMap.values())
+        {
+            groupsForUser.remove(group);
+        }
+
+        update();
+    }
+
+    private synchronized void update()
+    {
+        if (_groupFile != null)
+        {
+            try
+            {
+                writeGroupFile(_groupFile);
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException("Unable to persist change to file " + _groupFile);
+            }
+        }
+    }
+
+    private synchronized void readGroupFile(String groupFile) throws IOException
+    {
+        _groupFile = groupFile;
+        _groupToUserMap.clear();
+        _userToGroupMap.clear();
+        Properties propertiesFile = new Properties();
+        propertiesFile.load(new FileInputStream(groupFile));
+
+        for (String propertyName : propertiesFile.stringPropertyNames())
+        {
+            validatePropertyNameIsGroupName(propertyName);
+
+            String groupName = propertyName.replaceAll("\\.users$", "");
+            String userString = propertiesFile.getProperty(propertyName);
+
+            final Set<String> userSet = buildUserSetFromCommaSeparateValue(userString);
+
+            _groupToUserMap.put(groupName, userSet);
+
+            for (String userName : userSet)
+            {
+                Set<String> groupsForThisUser = _userToGroupMap.get(userName);
+
+                if (groupsForThisUser == null)
+                {
+                    groupsForThisUser = new ConcurrentSkipListSet<String>();
+                    _userToGroupMap.put(userName, groupsForThisUser);
+                }
+
+                groupsForThisUser.add(groupName);
+            }
+        }
+    }
+
+    private synchronized void writeGroupFile(String groupFile) throws IOException
+    {
+        Properties propertiesFile = new Properties();
+
+        for (String group : _groupToUserMap.keySet())
+        {
+            Set<String> users = _groupToUserMap.get(group);
+            String userList = StringUtils.join(users, ",");
+
+            propertiesFile.setProperty(group + ".users", userList);
+        }
+
+        String comment = "Written " + new Date();
+        propertiesFile.store(new FileOutputStream(groupFile), comment);
+    }
+
+    private void validatePropertyNameIsGroupName(String propertyName)
+    {
+        if (!propertyName.endsWith(".users"))
+        {
+            throw new IllegalArgumentException(
+                    "Invalid definition with name '"
+                            + propertyName
+                            + "'. Group definitions must end with suffix '.users'");
+        }
+    }
+
+    private ConcurrentSkipListSet<String> buildUserSetFromCommaSeparateValue(String userString)
+    {
+        String[] users = userString.split(",");
+        final ConcurrentSkipListSet<String> userSet = new ConcurrentSkipListSet<String>();
+        for (String user : users)
+        {
+            final String trimmed = user.trim();
+            if (!trimmed.isEmpty())
+            {
+                userSet.add(trimmed);
+            }
+        }
+        return userSet;
+    }
+
+}

Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java (added)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,251 @@
+/*
+ * 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.qpid.server.security.group;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+
+/**
+ * Implementation of a group manager whose implementation is backed by a flat group file.
+ * <p>
+ * This plugin is configured in the following manner:
+ * </p>
+ * <pre>
+ * &lt;file-group-manager&gt;
+ *    &lt;attributes&gt;
+ *       &lt;attribute&gt;
+ *            &lt;name>groupFile&lt;/name&gt;
+ *            &lt;value>${conf}/groups&lt;/value&gt;
+ *        &lt;/attribute&gt;
+ *    &lt;/attributes&gt;
+ * &lt;/file-group-manager&gt;
+ * </pre>
+ */
+public class FileGroupManager implements GroupManager
+{
+    private static final Logger LOGGER = Logger.getLogger(FileGroupManager.class);
+
+    public static final GroupManagerPluginFactory<FileGroupManager> FACTORY = new GroupManagerPluginFactory<FileGroupManager>()
+    {
+        public FileGroupManager newInstance(final ConfigurationPlugin config) throws ConfigurationException
+        {
+            final FileGroupManagerConfiguration configuration =
+                    config == null
+                            ? null
+                            : (FileGroupManagerConfiguration) config.getConfiguration(FileGroupManagerConfiguration.class.getName());
+
+            // If there is no configuration for this plugin then don't load it.
+            if (configuration == null)
+            {
+                LOGGER.info("No file-group-manager configuration found for FileGroupManager");
+                return null;
+            }
+
+            final FileGroupManager fgm = new FileGroupManager();
+            fgm.configure(configuration);
+            return fgm;
+        }
+
+        public Class<FileGroupManager> getPluginClass()
+        {
+            return FileGroupManager.class;
+        }
+
+        public String getPluginName()
+        {
+            return FileGroupManager.class.getName();
+        }
+    };
+
+    private FileGroupDatabase _groupDatabase;
+
+    public static class FileGroupManagerConfiguration extends ConfigurationPlugin {
+
+        public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
+        {
+            public List<String> getParentPaths()
+            {
+                return Arrays.asList("security.file-group-manager");
+            }
+
+            public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException
+            {
+                final ConfigurationPlugin instance = new FileGroupManagerConfiguration();
+
+                instance.setConfiguration(path, config);
+                return instance;
+            }
+        };
+
+        public String[] getElementsProcessed()
+        {
+            return new String[] {"attributes.attribute.name",
+                                 "attributes.attribute.value"};
+        }
+
+        public void validateConfiguration() throws ConfigurationException
+        {
+        }
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        public Map<String,String> getAttributeMap() throws ConfigurationException
+        {
+            final List<String> argumentNames = (List) getConfig().getList("attributes.attribute.name");
+            final List<String> argumentValues = (List) getConfig().getList("attributes.attribute.value");
+            final Map<String,String> attributes = new HashMap<String,String>(argumentNames.size());
+
+            for (int i = 0; i < argumentNames.size(); i++)
+            {
+                final String argName = argumentNames.get(i);
+                final String argValue = argumentValues.get(i);
+
+                attributes.put(argName, argValue);
+            }
+
+            return Collections.unmodifiableMap(attributes);
+        }
+    }
+
+    @Override
+    public void configure(ConfigurationPlugin config)
+            throws ConfigurationException
+    {
+        if (LOGGER.isDebugEnabled())
+        {
+            LOGGER.debug("configuring file group plugin");
+        }
+
+        FileGroupManagerConfiguration fileGroupMangerConfig = (FileGroupManagerConfiguration) config;
+        Map<String,String> attribMap = fileGroupMangerConfig.getAttributeMap();
+        String groupFile = attribMap.get("groupFile");
+
+        if (LOGGER.isDebugEnabled())
+        {
+            LOGGER.debug("Group file : " + groupFile);
+        }
+
+        _groupDatabase = new FileGroupDatabase();
+        try
+        {
+            _groupDatabase.setGroupFile(groupFile);
+        }
+        catch (IOException e)
+        {
+            throw new ConfigurationException("Unable to set group file " + groupFile, e);
+        }
+    }
+
+    @Override
+    public Set<Principal> getGroupPrincipalsForUser(String userId)
+    {
+        Set<String> groups = _groupDatabase.getGroupsForUser(userId);
+        if (groups.isEmpty())
+        {
+            return Collections.emptySet();
+        }
+        else
+        {
+            Set<Principal> principals = new HashSet<Principal>();
+            for (String groupName : groups)
+            {
+                principals.add(new GroupPrincipal(groupName));
+            }
+            return principals;
+        }
+    }
+
+    @Override
+    public Set<Principal> getUserPrincipalsForGroup(String group)
+    {
+        Set<String> users = _groupDatabase.getUsersInGroup(group);
+        if (users.isEmpty())
+        {
+            return Collections.emptySet();
+        }
+        else
+        {
+            Set<Principal> principals = new HashSet<Principal>();
+            for (String user : users)
+            {
+                principals.add(new UsernamePrincipal(user));
+            }
+            return principals;
+        }
+    }
+
+    @Override
+    public Set<Principal> getGroupPrincipals()
+    {
+        Set<String> groups = _groupDatabase.getAllGroups();
+        if (groups.isEmpty())
+        {
+            return Collections.emptySet();
+        }
+        else
+        {
+            Set<Principal> principals = new HashSet<Principal>();
+            for (String groupName : groups)
+            {
+                principals.add(new GroupPrincipal(groupName));
+            }
+            return principals;
+        }
+    }
+
+    @Override
+    public void createGroup(String group)
+    {
+        _groupDatabase.createGroup(group);
+    }
+
+    @Override
+    public void removeGroup(String group)
+    {
+        _groupDatabase.removeGroup(group);
+    }
+
+    @Override
+    public void addUserToGroup(String user, String group)
+    {
+        _groupDatabase.addUserToGroup(user, group);
+    }
+
+    @Override
+    public void removeUserFromGroup(String user, String group)
+    {
+        _groupDatabase.removeUserFromGroup(user, group);
+
+    }
+
+}

Copied: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java (from r1376735, qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java?p2=qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java&p1=qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java&r1=1376735&r2=1376968&rev=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java Fri Aug 24 15:33:00 2012
@@ -1,5 +1,4 @@
 /*
- *
  * 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
@@ -18,25 +17,18 @@
  * under the License.
  *
  */
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.server.security.group;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
-public class SaslRestTest extends QpidRestTestCase
+public interface GroupDatabase
 {
-    public void testGet() throws Exception
-    {
-        Map<String, Object> saslData = getJsonAsMap("/rest/sasl");
-        assertNotNull("mechanisms attribute is not found", saslData.get("mechanisms"));
-
-        @SuppressWarnings("unchecked")
-        List<String> mechanisms = (List<String>) saslData.get("mechanisms");
-        String[] expectedMechanisms = { "AMQPLAIN", "PLAIN", "CRAM-MD5" };
-        for (String mechanism : expectedMechanisms)
-        {
-            assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
-        }
-    }
+    Set<String> getAllGroups();
+    Set<String> getUsersInGroup(String group);
 
+    void addUserToGroup(String user, String group);
+    void removeUserFromGroup(String user, String group);
+    Set<String> getGroupsForUser(String user);
+    void createGroup(String group);
+    void removeGroup(String group);
 }

Copied: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java (from r1376735, qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java?p2=qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java&p1=qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java&r1=1376735&r2=1376968&rev=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java Fri Aug 24 15:33:00 2012
@@ -1,5 +1,4 @@
 /*
- *
  * 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
@@ -18,25 +17,26 @@
  * under the License.
  *
  */
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.server.security.group;
+
+import java.security.Principal;
+import java.util.Set;
 
-import java.util.List;
-import java.util.Map;
+import org.apache.qpid.server.plugins.Plugin;
 
-public class SaslRestTest extends QpidRestTestCase
+public interface GroupManager extends Plugin
 {
-    public void testGet() throws Exception
-    {
-        Map<String, Object> saslData = getJsonAsMap("/rest/sasl");
-        assertNotNull("mechanisms attribute is not found", saslData.get("mechanisms"));
-
-        @SuppressWarnings("unchecked")
-        List<String> mechanisms = (List<String>) saslData.get("mechanisms");
-        String[] expectedMechanisms = { "AMQPLAIN", "PLAIN", "CRAM-MD5" };
-        for (String mechanism : expectedMechanisms)
-        {
-            assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
-        }
-    }
+    Set<Principal> getGroupPrincipalsForUser(String user);
+
+    Set<Principal> getGroupPrincipals();
+
+    Set<Principal> getUserPrincipalsForGroup(String group);
+
+    void createGroup(String group);
+
+    void removeGroup(String group);
+
+    void addUserToGroup(String user, String group);
 
+    void removeUserFromGroup(String user, String group);
 }

Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManagerPluginFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManagerPluginFactory.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManagerPluginFactory.java (added)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManagerPluginFactory.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,27 @@
+/*
+ * 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.qpid.server.security.group;
+
+import org.apache.qpid.server.plugins.PluginFactory;
+
+public interface GroupManagerPluginFactory<S extends GroupManager> extends PluginFactory<S>
+{
+
+}

Copied: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java (from r1376735, qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java?p2=qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java&p1=qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java&r1=1376735&r2=1376968&rev=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java Fri Aug 24 15:33:00 2012
@@ -7,9 +7,9 @@
  * 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
@@ -18,7 +18,7 @@
  * under the License.
  *
  */
-package org.apache.qpid.server.security.auth.sasl;
+package org.apache.qpid.server.security.group;
 
 import java.security.Principal;
 import java.security.acl.Group;
@@ -34,7 +34,7 @@ public class GroupPrincipal implements G
 {
     /** Name of the group */
     private final String _groupName;
-    
+
     public GroupPrincipal(final String groupName)
     {
         _groupName = groupName;
@@ -83,7 +83,7 @@ public class GroupPrincipal implements G
         {
             return true;
         }
-        else 
+        else
         {
             if (obj instanceof GroupPrincipal)
             {

Copied: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java (from r1376735, qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java?p2=qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java&p1=qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java&r1=1376735&r2=1376968&rev=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java Fri Aug 24 15:33:00 2012
@@ -1,5 +1,4 @@
 /*
- *
  * 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
@@ -16,33 +15,37 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
-package org.apache.qpid.server.security.auth.sasl;
+package org.apache.qpid.server.security.group;
 
-import javax.security.auth.Subject;
 import java.security.Principal;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
-public class TestPrincipalUtils
+
+public class GroupPrincipalAccessor
 {
+    private final List<GroupManager> _groupManagerList;
+
+    public GroupPrincipalAccessor(List<GroupManager> groupManagerList)
+    {
+        _groupManagerList = groupManagerList;
+    }
 
-    /**
-     * Creates a test subject, with exactly one UsernamePrincipal and zero or more GroupPrincipals.
-     */
-    public static Subject createTestSubject(final String username, final String... groups)
+    public Set<Principal> getGroupPrincipals(String username)
     {
-        final Set<Principal> principals = new HashSet<Principal>(1 + groups.length);
-        principals.add(new UsernamePrincipal(username));
-        for (String group : groups)
+        Set<Principal> principals = new HashSet<Principal>();
+        for (GroupManager groupManager : _groupManagerList)
         {
-            principals.add(new GroupPrincipal(group));
+            Set<Principal> groups = groupManager.getGroupPrincipalsForUser(username);
+            if (groups != null)
+            {
+                principals.addAll(groups);
+            }
         }
-        
-        final Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
-        return subject;
-    }
 
+        return Collections.unmodifiableSet(principals);
+    }
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java Fri Aug 24 15:33:00 2012
@@ -34,6 +34,7 @@ import org.apache.qpid.protocol.AMQMetho
 import org.apache.qpid.server.protocol.AMQProtocolSession;
 import org.apache.qpid.server.registry.IApplicationRegistry;
 import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.SubjectCreator;
 import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
 import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
 
@@ -157,13 +158,9 @@ public class AMQStateManager implements 
         return _protocolSession;
     }
 
-    /**
-     * Get the AuthenticationManager associated with the ProtocolSession of the AMQStateManager
-     *
-     * @return the AuthenticationManager
-     */
-    public AuthenticationManager getAuthenticationManager()
+    
+    public SubjectCreator getSubjectCreator()
     {
-        return getApplicationRegistry().getAuthenticationManager(getProtocolSession().getLocalAddress());
+        return getApplicationRegistry().getSubjectCreator(getProtocolSession().getLocalAddress());
     }
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java Fri Aug 24 15:33:00 2012
@@ -37,9 +37,9 @@ import org.apache.qpid.server.configurat
 import org.apache.qpid.server.protocol.AMQConnectionModel;
 import org.apache.qpid.server.registry.IApplicationRegistry;
 import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.SubjectCreator;
 import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
 import org.apache.qpid.server.subscription.Subscription_0_10;
 import org.apache.qpid.server.virtualhost.State;
 import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -57,25 +57,25 @@ public class ServerConnectionDelegate ex
     private final IApplicationRegistry _appRegistry;
     private int _maxNoOfChannels;
     private Map<String,Object> _clientProperties;
-    private final AuthenticationManager _authManager;
+    private final SubjectCreator _subjectCreator;
 
-    public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN, AuthenticationManager authManager)
+    public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN, SubjectCreator subjectCreator)
     {
-        this(createConnectionProperties(appRegistry.getBrokerConfig()), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN, authManager);
+        this(createConnectionProperties(appRegistry.getBrokerConfig()), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN, subjectCreator);
     }
 
     private ServerConnectionDelegate(Map<String, Object> properties,
                                     List<Object> locales,
                                     IApplicationRegistry appRegistry,
                                     String localFQDN,
-                                    AuthenticationManager authManager)
+                                    SubjectCreator subjectCreator)
     {
-        super(properties, parseToList(authManager.getMechanisms()), locales);
+        super(properties, parseToList(subjectCreator.getMechanisms()), locales);
 
         _appRegistry = appRegistry;
         _localFQDN = localFQDN;
         _maxNoOfChannels = appRegistry.getConfiguration().getMaxChannelCount();
-        _authManager = authManager;
+        _subjectCreator = subjectCreator;
     }
 
     private static Map<String, Object> createConnectionProperties(final BrokerConfig brokerConfig)
@@ -112,14 +112,14 @@ public class ServerConnectionDelegate ex
 
     protected SaslServer createSaslServer(Connection conn, String mechanism) throws SaslException
     {
-        return _authManager.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal());
+        return _subjectCreator.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal());
 
     }
 
     protected void secure(final SaslServer ss, final Connection conn, final byte[] response)
     {
         final ServerConnection sconn = (ServerConnection) conn;
-        final AuthenticationResult authResult = _authManager.authenticate(ss, response);
+        final SubjectAuthenticationResult authResult = _subjectCreator.authenticate(ss, response);
 
         if (AuthenticationStatus.SUCCESS.equals(authResult.getStatus()))
         {

Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java (added)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.qpid.server.logging.actors;
+
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.logging.NullRootMessageLogger;
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class AbstractManagementActorTest extends QpidTestCase
+{
+    private AbstractManagementActor _logActor;
+
+    @Override
+    public void setUp()
+    {
+        _logActor = new AbstractManagementActor(new NullRootMessageLogger(), AbstractManagementActor.UNKNOWN_PRINCIPAL)
+        {
+            @Override
+            public String getLogMessage()
+            {
+                return null;
+            }
+        };
+    }
+
+    public void testGetPrincipalName()
+    {
+        Subject subject = TestPrincipalUtils.createTestSubject("guest");
+        
+        final String principalName = Subject.doAs(subject, 
+                new PrivilegedAction<String>()
+                {
+                    public String run()
+                    {
+                        return _logActor.getPrincipalName();
+                    }
+                });
+
+        assertEquals("guest", principalName);
+    }
+
+    public void testGetPrincipalNameUsingSubjectWithoutAuthenticatedPrincipal()
+    {
+        Subject subject = new Subject(true, Collections.<Principal>emptySet(), Collections.emptySet(), Collections.emptySet());
+
+        final String principalName = Subject.doAs(subject, 
+                new PrivilegedAction<String>()
+                {
+                    public String run()
+                    {
+                        return _logActor.getPrincipalName();
+                    }
+                });
+
+        assertEquals(AbstractManagementActor.UNKNOWN_PRINCIPAL, principalName);
+    }
+
+    public void testGetPrincipalWithoutSubject()
+    {
+        assertEquals(AbstractManagementActor.UNKNOWN_PRINCIPAL, _logActor.getPrincipalName());
+    }
+}

Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java (added)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,94 @@
+/*
+ *
+ * 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.qpid.server.logging.actors;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
+
+import java.security.PrivilegedAction;
+import java.util.List;
+
+public class HttpManagementActorTest extends BaseActorTestCase
+{
+    private static final String IP = "127.0.0.1";
+    private static final int PORT = 1;
+    private static final String SUFFIX = "(" + IP + ":" + PORT + ")] ";
+
+    @Override
+    public void createBroker() throws Exception
+    {
+        super.createBroker();
+        _amqpActor = new HttpManagementActor(_rootLogger, IP, PORT);
+    }
+
+    public void testSubjectPrincipalNameAppearance()
+    {
+        Subject subject = TestPrincipalUtils.createTestSubject("guest");
+
+        final String message = Subject.doAs(subject, new PrivilegedAction<String>()
+        {
+            public String run()
+            {
+                return sendTestLogMessage(_amqpActor);
+            }
+        });
+
+        assertNotNull("Test log message is not created!", message);
+
+        List<Object> logs = _rawLogger.getLogMessages();
+        assertEquals("Message log size not as expected.", 1, logs.size());
+
+        String logMessage = logs.get(0).toString();
+        assertTrue("Message was not found in log message", logMessage.contains(message));
+        assertTrue("Message does not contain expected value: " + logMessage, logMessage.contains("[mng:guest" + SUFFIX));
+    }
+
+    /** It's necessary to test successive calls because HttpManagementActor caches
+     *  its log message based on principal name */
+    public void testGetLogMessageCaching()
+    {
+        assertLogMessageWithoutPrincipal();
+        assertLogMessageWithPrincipal("my_principal");
+        assertLogMessageWithPrincipal("my_principal2");
+        assertLogMessageWithoutPrincipal();
+    }
+
+    private void assertLogMessageWithoutPrincipal()
+    {
+        String message = _amqpActor.getLogMessage();
+        assertEquals("Unexpected log message", "[mng:" + AbstractManagementActor.UNKNOWN_PRINCIPAL + SUFFIX, message);
+    }
+
+    private void assertLogMessageWithPrincipal(String principalName)
+    {
+        Subject subject = TestPrincipalUtils.createTestSubject(principalName);
+        final String message = Subject.doAs(subject, new PrivilegedAction<String>()
+        {
+            public String run()
+            {
+                return _amqpActor.getLogMessage();
+            }
+        });
+
+        assertEquals("Unexpected log message", "[mng:" + principalName + SUFFIX, message);
+    }
+}

Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java (original)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java Fri Aug 24 15:33:00 2012
@@ -20,10 +20,11 @@
  */
 package org.apache.qpid.server.logging.actors;
 
-import javax.management.remote.JMXPrincipal;
 import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
+
 import java.security.PrivilegedAction;
-import java.util.Collections;
 import java.util.List;
 
 public class ManagementActorTest extends BaseActorTestCase
@@ -94,8 +95,7 @@ public class ManagementActorTest extends
      */
     public void testSubjectPrincipalNameAppearance()
     {
-        Subject subject = new Subject(true, Collections.singleton(new JMXPrincipal("guest")), Collections.EMPTY_SET,
-                Collections.EMPTY_SET);
+        Subject subject = TestPrincipalUtils.createTestSubject("guest");
 
         final String message = Subject.doAs(subject, new PrivilegedAction<String>()
         {
@@ -172,9 +172,7 @@ public class ManagementActorTest extends
     private void assertLogMessageInRMIThreadWithPrincipal(String threadName, String principalName)
     {
         Thread.currentThread().setName(threadName);
-        Subject subject = new Subject(true, Collections.singleton(new JMXPrincipal(principalName)), Collections.EMPTY_SET,
-                Collections.EMPTY_SET);
-
+        Subject subject = TestPrincipalUtils.createTestSubject(principalName);
         final String message = Subject.doAs(subject, new PrivilegedAction<String>()
         {
             public String run()

Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java (original)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java Fri Aug 24 15:33:00 2012
@@ -70,8 +70,12 @@ public class UUIDGeneratorTest extends Q
         idSet.add(id6);
         UUID id7 = UUIDGenerator.generateVhostAliasUUID(value, value);
         idSet.add(id7);
+        UUID id8 = UUIDGenerator.generateGroupUUID(value, value);
+        idSet.add(id8);
+        UUID id9 = UUIDGenerator.generateGroupMemberUUID(value, value, value);
+        idSet.add(id9);
 
-        assertEquals("The produced UUIDs were not all unique", 7, idSet.size());
+        assertEquals("The produced UUIDs were not all unique", 9, idSet.size());
     }
 
     public void testQueueIdGeneration() throws Exception

Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java (original)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java Fri Aug 24 15:33:00 2012
@@ -31,7 +31,8 @@ import org.apache.qpid.server.message.Me
 import org.apache.qpid.server.output.ProtocolOutputConverter;
 import org.apache.qpid.server.queue.QueueEntry;
 import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
 import org.apache.qpid.server.subscription.ClientDeliveryMethod;
 import org.apache.qpid.server.subscription.Subscription;
 import org.apache.qpid.server.subscription.SubscriptionImpl;
@@ -39,6 +40,8 @@ import org.apache.qpid.server.virtualhos
 import org.apache.qpid.transport.TestNetworkConnection;
 
 import javax.security.auth.Subject;
+
+import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -61,13 +64,22 @@ public class InternalTestProtocolSession
 
         _channelDelivers = new HashMap<Integer, Map<AMQShortString, LinkedList<DeliveryPair>>>();
 
-        // Need to authenticate session for it to be representative testing.
-        setAuthorizedSubject(new Subject(true, Collections.singleton(new UsernamePrincipal("InternalTestProtocolSession")),
-                Collections.EMPTY_SET, Collections.EMPTY_SET));
-
+        setTestAuthorizedSubject();
         setVirtualHost(virtualHost);
     }
 
+    private void setTestAuthorizedSubject()
+    {
+        Principal principal = new AuthenticatedPrincipal(new UsernamePrincipal("InternalTestProtocolSession"));
+        Subject authorizedSubject = new Subject(
+                true,
+                Collections.singleton(principal),
+                Collections.emptySet(),
+                Collections.emptySet());
+
+        setAuthorizedSubject(authorizedSubject);
+    }
+
     public ProtocolOutputConverter getProtocolOutputConverter()
     {
         return this;

Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java (added)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,138 @@
+/*
+ * 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.qpid.server.security;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.HashSet;
+
+import javax.security.auth.Subject;
+import javax.security.sasl.SaslServer;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
+
+public class SubjectCreatorTest extends TestCase
+{
+    private static final String USERNAME = "username";
+    private static final String PASSWORD = "password";
+
+    private AuthenticationManager _authenticationManager = mock(AuthenticationManager.class);
+    private GroupPrincipalAccessor _groupPrincipalAccessor = mock(GroupPrincipalAccessor.class);
+    private SubjectCreator _subjectCreator = new SubjectCreator(_authenticationManager, _groupPrincipalAccessor);
+
+    private Principal _userPrincipal = mock(Principal.class);
+    private Principal _group1 = mock(Principal.class);
+    private Principal _group2 = mock(Principal.class);
+
+    private AuthenticationResult _authenticationResult;
+    private SaslServer _testSaslServer = mock(SaslServer.class);
+    private byte[] _saslResponseBytes = PASSWORD.getBytes();
+
+    @Override
+    public void setUp()
+    {
+        _authenticationResult = new AuthenticationResult(_userPrincipal);
+        when(_authenticationManager.authenticate(USERNAME, PASSWORD)).thenReturn(_authenticationResult);
+
+        when(_groupPrincipalAccessor.getGroupPrincipals(USERNAME))
+            .thenReturn(new HashSet<Principal>(Arrays.asList(_group1, _group2)));
+    }
+
+    public void testAuthenticateUsernameAndPasswordReturnsSubjectWithUserAndGroupPrincipals()
+    {
+        final SubjectAuthenticationResult actualResult = _subjectCreator.authenticate(USERNAME, PASSWORD);
+
+        assertEquals(AuthenticationStatus.SUCCESS, actualResult.getStatus());
+
+        final Subject actualSubject = actualResult.getSubject();
+
+        assertEquals("Should contain one user principal and two groups ", 3, actualSubject.getPrincipals().size());
+
+        assertTrue(actualSubject.getPrincipals().contains(new AuthenticatedPrincipal(_userPrincipal)));
+        assertTrue(actualSubject.getPrincipals().contains(_group1));
+        assertTrue(actualSubject.getPrincipals().contains(_group2));
+
+        assertTrue(actualSubject.isReadOnly());
+    }
+
+    public void testSaslAuthenticationSuccessReturnsSubjectWithUserAndGroupPrincipals() throws Exception
+    {
+        when(_authenticationManager.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(_authenticationResult);
+        when(_testSaslServer.isComplete()).thenReturn(true);
+        when(_testSaslServer.getAuthorizationID()).thenReturn(USERNAME);
+
+        SubjectAuthenticationResult result = _subjectCreator.authenticate(_testSaslServer, _saslResponseBytes);
+
+        final Subject actualSubject = result.getSubject();
+        assertEquals("Should contain one user principal and two groups ", 3, actualSubject.getPrincipals().size());
+
+        assertTrue(actualSubject.getPrincipals().contains(new AuthenticatedPrincipal(_userPrincipal)));
+        assertTrue(actualSubject.getPrincipals().contains(_group1));
+        assertTrue(actualSubject.getPrincipals().contains(_group2));
+
+        assertTrue(actualSubject.isReadOnly());
+    }
+
+    public void testAuthenticateUnsuccessfulWithUsernameReturnsNullSubjectAndCorrectStatus()
+    {
+        testUnsuccessfulAuthentication(AuthenticationResult.AuthenticationStatus.CONTINUE);
+        testUnsuccessfulAuthentication(AuthenticationResult.AuthenticationStatus.ERROR);
+    }
+
+    private void testUnsuccessfulAuthentication(AuthenticationStatus expectedStatus)
+    {
+        AuthenticationResult failedAuthenticationResult = new AuthenticationResult(expectedStatus);
+
+        when(_authenticationManager.authenticate(USERNAME, PASSWORD)).thenReturn(failedAuthenticationResult);
+
+        SubjectAuthenticationResult subjectAuthenticationResult = _subjectCreator.authenticate(USERNAME, PASSWORD);
+
+        assertSame(expectedStatus, subjectAuthenticationResult.getStatus());
+        assertNull(subjectAuthenticationResult.getSubject());
+    }
+
+    public void testAuthenticateUnsuccessfulWithSaslServerReturnsNullSubjectAndCorrectStatus()
+    {
+        testUnsuccessfulAuthenticationWithSaslServer(AuthenticationResult.AuthenticationStatus.CONTINUE);
+        testUnsuccessfulAuthenticationWithSaslServer(AuthenticationResult.AuthenticationStatus.ERROR);
+    }
+
+    private void testUnsuccessfulAuthenticationWithSaslServer(AuthenticationStatus expectedStatus)
+    {
+        AuthenticationResult failedAuthenticationResult = new AuthenticationResult(expectedStatus);
+
+        when(_authenticationManager.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(failedAuthenticationResult);
+        when(_testSaslServer.isComplete()).thenReturn(false);
+
+        SubjectAuthenticationResult subjectAuthenticationResult = _subjectCreator.authenticate(_testSaslServer, _saslResponseBytes);
+
+        assertSame(expectedStatus, subjectAuthenticationResult.getStatus());
+        assertNull(subjectAuthenticationResult.getSubject());
+    }
+}

Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java (added)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java Fri Aug 24 15:33:00 2012
@@ -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.qpid.server.security.auth;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+
+import junit.framework.TestCase;
+
+public class AuthenticatedPrincipalTest extends TestCase
+{
+
+    private AuthenticatedPrincipal _authenticatedPrincipal = new AuthenticatedPrincipal(new UsernamePrincipal("name"));
+
+    public void testGetAuthenticatedPrincipalFromSubject()
+    {
+        final Subject subject = createSubjectContainingAuthenticatedPrincipal();
+        final AuthenticatedPrincipal actual = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+        assertSame(_authenticatedPrincipal, actual);
+    }
+
+    public void testAuthenticatedPrincipalNotInSubject()
+    {
+        try
+        {
+            AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(new Subject());
+            fail("Exception not thrown");
+        }
+        catch (IllegalArgumentException iae)
+        {
+            // PASS
+        }
+    }
+
+    public void testGetOptionalAuthenticatedPrincipalFromSubject()
+    {
+        final Subject subject = createSubjectContainingAuthenticatedPrincipal();
+        final AuthenticatedPrincipal actual = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subject);
+        assertSame(_authenticatedPrincipal, actual);
+    }
+
+    public void testGetOptionalAuthenticatedPrincipalFromSubjectReturnsNullIfMissing()
+    {
+        Subject subjectWithNoPrincipals = new Subject();
+        assertNull(AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subjectWithNoPrincipals));
+
+        Subject subjectWithoutAuthenticatedPrincipal = new Subject();
+        subjectWithoutAuthenticatedPrincipal.getPrincipals().add(new UsernamePrincipal("name1"));
+        assertNull("Should return null for a subject containing a principal that isn't an AuthenticatedPrincipal",
+                AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subjectWithoutAuthenticatedPrincipal));
+    }
+
+    public void testTooManyAuthenticatedPrincipalsInSubject()
+    {
+        final Subject subject = new Subject();
+        subject.getPrincipals().add(new AuthenticatedPrincipal(new UsernamePrincipal("name1")));
+        subject.getPrincipals().add(new AuthenticatedPrincipal(new UsernamePrincipal("name2")));
+
+        try
+        {
+            AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+            fail("Exception not thrown");
+        }
+        catch (IllegalArgumentException iae)
+        {
+            // PASS
+        }
+    }
+
+    private Subject createSubjectContainingAuthenticatedPrincipal()
+    {
+        final Principal other = new Principal()
+        {
+            public String getName()
+            {
+                return "otherprincipal";
+            }
+        };
+
+        final Subject subject = new Subject();
+        subject.getPrincipals().add(_authenticatedPrincipal);
+        subject.getPrincipals().add(other);
+        return subject;
+    }
+
+    public void testEqualsAndHashcode()
+    {
+        AuthenticatedPrincipal user1principal1 = new AuthenticatedPrincipal(new UsernamePrincipal("user1"));
+        AuthenticatedPrincipal user1principal2 = new AuthenticatedPrincipal(new UsernamePrincipal("user1"));
+
+        assertTrue(user1principal1.equals(user1principal1));
+        assertTrue(user1principal1.equals(user1principal2));
+        assertTrue(user1principal2.equals(user1principal1));
+
+        assertEquals(user1principal1.hashCode(), user1principal2.hashCode());
+    }
+
+    public void testEqualsAndHashcodeWithSameWrappedObject()
+    {
+        UsernamePrincipal wrappedPrincipal = new UsernamePrincipal("user1");
+        AuthenticatedPrincipal user1principal1 = new AuthenticatedPrincipal(wrappedPrincipal);
+        AuthenticatedPrincipal user1principal2 = new AuthenticatedPrincipal(wrappedPrincipal);
+
+        assertTrue(user1principal1.equals(user1principal1));
+        assertTrue(user1principal1.equals(user1principal2));
+        assertTrue(user1principal2.equals(user1principal1));
+
+        assertEquals(user1principal1.hashCode(), user1principal2.hashCode());
+    }
+
+    public void testEqualsWithDifferentUsernames()
+    {
+        AuthenticatedPrincipal user1principal1 = new AuthenticatedPrincipal(new UsernamePrincipal("user1"));
+        AuthenticatedPrincipal user1principal2 = new AuthenticatedPrincipal(new UsernamePrincipal("user2"));
+
+        assertFalse(user1principal1.equals(user1principal2));
+        assertFalse(user1principal2.equals(user1principal1));
+    }
+
+    public void testEqualsWithDisimilarObjects()
+    {
+        UsernamePrincipal wrappedPrincipal = new UsernamePrincipal("user1");
+        AuthenticatedPrincipal authenticatedPrincipal = new AuthenticatedPrincipal(wrappedPrincipal);
+
+        assertFalse(authenticatedPrincipal.equals(wrappedPrincipal));
+        assertFalse(wrappedPrincipal.equals(authenticatedPrincipal));
+    }
+}

Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java (added)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,54 @@
+/*
+ * 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.qpid.server.security.auth;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+/**
+ * Helper class for testing that sets of principals contain {@link AuthenticatedPrincipal}'s that wrap
+ * expected {@link Principal}'s.
+ */
+public class AuthenticatedPrincipalTestHelper
+{
+    public static void assertOnlyContainsWrapped(Principal wrappedPrincipal, Set<Principal> principals)
+    {
+        assertOnlyContainsWrappedAndSecondaryPrincipals(wrappedPrincipal, Collections.<Principal>emptySet(), principals);
+    }
+
+
+    public static void assertOnlyContainsWrappedAndSecondaryPrincipals(
+            Principal      expectedWrappedPrincipal,
+            Set<Principal> expectedSecondaryPrincipals,
+            Set<Principal> actualPrincipals)
+    {
+        Assert.assertEquals("Principal set should contain one principal " + "but the principal set is: " + actualPrincipals,
+                1 + expectedSecondaryPrincipals.size(),
+                actualPrincipals.size());
+
+        Set<Principal> expectedSet = new HashSet<Principal>(expectedSecondaryPrincipals);
+        expectedSet.add(new AuthenticatedPrincipal(expectedWrappedPrincipal));
+
+        Assert.assertEquals(expectedSet, actualPrincipals);
+    }
+}

Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java (added)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,112 @@
+/*
+ * 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.qpid.server.security.auth;
+
+import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped;
+import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrappedAndSecondaryPrincipals;
+import static org.mockito.Mockito.mock;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+public class AuthenticationResultTest extends TestCase
+{
+    public void testConstructWithAuthenticationStatusContinue()
+    {
+        AuthenticationResult authenticationResult = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.CONTINUE);
+        assertSame(AuthenticationResult.AuthenticationStatus.CONTINUE, authenticationResult.getStatus());
+        assertTrue(authenticationResult.getPrincipals().isEmpty());
+    }
+
+    public void testConstructWithAuthenticationStatusError()
+    {
+        AuthenticationResult authenticationResult = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
+        assertSame(AuthenticationResult.AuthenticationStatus.ERROR, authenticationResult.getStatus());
+        assertTrue(authenticationResult.getPrincipals().isEmpty());
+    }
+
+    public void testConstructWithAuthenticationStatusSuccessThrowsException()
+    {
+        try
+        {
+            new AuthenticationResult(AuthenticationResult.AuthenticationStatus.SUCCESS);
+            fail("Exception not thrown");
+        }
+        catch(IllegalArgumentException e)
+        {
+            // PASS
+        }
+    }
+
+    public void testConstructWithPrincipal()
+    {
+        Principal mainPrincipal = mock(Principal.class);
+        AuthenticationResult authenticationResult = new AuthenticationResult(mainPrincipal);
+
+        assertOnlyContainsWrapped(mainPrincipal, authenticationResult.getPrincipals());
+        assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus());
+    }
+
+    public void testConstructWithNullPrincipalThrowsException()
+    {
+        try
+        {
+            new AuthenticationResult((Principal)null);
+            fail("Exception not thrown");
+        }
+        catch(IllegalArgumentException e)
+        {
+            // pass
+        }
+    }
+
+    public void testConstructWithSetOfPrincipals()
+    {
+        Principal mainPrincipal = mock(Principal.class);
+        Principal secondaryPrincipal = mock(Principal.class);
+        Set<Principal> secondaryPrincipals = Collections.singleton(secondaryPrincipal);
+
+        AuthenticationResult authenticationResult = new AuthenticationResult(mainPrincipal, secondaryPrincipals);
+
+        assertOnlyContainsWrappedAndSecondaryPrincipals(mainPrincipal, secondaryPrincipals, authenticationResult.getPrincipals());
+        assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus());
+    }
+
+    public void testConstructWithSetOfPrincipalsDeDuplicatesMainPrincipal()
+    {
+        Principal mainPrincipal = mock(Principal.class);
+        Principal secondaryPrincipal = mock(Principal.class);
+
+        Set<Principal> secondaryPrincipalsContainingDuplicateOfMainPrincipal = new HashSet<Principal>(
+                Arrays.asList(secondaryPrincipal, mainPrincipal));
+        Set<Principal> deDuplicatedSecondaryPrincipals = Collections.singleton(secondaryPrincipal);
+
+        AuthenticationResult authenticationResult = new AuthenticationResult(
+                mainPrincipal, secondaryPrincipalsContainingDuplicateOfMainPrincipal);
+
+        assertOnlyContainsWrappedAndSecondaryPrincipals(mainPrincipal, deDuplicatedSecondaryPrincipals, authenticationResult.getPrincipals());
+
+        assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus());
+    }
+}

Copied: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/TestPrincipalUtils.java (from r1376735, qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/TestPrincipalUtils.java?p2=qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/TestPrincipalUtils.java&p1=qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java&r1=1376735&r2=1376968&rev=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java (original)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/TestPrincipalUtils.java Fri Aug 24 15:33:00 2012
@@ -18,9 +18,12 @@
  * under the License.
  *
  */
-package org.apache.qpid.server.security.auth.sasl;
+package org.apache.qpid.server.security.auth;
 
 import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.group.GroupPrincipal;
+
 import java.security.Principal;
 import java.util.Collections;
 import java.util.HashSet;
@@ -28,21 +31,19 @@ import java.util.Set;
 
 public class TestPrincipalUtils
 {
-
     /**
-     * Creates a test subject, with exactly one UsernamePrincipal and zero or more GroupPrincipals.
+     * Creates a test subject, with exactly one {@link AuthenticatedPrincipal} and zero or more GroupPrincipals.
      */
     public static Subject createTestSubject(final String username, final String... groups)
     {
         final Set<Principal> principals = new HashSet<Principal>(1 + groups.length);
-        principals.add(new UsernamePrincipal(username));
+        principals.add(new AuthenticatedPrincipal(username));
         for (String group : groups)
         {
             principals.add(new GroupPrincipal(group));
         }
-        
-        final Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
-        return subject;
+
+        return new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
     }
 
 }

Added: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/UsernamePrincipalTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/UsernamePrincipalTest.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/UsernamePrincipalTest.java (added)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/UsernamePrincipalTest.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,70 @@
+/*
+ *
+ * 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.qpid.server.security.auth;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests the UsernamePrincipal.
+ *
+ */
+public class UsernamePrincipalTest extends TestCase
+{
+    public void testEqualitySameObject()
+    {
+        final UsernamePrincipal principal = new UsernamePrincipal("string");
+        assertTrue(principal.equals(principal));
+    }
+
+    public void testEqualitySameName()
+    {
+        final String string = "string";
+        final UsernamePrincipal principal1 = new UsernamePrincipal(string);
+        final UsernamePrincipal principal2 = new UsernamePrincipal(string);
+        assertTrue(principal1.equals(principal2));
+    }
+
+    public void testEqualityEqualName()
+    {
+        final UsernamePrincipal principal1 = new UsernamePrincipal(new String("string"));
+        final UsernamePrincipal principal2 = new UsernamePrincipal(new String("string"));
+        assertTrue(principal1.equals(principal2));
+    }
+
+    public void testInequalityDifferentUserPrincipals()
+    {
+        UsernamePrincipal principal1 = new UsernamePrincipal("string1");
+        UsernamePrincipal principal2 = new UsernamePrincipal("string2");
+        assertFalse(principal1.equals(principal2));
+    }
+
+    public void testInequalityNonUserPrincipal()
+    {
+        UsernamePrincipal principal = new UsernamePrincipal("string");
+        assertFalse(principal.equals(new String("string")));
+    }
+
+    public void testInequalityNull()
+    {
+        UsernamePrincipal principal = new UsernamePrincipal("string");
+        assertFalse(principal.equals(null));
+    }
+}

Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java (original)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java Fri Aug 24 15:33:00 2012
@@ -23,7 +23,7 @@ package org.apache.qpid.server.security.
 import junit.framework.TestCase;
 import org.apache.commons.codec.binary.Base64;
 
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
 
 import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.login.AccountNotFoundException;

Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java (original)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java Fri Aug 24 15:33:00 2012
@@ -22,7 +22,7 @@ package org.apache.qpid.server.security.
 
 import junit.framework.TestCase;
 
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
 
 import javax.security.auth.login.AccountNotFoundException;
 import java.io.BufferedReader;

Modified: qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java (original)
+++ qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java Fri Aug 24 15:33:00 2012
@@ -20,6 +20,8 @@
  */
 package org.apache.qpid.server.security.auth.manager;
 
+import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped;
+
 import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslServer;
 import org.apache.commons.configuration.CompositeConfiguration;
@@ -102,7 +104,8 @@ public class AnonymousAuthenticationMana
         assertEquals("Expected authentication to be successful",
                      AuthenticationResult.AuthenticationStatus.SUCCESS,
                      result.getStatus());
-        assertNotNull("Subject should not be null", result.getSubject());
+
+        assertOnlyContainsWrapped(AnonymousAuthenticationManager.ANONYMOUS_PRINCIPAL, result.getPrincipals());
     }
 
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org