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 [4/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-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java Fri Aug 24 15:33:00 2012
@@ -46,12 +46,12 @@ public class VirtualHostRestTest extends
 
     public void testGet() throws Exception
     {
-        List<Map<String, Object>> hosts = getJsonAsList("/rest/virtualhost/");
+        List<Map<String, Object>> hosts = getRestTestHelper().getJsonAsList("/rest/virtualhost/");
         assertNotNull("Hosts data cannot be null", hosts);
         assertEquals("Unexpected number of hosts", 3, hosts.size());
         for (String hostName : EXPECTED_HOSTS)
         {
-            Map<String, Object> host = find("name", hostName, hosts);
+            Map<String, Object> host = getRestTestHelper().find("name", hostName, hosts);
             Asserts.assertVirtualHost(hostName, host);
         }
     }
@@ -62,7 +62,7 @@ public class VirtualHostRestTest extends
         _connection = (AMQConnection) getConnection();
         _connection.createSession(true, Session.SESSION_TRANSACTED);
 
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
         Asserts.assertVirtualHost("test", hostDetails);
 
         @SuppressWarnings("unchecked")
@@ -74,18 +74,18 @@ public class VirtualHostRestTest extends
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VIRTUALHOST_EXCHANGES_ATTRIBUTE);
         assertEquals("Unexpected number of exchanges", 6, exchanges.size());
-        Asserts.assertDurableExchange("amq.fanout", "fanout", find(Exchange.NAME, "amq.fanout", exchanges));
-        Asserts.assertDurableExchange("qpid.management", "management", find(Exchange.NAME, "qpid.management", exchanges));
-        Asserts.assertDurableExchange("amq.topic", "topic", find(Exchange.NAME, "amq.topic", exchanges));
-        Asserts.assertDurableExchange("amq.direct", "direct", find(Exchange.NAME, "amq.direct", exchanges));
-        Asserts.assertDurableExchange("amq.match", "headers", find(Exchange.NAME, "amq.match", exchanges));
-        Asserts.assertDurableExchange("<<default>>", "direct", find(Exchange.NAME, "<<default>>", exchanges));
+        Asserts.assertDurableExchange("amq.fanout", "fanout", getRestTestHelper().find(Exchange.NAME, "amq.fanout", exchanges));
+        Asserts.assertDurableExchange("qpid.management", "management", getRestTestHelper().find(Exchange.NAME, "qpid.management", exchanges));
+        Asserts.assertDurableExchange("amq.topic", "topic", getRestTestHelper().find(Exchange.NAME, "amq.topic", exchanges));
+        Asserts.assertDurableExchange("amq.direct", "direct", getRestTestHelper().find(Exchange.NAME, "amq.direct", exchanges));
+        Asserts.assertDurableExchange("amq.match", "headers", getRestTestHelper().find(Exchange.NAME, "amq.match", exchanges));
+        Asserts.assertDurableExchange("<<default>>", "direct", getRestTestHelper().find(Exchange.NAME, "<<default>>", exchanges));
 
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VIRTUALHOST_QUEUES_ATTRIBUTE);
         assertEquals("Unexpected number of queues", 2, queues.size());
-        Map<String, Object> queue = find(Queue.NAME,  "queue", queues);
-        Map<String, Object> ping = find(Queue.NAME, "ping", queues);
+        Map<String, Object> queue = getRestTestHelper().find(Queue.NAME,  "queue", queues);
+        Map<String, Object> ping = getRestTestHelper().find(Queue.NAME, "ping", queues);
         Asserts.assertQueue("queue", "standard", queue);
         Asserts.assertQueue("ping", "standard", ping);
         assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.FALSE, queue.get(Queue.DURABLE));
@@ -116,14 +116,14 @@ public class VirtualHostRestTest extends
         lvqQueueAttributes.put(Queue.LVQ_KEY, "LVQ");
         createQueue(queueName + "-lvq", "lvq", lvqQueueAttributes);
 
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
 
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
-        Map<String, Object> standardQueue = find(Queue.NAME, queueName + "-standard" , queues);
-        Map<String, Object> sortedQueue = find(Queue.NAME, queueName + "-sorted" , queues);
-        Map<String, Object> priorityQueue = find(Queue.NAME, queueName + "-priority" , queues);
-        Map<String, Object> lvqQueue = find(Queue.NAME, queueName + "-lvq" , queues);
+        Map<String, Object> standardQueue = getRestTestHelper().find(Queue.NAME, queueName + "-standard" , queues);
+        Map<String, Object> sortedQueue = getRestTestHelper().find(Queue.NAME, queueName + "-sorted" , queues);
+        Map<String, Object> priorityQueue = getRestTestHelper().find(Queue.NAME, queueName + "-priority" , queues);
+        Map<String, Object> lvqQueue = getRestTestHelper().find(Queue.NAME, queueName + "-lvq" , queues);
 
         Asserts.assertQueue(queueName + "-standard", "standard", standardQueue);
         Asserts.assertQueue(queueName + "-sorted", "sorted", sortedQueue);
@@ -149,14 +149,14 @@ public class VirtualHostRestTest extends
         createExchange(exchangeName + "-headers", "headers");
         createExchange(exchangeName + "-fanout", "fanout");
 
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
 
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
-        Map<String, Object> directExchange = find(Queue.NAME, exchangeName + "-direct" , exchanges);
-        Map<String, Object> topicExchange = find(Queue.NAME, exchangeName + "-topic" , exchanges);
-        Map<String, Object> headersExchange = find(Queue.NAME, exchangeName + "-headers" , exchanges);
-        Map<String, Object> fanoutExchange = find(Queue.NAME, exchangeName + "-fanout" , exchanges);
+        Map<String, Object> directExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-direct" , exchanges);
+        Map<String, Object> topicExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-topic" , exchanges);
+        Map<String, Object> headersExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-headers" , exchanges);
+        Map<String, Object> fanoutExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-fanout" , exchanges);
 
         Asserts.assertDurableExchange(exchangeName + "-direct", "direct", directExchange);
         Asserts.assertDurableExchange(exchangeName + "-topic", "topic", topicExchange);
@@ -175,11 +175,11 @@ public class VirtualHostRestTest extends
         String queueName = getTestQueueName()+ "-lvq";
         createQueue(queueName, "lvq", null);
 
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
 
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
-        Map<String, Object> lvqQueue = find(Queue.NAME, queueName  , queues);
+        Map<String, Object> lvqQueue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
 
         Asserts.assertQueue(queueName , "lvq", lvqQueue);
         assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, lvqQueue.get(Queue.DURABLE));
@@ -192,11 +192,11 @@ public class VirtualHostRestTest extends
         int responseCode = tryCreateQueue(queueName, "sorted", null);
         assertEquals("Unexpected response code", 409, responseCode);
 
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
 
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
-        Map<String, Object> testQueue = find(Queue.NAME, queueName  , queues);
+        Map<String, Object> testQueue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
 
         assertNull("Sorted queue without a key was created ", testQueue);
     }
@@ -206,11 +206,11 @@ public class VirtualHostRestTest extends
         String queueName = getTestQueueName()+ "-priority";
         createQueue(queueName, "priority", null);
 
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
 
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
-        Map<String, Object> priorityQueue = find(Queue.NAME, queueName  , queues);
+        Map<String, Object> priorityQueue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
 
         Asserts.assertQueue(queueName , "priority", priorityQueue);
         assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, priorityQueue.get(Queue.DURABLE));
@@ -222,11 +222,11 @@ public class VirtualHostRestTest extends
         String queueName = getTestQueueName();
         createQueue(queueName, null, null);
 
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
 
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
-        Map<String, Object> queue = find(Queue.NAME, queueName  , queues);
+        Map<String, Object> queue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
 
         Asserts.assertQueue(queueName , "standard", queue);
     }
@@ -237,11 +237,11 @@ public class VirtualHostRestTest extends
         int responseCode = tryCreateQueue(queueName, "unsupported", null);
         assertEquals("Unexpected response code", 409, responseCode);
 
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
 
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
-        Map<String, Object> queue = find(Queue.NAME, queueName  , queues);
+        Map<String, Object> queue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
 
         assertNull("Queue of unsupported type was created", queue);
     }
@@ -251,10 +251,10 @@ public class VirtualHostRestTest extends
         String queueName = getTestQueueName();
         createQueue(queueName, null, null);
 
-        HttpURLConnection connection = openManagementConection("/rest/queue/test/" + queueName, "DELETE");
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/" + queueName, "DELETE");
         connection.connect();
         assertEquals("Unexpected response code", 200, connection.getResponseCode());
-        List<Map<String, Object>> queues = getJsonAsList("/rest/queue/test/" + queueName);
+        List<Map<String, Object>> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/" + queueName);
         assertEquals("Queue should be deleted", 0, queues.size());
     }
 
@@ -262,12 +262,12 @@ public class VirtualHostRestTest extends
     {
         String queueName = getTestQueueName();
         createQueue(queueName, null, null);
-        Map<String, Object> queueDetails = getJsonAsSingletonList("/rest/queue/test/" + queueName);
+        Map<String, Object> queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName);
 
-        HttpURLConnection connection = openManagementConection("/rest/queue/test?id=" + queueDetails.get(Queue.ID), "DELETE");
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test?id=" + queueDetails.get(Queue.ID), "DELETE");
         connection.connect();
         assertEquals("Unexpected response code", 200, connection.getResponseCode());
-        List<Map<String, Object>> queues = getJsonAsList("/rest/queue/test/" + queueName);
+        List<Map<String, Object>> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/" + queueName);
         assertEquals("Queue should be deleted", 0, queues.size());
     }
 
@@ -276,10 +276,10 @@ public class VirtualHostRestTest extends
         String exchangeName = getTestName();
         createExchange(exchangeName, "direct");
 
-        HttpURLConnection connection = openManagementConection("/rest/exchange/test/" + exchangeName, "DELETE");
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/" + exchangeName, "DELETE");
         connection.connect();
         assertEquals("Unexpected response code", 200, connection.getResponseCode());
-        List<Map<String, Object>> queues = getJsonAsList("/rest/exchange/test/" + exchangeName);
+        List<Map<String, Object>> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/" + exchangeName);
         assertEquals("Exchange should be deleted", 0, queues.size());
     }
 
@@ -287,12 +287,12 @@ public class VirtualHostRestTest extends
     {
         String exchangeName = getTestName();
         createExchange(exchangeName, "direct");
-        Map<String, Object> echangeDetails = getJsonAsSingletonList("/rest/exchange/test/" + exchangeName);
+        Map<String, Object> echangeDetails = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/" + exchangeName);
 
-        HttpURLConnection connection = openManagementConection("/rest/exchange/test?id=" + echangeDetails.get(Exchange.ID), "DELETE");
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test?id=" + echangeDetails.get(Exchange.ID), "DELETE");
         connection.connect();
         assertEquals("Unexpected response code", 200, connection.getResponseCode());
-        List<Map<String, Object>> queues = getJsonAsList("/rest/exchange/test/" + exchangeName);
+        List<Map<String, Object>> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/" + exchangeName);
         assertEquals("Exchange should be deleted", 0, queues.size());
     }
 
@@ -326,14 +326,14 @@ public class VirtualHostRestTest extends
         lvqQueueAttributes.put(Queue.LVQ_KEY, "LVQ");
         createQueue(queueName + "-lvq", "lvq", lvqQueueAttributes);
 
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
 
         @SuppressWarnings("unchecked")
         List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
-        Map<String, Object> standardQueue = find(Queue.NAME, queueName + "-standard" , queues);
-        Map<String, Object> sortedQueue = find(Queue.NAME, queueName + "-sorted" , queues);
-        Map<String, Object> priorityQueue = find(Queue.NAME, queueName + "-priority" , queues);
-        Map<String, Object> lvqQueue = find(Queue.NAME, queueName + "-lvq" , queues);
+        Map<String, Object> standardQueue = getRestTestHelper().find(Queue.NAME, queueName + "-standard" , queues);
+        Map<String, Object> sortedQueue = getRestTestHelper().find(Queue.NAME, queueName + "-sorted" , queues);
+        Map<String, Object> priorityQueue = getRestTestHelper().find(Queue.NAME, queueName + "-priority" , queues);
+        Map<String, Object> lvqQueue = getRestTestHelper().find(Queue.NAME, queueName + "-lvq" , queues);
 
         attributes.put(Queue.DURABLE, Boolean.TRUE);
         Asserts.assertQueue(queueName + "-standard", "standard", standardQueue, attributes);
@@ -355,25 +355,25 @@ public class VirtualHostRestTest extends
         attributes.put(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
 
         //verify the starting state
-        Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
         List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
         List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
 
-        assertNull("queue should not have already been present", find(Queue.NAME, queueName , queues));
-        assertNull("queue should not have already been present", find(Queue.NAME, queueName + "_DLQ" , queues));
-        assertNull("exchange should not have already been present", find(Exchange.NAME, queueName + "_DLE" , exchanges));
+        assertNull("queue should not have already been present", getRestTestHelper().find(Queue.NAME, queueName , queues));
+        assertNull("queue should not have already been present", getRestTestHelper().find(Queue.NAME, queueName + "_DLQ" , queues));
+        assertNull("exchange should not have already been present", getRestTestHelper().find(Exchange.NAME, queueName + "_DLE" , exchanges));
 
         //create the queue
         createQueue(queueName, "standard", attributes);
 
         //verify the new queue, as well as the DLQueue and DLExchange have been created
-        hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+        hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
         queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
         exchanges = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
 
-        Map<String, Object> queue = find(Queue.NAME, queueName , queues);
-        Map<String, Object> dlqQueue = find(Queue.NAME, queueName + "_DLQ" , queues);
-        Map<String, Object> dlExchange = find(Exchange.NAME, queueName + "_DLE" , exchanges);
+        Map<String, Object> queue = getRestTestHelper().find(Queue.NAME, queueName , queues);
+        Map<String, Object> dlqQueue = getRestTestHelper().find(Queue.NAME, queueName + "_DLQ" , queues);
+        Map<String, Object> dlExchange = getRestTestHelper().find(Exchange.NAME, queueName + "_DLE" , exchanges);
         assertNotNull("queue should not have been present", queue);
         assertNotNull("queue should not have been present", dlqQueue);
         assertNotNull("exchange should not have been present", dlExchange);
@@ -388,14 +388,14 @@ public class VirtualHostRestTest extends
 
     private void createExchange(String exchangeName, String exchangeType) throws IOException
     {
-        HttpURLConnection connection = openManagementConection("/rest/exchange/test/" + exchangeName, "PUT");
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/" + exchangeName, "PUT");
 
         Map<String, Object> queueData = new HashMap<String, Object>();
         queueData.put(Exchange.NAME, exchangeName);
         queueData.put(Exchange.DURABLE, Boolean.TRUE);
         queueData.put(Exchange.TYPE, exchangeType);
 
-        writeJsonRequest(connection, queueData);
+        getRestTestHelper().writeJsonRequest(connection, queueData);
         assertEquals("Unexpected response code", 201, connection.getResponseCode());
 
         connection.disconnect();
@@ -411,7 +411,7 @@ public class VirtualHostRestTest extends
     private int tryCreateQueue(String queueName, String queueType, Map<String, Object> attributes) throws IOException,
             JsonGenerationException, JsonMappingException
     {
-        HttpURLConnection connection = openManagementConection("/rest/queue/test/" + queueName, "PUT");
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/" + queueName, "PUT");
 
         Map<String, Object> queueData = new HashMap<String, Object>();
         queueData.put(Queue.NAME, queueName);
@@ -425,7 +425,7 @@ public class VirtualHostRestTest extends
             queueData.putAll(attributes);
         }
 
-        writeJsonRequest(connection, queueData);
+        getRestTestHelper().writeJsonRequest(connection, queueData);
         int responseCode = connection.getResponseCode();
         connection.disconnect();
         return responseCode;

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,187 @@
+/*
+ *
+ * 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.systest.rest.acl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.server.management.plugin.servlet.rest.QpidRestTestCase;
+import org.apache.qpid.server.security.acl.AbstractACLTestCase;
+
+public class GroupRestACLTest extends QpidRestTestCase
+{
+    private static final String FILE_GROUP_MANAGER = "FileGroupManager";
+
+    private static final String ALLOWED_GROUP = "allowedGroup";
+    private static final String DENIED_GROUP = "deniedGroup";
+    private static final String OTHER_GROUP = "otherGroup";
+
+    private static final String ALLOWED_USER = "webadmin";
+    private static final String DENIED_USER = "admin";
+    private static final String OTHER_USER = "admin";
+
+    private File _groupFile;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        _groupFile = createTemporaryGroupFile();
+
+        setConfigurationProperty("security.file-group-manager.attributes.attribute.name", "groupFile");
+        setConfigurationProperty("security.file-group-manager.attributes.attribute.value", _groupFile.getAbsolutePath());
+
+        //DONT call super.setUp(), the tests will start the broker after configuring it
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        super.tearDown();
+
+        if (_groupFile != null)
+        {
+            if (_groupFile.exists())
+            {
+                _groupFile.delete();
+            }
+        }
+    }
+
+    private File createTemporaryGroupFile() throws Exception
+    {
+        File groupFile = File.createTempFile("group", "grp");
+        groupFile.deleteOnExit();
+
+        Properties props = new Properties();
+        props.put(ALLOWED_GROUP + ".users", ALLOWED_USER);
+        props.put(DENIED_GROUP + ".users", DENIED_USER);
+        props.put(OTHER_GROUP + ".users", OTHER_USER);
+
+        props.store(new FileOutputStream(groupFile), "test group file");
+
+        return groupFile;
+    }
+
+    public void testCreateGroup() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " CREATE GROUP",
+                "ACL DENY-LOG " + DENIED_GROUP + " CREATE GROUP");
+
+        //Start the broker with the custom config
+        super.setUp();
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+
+        Map<String, Object> data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 3);
+
+        getRestTestHelper().createGroup("newGroup", FILE_GROUP_MANAGER);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 4);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        //TODO: the expected response code needs changed when we overhaul the brokers error handling
+        getRestTestHelper().createGroup("anotherNewGroup", FILE_GROUP_MANAGER, HttpServletResponse.SC_CONFLICT);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 4);
+    }
+
+    public void testDeleteGroup() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " DELETE GROUP",
+                "ACL DENY-LOG " + DENIED_GROUP + " DELETE GROUP");
+
+        //Start the broker with the custom config
+        super.setUp();
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        Map<String, Object> data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 3);
+
+        //TODO: the expected response code needs changed when we overhaul the brokers error handling
+        getRestTestHelper().removeGroup(OTHER_GROUP, FILE_GROUP_MANAGER, HttpServletResponse.SC_CONFLICT);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 3);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+
+        getRestTestHelper().removeGroup(OTHER_GROUP, FILE_GROUP_MANAGER);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 2);
+    }
+
+    public void testUpdateGroupAddMember() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE GROUP",
+                "ACL DENY-LOG " + DENIED_GROUP + " UPDATE GROUP");
+
+        //Start the broker with the custom config
+        super.setUp();
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+        getRestTestHelper().createNewGroupMember(FILE_GROUP_MANAGER, OTHER_GROUP, "newGroupMember", HttpServletResponse.SC_CONFLICT);
+        assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().createNewGroupMember(FILE_GROUP_MANAGER, OTHER_GROUP, "newGroupMember");
+        assertNumberOfGroupMembers(OTHER_GROUP, 2);
+    }
+
+    public void testUpdateGroupDeleteMember() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE GROUP",
+                "ACL DENY-LOG " + DENIED_GROUP + " UPDATE GROUP");
+
+        //Start the broker with the custom config
+        super.setUp();
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+        getRestTestHelper().removeMemberFromGroup(FILE_GROUP_MANAGER, OTHER_GROUP, OTHER_USER, HttpServletResponse.SC_CONFLICT);
+        assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().removeMemberFromGroup(FILE_GROUP_MANAGER, OTHER_GROUP, OTHER_USER);
+        assertNumberOfGroupMembers(OTHER_GROUP, 0);
+    }
+
+    private void assertNumberOfGroupMembers(String groupName, int expectedNumberOfMembers) throws IOException
+    {
+        Map<String, Object> group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/" + groupName);
+        getRestTestHelper().assertNumberOfGroupMembers(group, expectedNumberOfMembers);
+    }
+}

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,188 @@
+/*
+ * 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.systest.rest.acl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.server.management.plugin.servlet.rest.QpidRestTestCase;
+import org.apache.qpid.server.security.acl.AbstractACLTestCase;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+
+public class UserRestACLTest extends QpidRestTestCase
+{
+    private static final String ALLOWED_GROUP = "allowedGroup";
+    private static final String DENIED_GROUP = "deniedGroup";
+    private static final String OTHER_GROUP = "otherGroup";
+
+    private static final String ALLOWED_USER = "webadmin";
+    private static final String DENIED_USER = "admin";
+    private static final String OTHER_USER = "other";
+
+    private File _groupFile;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        _groupFile = createTemporaryGroupFile();
+
+        setConfigurationProperty("security.file-group-manager.attributes.attribute.name", "groupFile");
+        setConfigurationProperty("security.file-group-manager.attributes.attribute.value", _groupFile.getAbsolutePath());
+
+        getRestTestHelper().configureTemporaryPasswordFile(this, ALLOWED_USER, DENIED_USER, OTHER_USER);
+
+        //DONT call super.setUp(), the tests will start the broker after configuring it
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        super.tearDown();
+
+        if (_groupFile != null)
+        {
+            if (_groupFile.exists())
+            {
+                _groupFile.delete();
+            }
+        }
+    }
+
+    private File createTemporaryGroupFile() throws Exception
+    {
+        File groupFile = File.createTempFile("group", "grp");
+        groupFile.deleteOnExit();
+
+        Properties props = new Properties();
+        props.put(ALLOWED_GROUP + ".users", ALLOWED_USER);
+        props.put(DENIED_GROUP + ".users", DENIED_USER);
+        props.put(OTHER_GROUP + ".users", OTHER_USER);
+
+        props.store(new FileOutputStream(groupFile), "test group file");
+
+        return groupFile;
+    }
+
+    public void testAddUser() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " CREATE USER",
+                "ACL DENY-LOG " + DENIED_GROUP + " CREATE USER");
+
+        //Start the broker with the custom config
+        super.setUp();
+
+        String newUser = "newUser";
+        String password = "password";
+
+        assertUserDoesNotExist(newUser);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        getRestTestHelper().createOrUpdateUser(newUser, password, HttpServletResponse.SC_CONFLICT);
+        assertUserDoesNotExist(newUser);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().createOrUpdateUser(newUser, password);
+        assertUserExists(newUser);
+    }
+
+    public void testDeleteUser() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " DELETE USER",
+                "ACL DENY-LOG " + DENIED_GROUP + " DELETE USER");
+
+        //Start the broker with the custom config
+        super.setUp();
+
+        assertUserExists(OTHER_USER);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+        getRestTestHelper().removeUser(OTHER_USER, HttpServletResponse.SC_CONFLICT);
+        assertUserExists(OTHER_USER);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().removeUser(OTHER_USER);
+        assertUserDoesNotExist(OTHER_USER);
+    }
+
+    public void testUpdateUser() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE USER",
+                "ACL DENY-LOG " + DENIED_GROUP + " UPDATE USER");
+
+        //Start the broker with the custom config
+        super.setUp();
+
+        String newPassword = "newPassword";
+
+        checkPassword(OTHER_USER, OTHER_USER, true);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+        getRestTestHelper().createOrUpdateUser(OTHER_USER, newPassword, HttpServletResponse.SC_CONFLICT);
+
+        checkPassword(OTHER_USER, newPassword, false);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().createOrUpdateUser(OTHER_USER, newPassword, HttpServletResponse.SC_OK); // expect SC_OK rather than the default SC_CREATED
+
+        checkPassword(OTHER_USER, newPassword, true);
+        checkPassword(OTHER_USER, OTHER_USER, false);
+    }
+
+    private void checkPassword(String username, String password, boolean passwordExpectedToBeCorrect) throws IOException
+    {
+        getRestTestHelper().setUsernameAndPassword(username, password);
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/user/PrincipalDatabaseAuthenticationManager/", "GET");
+
+        boolean passwordIsCorrect = connection.getResponseCode() == HttpServletResponse.SC_OK;
+
+        connection.disconnect();
+
+        assertEquals(passwordExpectedToBeCorrect, passwordIsCorrect);
+    }
+
+    private void assertUserDoesNotExist(String newUser) throws JsonParseException, JsonMappingException, IOException
+    {
+        String path = "/rest/user/PrincipalDatabaseAuthenticationManager/" + newUser;
+        List<Map<String, Object>> userDetailsList = getRestTestHelper().getJsonAsList(path);
+        assertTrue(userDetailsList.isEmpty());
+    }
+
+    private void assertUserExists(String username) throws IOException
+    {
+        String path = "/rest/user/PrincipalDatabaseAuthenticationManager/" + username;
+        Map<String, Object> userDetails = getRestTestHelper().getJsonAsSingletonList(path);
+
+        assertEquals(
+                "User returned by " + path + " should have name=" + username + ". The returned JSON was: " + userDetails,
+                username,
+                userDetails.get("name"));
+    }
+}

Modified: qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java Fri Aug 24 15:33:00 2012
@@ -29,9 +29,8 @@ import org.apache.qpid.server.logging.me
 import org.apache.qpid.server.registry.ApplicationRegistry;
 import org.apache.qpid.server.registry.IApplicationRegistry;
 
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
 import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
-
 import javax.management.JMException;
 import javax.management.MBeanServer;
 import javax.management.MBeanServerFactory;
@@ -73,7 +72,7 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * This class starts up an MBeanserver. If out of the box agent has been enabled then there are no 
+ * This class starts up an MBeanserver. If out of the box agent has been enabled then there are no
  * security features implemented like user authentication and authorisation.
  */
 public class JMXManagedObjectRegistry implements ManagedObjectRegistry
@@ -244,8 +243,8 @@ public class JMXManagedObjectRegistry im
             protected RMIConnection makeClient(String connectionId, Subject subject) throws IOException
             {
                 final RMIConnection makeClient = super.makeClient(connectionId, subject);
-                final UsernamePrincipal usernamePrincipalFromSubject = UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
-                connectionIdUsernameMap.put(connectionId, usernamePrincipalFromSubject.getName());
+                final AuthenticatedPrincipal authenticatedPrincipalFromSubject = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+                connectionIdUsernameMap.put(connectionId, authenticatedPrincipalFromSubject.getName());
                 return makeClient;
             }
         };
@@ -451,7 +450,7 @@ public class JMXManagedObjectRegistry im
                 _log.error("Exception while closing the JMX ConnectorServer: ",  e);
             }
         }
-        
+
         if (_rmiRegistry != null)
         {
             // Stopping the RMI registry
@@ -469,7 +468,7 @@ public class JMXManagedObjectRegistry im
                 _log.error("Exception while closing the RMI Registry: ", e);
             }
         }
-        
+
         //ObjectName query to gather all Qpid related MBeans
         ObjectName mbeanNameQuery = null;
         try

Modified: qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java Fri Aug 24 15:33:00 2012
@@ -30,6 +30,7 @@ import org.apache.qpid.server.registry.A
 import org.apache.qpid.server.registry.IApplicationRegistry;
 import org.apache.qpid.server.security.SecurityManager;
 import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
 
 import javax.management.Attribute;
 import javax.management.JMException;
@@ -41,7 +42,6 @@ import javax.management.NotificationList
 import javax.management.ObjectName;
 import javax.management.RuntimeErrorException;
 import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXPrincipal;
 import javax.management.remote.MBeanServerForwarder;
 import javax.security.auth.Subject;
 import java.lang.reflect.InvocationHandler;
@@ -52,7 +52,6 @@ import java.security.AccessControlContex
 import java.security.AccessController;
 import java.util.Arrays;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. It delegates
@@ -101,7 +100,7 @@ public class MBeanInvocationHandlerImpl 
         {
             ObjectName mbean = (ObjectName) args[0];
 
-            if(!DefaultManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain()))
+            if(!ManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain()))
             {
                 return true;
             }
@@ -151,11 +150,13 @@ public class MBeanInvocationHandlerImpl 
                 return method.invoke(_mbs, args);
             }
 
-            // Retrieve JMXPrincipal from Subject
-            Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
-            if (principals == null || principals.isEmpty())
+            try
+            {
+                AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+            }
+            catch(Exception e)
             {
-                throw new SecurityException("Access denied: no JMX principal");
+                throw new SecurityException("Access denied: no authenticated principal", e);
             }
 
             // Save the subject
@@ -381,6 +382,7 @@ public class MBeanInvocationHandlerImpl 
         String user = null;
         if (handback instanceof Map)
         {
+            @SuppressWarnings("unchecked")
             final Map<String, String> connectionIdUsernameMap = (Map<String, String>) handback;
             user = connectionIdUsernameMap.get(connectionId);
         }

Modified: qpid/trunk/qpid/java/broker/etc/broker_example.acl
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/etc/broker_example.acl?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/etc/broker_example.acl (original)
+++ qpid/trunk/qpid/java/broker/etc/broker_example.acl Fri Aug 24 15:33:00 2012
@@ -19,14 +19,7 @@
 
 ### EXAMPLE ACL V2 FILE
 ### NOTE: Rules are considered from top to bottom, and the first matching rule governs the decision.
-
-### DEFINE GROUPS ###
-
-#Define a 'messaging-users' group with users  'client' and  'server' in it
-GROUP messaging-users client server
-
-#Define a group for management web console users
-GROUP webadmins webadmin
+### Rules may refer to users or groups. Groups are currently defined in the etc/groups file.
 
 ### JMX MANAGEMENT ####
 
@@ -34,9 +27,9 @@ GROUP webadmins webadmin
 # This is used for items such as querying the management API and broker release versions.
 ACL ALLOW ALL ACCESS METHOD component="ServerInformation"
 
-# Allow 'admin' all management operations. To reduce log file noise, only non-read-only operations are logged.
-ACL ALLOW admin ACCESS METHOD
-ACL ALLOW-LOG admin ALL METHOD
+# Allow 'administrators' all management operations. To reduce log file noise, only non-read-only operations are logged.
+ACL ALLOW administrators ACCESS METHOD
+ACL ALLOW-LOG administrators ALL METHOD
 
 # Allow 'guest' to view logger levels, and use getter methods on LoggingManagement
 ACL ALLOW guest ACCESS METHOD component="LoggingManagement" name="viewEffectiveRuntimeLoggerLevels"
@@ -87,6 +80,13 @@ ACL ALLOW-LOG webadmins CREATE EXCHANGE
 ACL ALLOW-LOG webadmins DELETE EXCHANGE
 ACL ALLOW-LOG webadmins BIND   EXCHANGE
 ACL ALLOW-LOG webadmins UNBIND EXCHANGE
+ACL ALLOW-LOG webadmins CREATE GROUP
+ACL ALLOW-LOG webadmins DELETE GROUP
+ACL ALLOW-LOG webadmins UPDATE GROUP
+ACL ALLOW-LOG webadmins CREATE USER
+ACL ALLOW-LOG webadmins DELETE USER
+ACL ALLOW-LOG webadmins UPDATE USER
+
 ACL ALLOW-LOG webadmins UPDATE METHOD
 
 # at the moment only the following UPDATE METHOD rules are supported by web management console
@@ -96,5 +96,5 @@ ACL ALLOW-LOG webadmins UPDATE METHOD
 
 ### DEFAULT ###
 
-#Deny all users from performing all operations
+# Deny all users from performing all operations
 ACL DENY-LOG all all

Modified: qpid/trunk/qpid/java/broker/etc/config.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/etc/config.xml?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/etc/config.xml (original)
+++ qpid/trunk/qpid/java/broker/etc/config.xml Fri Aug 24 15:33:00 2012
@@ -79,13 +79,24 @@
             </principal-database>
         </pd-auth-manager>
 
-        <!-- By default, all authenticated users have permissions to perform all actions -->
+        <!--
+        <file-group-manager>
+            <attributes>
+              <attribute>
+                <name>groupFile</name>
+                <value>${conf}/groups</value>
+              </attribute>
+            </attributes>
+        </file-group-manager>
+        -->
+
+        <!--
+        ACL Example. This example illustrates securing both management and messaging.
+        By default, all authenticated users have permissions to perform all actions
 
-        <!-- ACL Example
-             This example illustrates securing the both Management (JMX) and Messaging.
         <acl>${conf}/broker_example.acl</acl>
         -->
-        
+
         <msg-auth>false</msg-auth>
     </security>
 

Added: qpid/trunk/qpid/java/broker/etc/groups
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/etc/groups?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/etc/groups (added)
+++ qpid/trunk/qpid/java/broker/etc/groups Fri Aug 24 15:33:00 2012
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# To define a group, use the format:
+#
+# <groupname>.users=<user1>,<user2>,...,<usern>
+#
+
+messaging-users.users=guest,client,server
+administrators.users=admin
+webadmins.users=webadmin
+

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java Fri Aug 24 15:33:00 2012
@@ -32,9 +32,8 @@ import org.apache.qpid.framing.MethodReg
 import org.apache.qpid.protocol.AMQConstant;
 import org.apache.qpid.server.protocol.AMQProtocolSession;
 import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
 import org.apache.qpid.server.state.AMQState;
 import org.apache.qpid.server.state.AMQStateManager;
 import org.apache.qpid.server.state.StateAwareMethodListener;
@@ -61,7 +60,7 @@ public class ConnectionSecureOkMethodHan
     {
         AMQProtocolSession session = stateManager.getProtocolSession();
 
-        AuthenticationManager authMgr = stateManager.getAuthenticationManager();
+        SubjectCreator subjectCreator = stateManager.getSubjectCreator();
 
         SaslServer ss = session.getSaslServer();
         if (ss == null)
@@ -69,7 +68,7 @@ public class ConnectionSecureOkMethodHan
             throw new AMQException("No SASL context set up in session");
         }
         MethodRegistry methodRegistry = session.getMethodRegistry();
-        AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
+        SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, body.getResponse());
         switch (authResult.getStatus())
         {
             case ERROR:

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java Fri Aug 24 15:33:00 2012
@@ -32,9 +32,8 @@ import org.apache.qpid.protocol.AMQConst
 import org.apache.qpid.server.configuration.ServerConfiguration;
 import org.apache.qpid.server.protocol.AMQProtocolSession;
 import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
 import org.apache.qpid.server.state.AMQState;
 import org.apache.qpid.server.state.AMQStateManager;
 import org.apache.qpid.server.state.StateAwareMethodListener;
@@ -65,11 +64,11 @@ public class ConnectionStartOkMethodHand
         _logger.info("SASL Mechanism selected: " + body.getMechanism());
         _logger.info("Locale selected: " + body.getLocale());
 
-        AuthenticationManager authMgr = stateManager.getAuthenticationManager();
+        SubjectCreator subjectCreator = stateManager.getSubjectCreator();
         SaslServer ss = null;
         try
         {
-            ss = authMgr.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN(), session.getPeerPrincipal());
+            ss = subjectCreator.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN(), session.getPeerPrincipal());
 
             if (ss == null)
             {
@@ -78,7 +77,7 @@ public class ConnectionStartOkMethodHand
 
             session.setSaslServer(ss);
 
-            final AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
+            final SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, body.getResponse());
             //save clientProperties
             session.setClientProperties(body.getClientProperties());
 

Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java (added)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,48 @@
+package org.apache.qpid.server.logging.actors;
+
+import java.security.AccessController;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+
+public abstract class AbstractManagementActor extends AbstractActor
+{
+    /**
+     * Holds the principal name to display when principal subject is not available.
+     * <p>
+     * This is useful for cases when users invoke JMX operation over JConsole
+     * attached to the local JVM.
+     */
+    protected static final String UNKNOWN_PRINCIPAL = "N/A";
+
+    /** used when the principal name cannot be discovered from the Subject */
+    private final String _fallbackPrincipalName;
+
+    public AbstractManagementActor(RootMessageLogger rootLogger, String fallbackPrincipalName)
+    {
+        super(rootLogger);
+        _fallbackPrincipalName = fallbackPrincipalName;
+    }
+
+    /**
+     * Returns current {@link AuthenticatedPrincipal} name or {@link #_fallbackPrincipalName}
+     * if it can't be found.
+     */
+    protected String getPrincipalName()
+    {
+        String identity = _fallbackPrincipalName;
+
+        final Subject subject = Subject.getSubject(AccessController.getContext());
+        if (subject != null)
+        {
+            AuthenticatedPrincipal authenticatedPrincipal = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subject);
+            if(authenticatedPrincipal != null)
+            {
+                identity = authenticatedPrincipal.getName();
+            }
+        }
+        return identity;
+    }
+}
\ No newline at end of file

Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java (added)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.text.MessageFormat;
+
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.subjects.LogSubjectFormat;
+
+/**
+ * HttpManagement actor to use in {@link AbstractServlet} to log all http management operational logging.
+ * 
+ * An instance is required per http Session.
+ */
+public class HttpManagementActor extends AbstractManagementActor
+{
+    private String _cachedLogString;
+    private String _lastPrincipalName;
+    private String _address;
+
+    public HttpManagementActor(RootMessageLogger rootLogger, String ip, int port)
+    {
+        super(rootLogger, UNKNOWN_PRINCIPAL);
+        _address = ip + ":" + port;
+    }
+
+    private synchronized String getAndCacheLogString()
+    {
+        String principalName = getPrincipalName();
+
+        if(!principalName.equals(_lastPrincipalName))
+        {
+            _lastPrincipalName = principalName;
+             _cachedLogString = "[" + MessageFormat.format(LogSubjectFormat.MANAGEMENT_FORMAT, principalName, _address) + "] ";
+        }
+
+        return _cachedLogString;
+    }
+
+    public String getLogMessage()
+    {
+        return getAndCacheLogString();
+    }
+}

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java Fri Aug 24 15:33:00 2012
@@ -21,58 +21,31 @@
 package org.apache.qpid.server.logging.actors;
 
 import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.subjects.LogSubjectFormat;
 
-import javax.management.remote.JMXPrincipal;
-import javax.security.auth.Subject;
-import java.security.AccessController;
-import java.security.Principal;
 import java.text.MessageFormat;
-import java.util.Set;
 
 /**
  * Management actor to use in {@link MBeanInvocationHandlerImpl} to log all management operational logging.
  */
-public class ManagementActor extends AbstractActor
+public class ManagementActor extends AbstractManagementActor
 {
-    /**
-     * Holds the principal name to display when principal subject is not available.
-     * <p>
-     * This is useful for cases when users invoke JMX operation over JConsole
-     * attached to the local JVM.
-     */
-    private static final String UNKNOWN_PRINCIPAL = "N/A";
-
     private String _lastThreadName = null;
 
     /**
-     * LOG FORMAT for the ManagementActor,
-     * Uses a MessageFormat call to insert the required values according to
-     * these indices:
-     *
-     * 0 - User ID
-     * 1 - IP
-     */
-    public static final String MANAGEMENT_FORMAT = "mng:{0}({1})";
-
-    /**
      * The logString to be used for logging
      */
     private String _logStringContainingPrincipal;
 
-    /** used when the principal name cannot be discovered from the Subject */
-    private final String _fallbackPrincipalName;
-
     /** @param rootLogger The RootLogger to use for this Actor */
     public ManagementActor(RootMessageLogger rootLogger)
     {
-        super(rootLogger);
-        _fallbackPrincipalName = UNKNOWN_PRINCIPAL;
+        super(rootLogger, UNKNOWN_PRINCIPAL);
     }
 
     public ManagementActor(RootMessageLogger rootLogger, String principalName)
     {
-        super(rootLogger);
-        _fallbackPrincipalName = principalName;
+        super(rootLogger, principalName);
     }
 
     private synchronized String getAndCacheLogString()
@@ -96,7 +69,7 @@ public class ManagementActor extends Abs
             if (split.length == 2)
             {
                 String ip = currentName.split("-")[1];
-                actor = MessageFormat.format(MANAGEMENT_FORMAT, principalName, ip);
+                actor = MessageFormat.format(LogSubjectFormat.MANAGEMENT_FORMAT, principalName, ip);
             }
             else
             {
@@ -119,33 +92,8 @@ public class ManagementActor extends Abs
         return logString;
     }
 
-    /**
-     * Returns current JMX principal name.
-     *
-     * @return principal name or null if principal can not be found
-     */
-    private String getPrincipalName()
-    {
-        String identity = _fallbackPrincipalName;
-
-        // retrieve Subject from current AccessControlContext
-        final Subject subject = Subject.getSubject(AccessController.getContext());
-        if (subject != null)
-        {
-            // retrieve JMXPrincipal from Subject
-            final Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
-            if (principals != null && !principals.isEmpty())
-            {
-                final Principal principal = principals.iterator().next();
-                identity = principal.getName();
-            }
-        }
-        return identity;
-    }
-
     public String getLogMessage()
     {
         return getAndCacheLogString();
     }
-
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java Fri Aug 24 15:33:00 2012
@@ -32,11 +32,19 @@ package org.apache.qpid.server.logging.s
 
 public class LogSubjectFormat
 {
+
     private LogSubjectFormat()
     {
     }
 
     /**
+     * LOG FORMAT for the ManagementActors,
+     * 0 - User ID
+     * 1 - IP[:Port]
+     */
+    public static final String MANAGEMENT_FORMAT = "mng:{0}({1})";
+
+    /**
      * LOG FORMAT for the Subscription Log Subject
      * 0 - Subscription ID
      */

Copied: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Group.java (from r1376735, qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Group.java?p2=qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Group.java&p1=qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java&r1=1376735&r2=1376968&rev=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Group.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,14 +17,13 @@
  * under the License.
  *
  */
-
 package org.apache.qpid.server.model;
 
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 
-public interface User extends ConfiguredObject
+public interface Group extends ConfiguredObject
 {
     String CREATED         = "created";
     String DURABLE         = "durable";
@@ -35,7 +33,6 @@ public interface User extends Configured
     String STATE           = "state";
     String TIME_TO_LIVE    = "timeToLive";
     String UPDATED         = "updated";
-    String PASSWORD        = "password";
 
     // Attributes
     public static final Collection<String> AVAILABLE_ATTRIBUTES =
@@ -48,12 +45,8 @@ public interface User extends Configured
                            LIFETIME_POLICY,
                            TIME_TO_LIVE,
                            CREATED,
-                           UPDATED,
-                           PASSWORD
+                           UPDATED
                    ));
 
-    public String getPassword();
-
-    public void setPassword(String password);
 
 }

Copied: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java (from r1376735, qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java?p2=qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java&p1=qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java&r1=1376735&r2=1376968&rev=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.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,14 +17,13 @@
  * under the License.
  *
  */
-
 package org.apache.qpid.server.model;
 
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 
-public interface User extends ConfiguredObject
+public interface GroupMember extends ConfiguredObject
 {
     String CREATED         = "created";
     String DURABLE         = "durable";
@@ -35,7 +33,6 @@ public interface User extends Configured
     String STATE           = "state";
     String TIME_TO_LIVE    = "timeToLive";
     String UPDATED         = "updated";
-    String PASSWORD        = "password";
 
     // Attributes
     public static final Collection<String> AVAILABLE_ATTRIBUTES =
@@ -48,12 +45,8 @@ public interface User extends Configured
                            LIFETIME_POLICY,
                            TIME_TO_LIVE,
                            CREATED,
-                           UPDATED,
-                           PASSWORD
+                           UPDATED
                    ));
 
-    public String getPassword();
-
-    public void setPassword(String password);
 
 }

Added: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java?rev=1376968&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java (added)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java Fri Aug 24 15:33:00 2012
@@ -0,0 +1,51 @@
+/*
+ * 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.model;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+public interface GroupProvider extends ConfiguredObject
+{
+    public static final String ID = "id";
+    public static final String DESCRIPTION = "description";
+    public static final String NAME = "name";
+    public static final String STATE = "state";
+    public static final String DURABLE = "durable";
+    public static final String LIFETIME_POLICY = "lifetimePolicy";
+    public static final String TIME_TO_LIVE = "timeToLive";
+    public static final String CREATED = "created";
+    public static final String UPDATED = "updated";
+    public static final String TYPE = "type";
+
+    public static final Collection<String> AVAILABLE_ATTRIBUTES =
+            Collections.unmodifiableList(
+                    Arrays.asList(ID,
+                                  NAME,
+                                  DESCRIPTION,
+                                  STATE,
+                                  DURABLE,
+                                  LIFETIME_POLICY,
+                                  TIME_TO_LIVE,
+                                  CREATED,
+                                  UPDATED,
+                                  TYPE));
+}

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java Fri Aug 24 15:33:00 2012
@@ -47,6 +47,7 @@ public class Model
         addRelationship(Broker.class, VirtualHost.class);
         addRelationship(Broker.class, Port.class);
         addRelationship(Broker.class, AuthenticationProvider.class);
+        addRelationship(Broker.class, GroupProvider.class);
 
         addRelationship(VirtualHost.class, Exchange.class);
         addRelationship(VirtualHost.class, Queue.class);
@@ -54,6 +55,10 @@ public class Model
         addRelationship(VirtualHost.class, VirtualHostAlias.class);
 
         addRelationship(AuthenticationProvider.class, User.class);
+        addRelationship(User.class, GroupMember.class);
+
+        addRelationship(GroupProvider.class, Group.class);
+        addRelationship(Group.class, GroupMember.class);
 
         addRelationship(Connection.class, Session.class);
 

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java Fri Aug 24 15:33:00 2012
@@ -63,6 +63,11 @@ public class UUIDGenerator
         return createUUID(User.class.getName(), authenticationProviderName, userName);
     }
 
+    public static UUID generateGroupUUID(String groupProviderName, String groupName)
+    {
+        return createUUID(Group.class.getName(), groupProviderName, groupName);
+    }
+
     public static UUID generateVhostUUID(String virtualHostName)
     {
         return createUUID(VirtualHost.class.getName(), virtualHostName);
@@ -77,4 +82,9 @@ public class UUIDGenerator
     {
         return createUUID(Consumer.class.getName(), virtualHostName, queueName, connectionRemoteAddress, channelNumber, consumerName);
     }
+
+    public static UUID generateGroupMemberUUID(String groupProviderName, String groupName, String groupMemberName)
+    {
+        return createUUID(GroupMember.class.getName(), groupProviderName, groupName, groupMemberName);
+    }
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java Fri Aug 24 15:33:00 2012
@@ -52,8 +52,6 @@ public interface User extends Configured
                            PASSWORD
                    ));
 
-    public String getPassword();
-
     public void setPassword(String password);
 
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java Fri Aug 24 15:33:00 2012
@@ -38,7 +38,7 @@ import org.apache.qpid.server.security.a
 import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
 import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
 import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
 
 public abstract class AuthenticationProviderAdapter<T extends AuthenticationManager> extends AbstractAdapter implements AuthenticationProvider
 {
@@ -147,7 +147,7 @@ public abstract class AuthenticationProv
     {
         if(TYPE.equals(name))
         {
-            return _authManager.getClass().getSimpleName();
+            return getName();
         }
         else if(CREATED.equals(name))
         {
@@ -195,7 +195,8 @@ public abstract class AuthenticationProv
                                                       Map<String, Object> attributes,
                                                       ConfiguredObject... otherParents)
     {
-        return null;
+        throw new IllegalArgumentException("This authentication provider does not support" +
+                                           " creating children of type: " + childClass);
     }
 
     private static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager>
@@ -220,15 +221,20 @@ public abstract class AuthenticationProv
         @Override
         public boolean createUser(String username, String password, Map<String, String> attributes)
         {
-            return getPrincipalDatabase().createPrincipal(new UsernamePrincipal(username), password.toCharArray());
+            if(getSecurityManager().authoriseUserOperation(Operation.CREATE, username))
+            {
+                return getPrincipalDatabase().createPrincipal(new UsernamePrincipal(username), password.toCharArray());
+            }
+            else
+            {
+                throw new AccessControlException("Do not have permission to create new user");
+            }
         }
 
         @Override
         public void deleteUser(String username) throws AccountNotFoundException
         {
-            if(getSecurityManager().authoriseMethod(Operation.DELETE,
-                                                    "UserManagement",
-                                                    "deleteUser"))
+            if(getSecurityManager().authoriseUserOperation(Operation.DELETE, username))
             {
 
                 getPrincipalDatabase().deletePrincipal(new UsernamePrincipal(username));
@@ -252,18 +258,13 @@ public abstract class AuthenticationProv
         @Override
         public void setPassword(String username, String password) throws AccountNotFoundException
         {
-            getPrincipalDatabase().updatePassword(new UsernamePrincipal(username), password.toCharArray());
-        }
-
-        public void reload() throws IOException
-        {
-            if(getSecurityManager().authoriseMethod(Operation.UPDATE, "UserManagement", "reload"))
+            if(getSecurityManager().authoriseUserOperation(Operation.UPDATE, username))
             {
-                getPrincipalDatabase().reload();
+                getPrincipalDatabase().updatePassword(new UsernamePrincipal(username), password.toCharArray());
             }
             else
             {
-                throw new AccessControlException("Do not have permission to reload principal database");
+                throw new AccessControlException("Do not have permission to set password");
             }
         }
 
@@ -279,6 +280,11 @@ public abstract class AuthenticationProv
             return users;
         }
 
+        public void reload() throws IOException
+        {
+            getPrincipalDatabase().reload();
+        }
+
         @Override
         public <C extends ConfiguredObject> C createChild(Class<C> childClass,
                                                           Map<String, Object> attributes,
@@ -286,19 +292,19 @@ public abstract class AuthenticationProv
         {
             if(childClass == User.class)
             {
-                Principal p = new UsernamePrincipal((String) attributes.get("name"));
-                if(getSecurityManager().authoriseMethod(Operation.UPDATE, "UserManagement", "createUser"))
+                String username = (String) attributes.get("name");
+                String password = (String) attributes.get("password");
+                Principal p = new UsernamePrincipal(username);
+
+                if(createUser(username, password,null))
                 {
-                    if(getPrincipalDatabase().createPrincipal(p, ((String)attributes.get("password")).toCharArray()))
-                    {
-                        return (C) new PrincipalAdapter(p);
-                    }
+                    return (C) new PrincipalAdapter(p);
                 }
                 else
                 {
-                    throw new AccessControlException("Do not have permission to create a new user");
+                    //TODO? Silly interface on the PrincipalDatabase at fault
+                    throw new RuntimeException("Failed to create user");
                 }
-
             }
 
             return super.createChild(childClass, attributes, otherParents);
@@ -336,12 +342,6 @@ public abstract class AuthenticationProv
             }
 
             @Override
-            public String getPassword()
-            {
-                return null;
-            }
-
-            @Override
             public void setPassword(String password)
             {
                 try
@@ -445,6 +445,10 @@ public abstract class AuthenticationProv
                 {
                     return getId();
                 }
+                else if(PASSWORD.equals(name))
+                {
+                    return null; // for security reasons we don't expose the password
+                }
                 else if(NAME.equals(name))
                 {
                     return getName();

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java?rev=1376968&r1=1376967&r2=1376968&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java Fri Aug 24 15:33:00 2012
@@ -32,6 +32,7 @@ import org.apache.qpid.common.QpidProper
 import org.apache.qpid.server.model.AuthenticationProvider;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.GroupProvider;
 import org.apache.qpid.server.model.LifetimePolicy;
 import org.apache.qpid.server.model.Port;
 import org.apache.qpid.server.model.Protocol;
@@ -43,12 +44,14 @@ import org.apache.qpid.server.model.Virt
 import org.apache.qpid.server.registry.IApplicationRegistry;
 import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
 import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry;
+import org.apache.qpid.server.security.group.GroupManager;
 import org.apache.qpid.server.transport.QpidAcceptor;
 import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
 
 public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHostRegistry.RegistryChangeListener,
                                                               IApplicationRegistry.PortBindingListener,
-                                                              IAuthenticationManagerRegistry.RegistryChangeListener
+                                                              IAuthenticationManagerRegistry.RegistryChangeListener,
+                                                              IApplicationRegistry.GroupManagerChangeListener
 {
 
 
@@ -62,6 +65,8 @@ public class BrokerAdapter extends Abstr
 
     private final Map<AuthenticationManager, AuthenticationProviderAdapter> _authManagerAdapters =
             new HashMap<AuthenticationManager, AuthenticationProviderAdapter>();
+    private final Map<GroupManager, GroupProviderAdapter> _groupManagerAdapters =
+            new HashMap<GroupManager, GroupProviderAdapter>();
 
 
     public BrokerAdapter(final IApplicationRegistry instance)
@@ -75,8 +80,10 @@ public class BrokerAdapter extends Abstr
         populateVhosts();
         instance.addPortBindingListener(this);
         populatePorts();
-        instance.addRegistryChangeListener(this);
+        instance.addAuthenticationManagerRegistryChangeListener(this);
         populateAuthenticationManagers();
+        instance.addGroupManagerChangeListener(this);
+        populateGroupManagers();
     }
 
     private void populateVhosts()
@@ -171,6 +178,25 @@ public class BrokerAdapter extends Abstr
         }
     }
 
+    private void populateGroupManagers()
+    {
+        synchronized (_groupManagerAdapters)
+        {
+            List<GroupManager> groupManagers = _applicationRegistry.getGroupManagers();
+            if(groupManagers != null)
+            {
+                for (GroupManager groupManager : groupManagers)
+                {
+                    if(!_groupManagerAdapters.containsKey(groupManager))
+                    {
+                        _groupManagerAdapters.put(groupManager,
+                                                 GroupProviderAdapter.createGroupProviderAdapter(this, groupManager));
+                    }
+                }
+            }
+        }
+    }
+
     public Collection<AuthenticationProvider> getAuthenticationProviders()
     {
         synchronized (_authManagerAdapters)
@@ -179,7 +205,16 @@ public class BrokerAdapter extends Abstr
                     new ArrayList<AuthenticationProvider>(_authManagerAdapters.values());
             return authManagers;
         }
+    }
 
+    public Collection<GroupProvider> getGroupProviders()
+    {
+        synchronized (_groupManagerAdapters)
+        {
+            final ArrayList<GroupProvider> groupManagers =
+                    new ArrayList<GroupProvider>(_groupManagerAdapters.values());
+            return groupManagers;
+        }
     }
 
     public VirtualHost createVirtualHost(final String name,
@@ -277,6 +312,10 @@ public class BrokerAdapter extends Abstr
         {
             return (Collection<C>) getAuthenticationProviders();
         }
+        else if(clazz == GroupProvider.class)
+        {
+            return (Collection<C>) getGroupProviders();
+        }
 
         return Collections.emptySet();
     }
@@ -491,4 +530,36 @@ public class BrokerAdapter extends Abstr
     {
         return super.setAttribute(name, expected, desired);    //TODO - Implement.
     }
+
+    @Override
+    public void groupManagerRegistered(GroupManager groupManager)
+    {
+        GroupProviderAdapter adapter = null;
+        synchronized (_groupManagerAdapters)
+        {
+            if(!_groupManagerAdapters.containsKey(groupManager))
+            {
+                adapter = GroupProviderAdapter.createGroupProviderAdapter(this, groupManager);
+                _groupManagerAdapters.put(groupManager, adapter);
+            }
+        }
+        if(adapter != null)
+        {
+            childAdded(adapter);
+        }
+    }
+
+    @Override
+    public void groupManagerUnregistered(GroupManager groupManager)
+    {
+        GroupProviderAdapter adapter;
+        synchronized (_groupManagerAdapters)
+        {
+            adapter = _groupManagerAdapters.remove(groupManager);
+        }
+        if(adapter != null)
+        {
+            childRemoved(adapter);
+        }
+    }
 }



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