[Carbon-commits] [Carbon] svn commit r116059 - in branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3: . src src/main src/main/java src/main/java/org src/main/java/org/wso2 src/main/java/org/wso2/carbon src/main/java/org/wso2/carbon/qpid src/main/java/org/wso2/carbon/qpid/authorization src/main/java/org/wso2/carbon/qpid/authorization/internal src/main/java/org/wso2/carbon/qpid/authorization/qpid src/main/java/org/wso2/carbon/qpid/authorization/service src/main/java/org/wso2/carbon/qpid/authorization/service/qpid

shammi at wso2.com shammi at wso2.com
Wed Nov 23 07:07:40 EST 2011


Author: shammi
Date: Wed Nov 23 04:07:39 2011
New Revision: 116059
URL: http://wso2.org/svn/browse/wso2?view=rev&revision=116059

Log:
Adding fix for the issue https://wso2.org/jira/browse/CARBON-11579

Added:
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/pom.xml
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/internal/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/internal/AuthorizationServiceComponent.java
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/internal/AuthorizationServiceDataHolder.java
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/qpid/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/qpid/QpidAuthorizationHandler.java
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/qpid/QpidAuthorizationHandlerException.java
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/qpid/
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/qpid/QpidAuthorizationPlugin.java
   branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/qpid/QpidAuthorizationPluginConfiguration.java

Added: branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/pom.xml
URL: http://wso2.org/svn/browse/wso2/branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/pom.xml?pathrev=116059
==============================================================================
--- (empty file)
+++ branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/pom.xml	Wed Nov 23 04:07:39 2011
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (c) 2009-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ ~
+ ~ Licensed 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <parent>
+        <groupId>org.wso2.carbon</groupId>
+        <artifactId>qpid</artifactId>
+        <version>3.2.0</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>org.wso2.carbon.qpid.authorization</artifactId>
+    <version>3.2.3</version>
+    <packaging>bundle</packaging>
+    <name>WSO2 Carbon - Component - Qpid - Authorization Manager</name>
+    <description>Qpid authorization manager based on Carbon authorization manager</description>
+    <url>http://wso2.org</url>
+
+    <dependencies>
+  	    <dependency>
+            <groupId>org.wso2.carbon</groupId>
+            <artifactId>org.wso2.carbon.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.qpid.wso2</groupId>
+            <artifactId>qpid</artifactId>
+    	</dependency>
+        <dependency>
+            <groupId>org.wso2.carbon</groupId>
+            <artifactId>org.wso2.carbon.qpid.commons</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.wso2.carbon</groupId>
+            <artifactId>org.wso2.carbon.qpid.authentication</artifactId>
+        </dependency>
+		<dependency>
+			<groupId>commons-configuration.wso2</groupId>
+			<artifactId>commons-configuration</artifactId>
+		</dependency>
+    </dependencies>
+
+    <build>
+  	    <plugins>
+	        <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+	        <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>1.4.0</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+                        <Bundle-Name>${pom.artifactId}</Bundle-Name>
+                        <Private-Package>
+                            org.wso2.carbon.qpid.authorization.internal
+                        </Private-Package>
+                        <Export-Package>
+                            !org.wso2.carbon.qpid.authorization.internal,
+                            org.wso2.carbon.qpid.authorization.*
+                        </Export-Package>
+                        <Import-Package>
+			                org.apache.qpid.*,
+                            org.wso2.carbon.qpid.commons.registry,
+                            org.wso2.carbon.qpid.authentication.service,
+                            *;resolution:=optional
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    
+</project>
+

Added: branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/internal/AuthorizationServiceComponent.java
URL: http://wso2.org/svn/browse/wso2/branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/internal/AuthorizationServiceComponent.java?pathrev=116059
==============================================================================
--- (empty file)
+++ branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/internal/AuthorizationServiceComponent.java	Wed Nov 23 04:07:39 2011
@@ -0,0 +1,94 @@
+/*
+ *  Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ *  Licensed 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.wso2.carbon.qpid.authorization.internal;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.Log;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.SecurityPluginFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.wso2.carbon.qpid.authorization.service.qpid.QpidAuthorizationPlugin;
+import org.wso2.carbon.qpid.authorization.service.qpid.QpidAuthorizationPluginConfiguration;
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.user.core.service.RealmService;
+
+/**
+ * @scr.component  name="org.wso2.carbon.qpid.authorization.internal.AuthorizationServiceComponent"
+ *                              immediate="true"
+ * @scr.reference    name="registry.service"
+ *                              interface="org.wso2.carbon.registry.core.service.RegistryService"
+ *                              cardinality="1..1"
+ *                              policy="dynamic"
+ *                              bind="setRegistryService"
+ *                              unbind="unsetRegistryService"
+ * @scr.reference    name="realm.service"
+ *                              interface="org.wso2.carbon.user.core.service.RealmService"
+ *                              cardinality="1..1"
+ *                              policy="dynamic"
+ *                              bind="setRealmService"
+ *                              unbind="unsetRealmService"
+ */
+public class AuthorizationServiceComponent {
+
+    private static final Log log = LogFactory.getLog(AuthorizationServiceComponent.class);
+    private ServiceRegistration securityPluginFactory = null;
+    private ServiceRegistration configurationPluginFactory = null;
+
+    protected void activate(ComponentContext ctx) {
+        try {
+            // Register security plugin factory
+            securityPluginFactory = ctx.getBundleContext().registerService(
+                    SecurityPluginFactory.class.getName(), QpidAuthorizationPlugin.FACTORY, null);
+
+            // Register security configuration plugin factory
+            configurationPluginFactory = ctx.getBundleContext().registerService(
+                    ConfigurationPluginFactory.class.getName(),
+                    QpidAuthorizationPluginConfiguration.FACTORY, null);
+        } catch (Throwable e) {
+            log.error("Failed to activate org.wso2.carbon.qpid.authorization.internal." +
+                      "AuthorizationServiceComponent : " + e);
+        }
+    }
+
+    protected void deactivate(ComponentContext ctx) {
+        // Unregister OSGi services that were registered at the time of activation
+        if (null != securityPluginFactory) {
+            securityPluginFactory.unregister();
+        }
+
+        if (null != configurationPluginFactory) {
+            configurationPluginFactory.unregister();
+        }
+    }
+
+    protected void setRegistryService(RegistryService registryService) {
+        AuthorizationServiceDataHolder.getInstance().setRegistryService(registryService);
+    }
+
+    protected void unsetRegistryService(RegistryService registryService) {
+        AuthorizationServiceDataHolder.getInstance().setRegistryService(null);
+    }
+
+    protected void setRealmService(RealmService realmService) {
+        AuthorizationServiceDataHolder.getInstance().setRealmService(realmService);
+    }
+
+    protected void unsetRealmService(RealmService realmService) {
+        AuthorizationServiceDataHolder.getInstance().setRealmService(null);
+    }
+}

Added: branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/internal/AuthorizationServiceDataHolder.java
URL: http://wso2.org/svn/browse/wso2/branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/internal/AuthorizationServiceDataHolder.java?pathrev=116059
==============================================================================
--- (empty file)
+++ branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/internal/AuthorizationServiceDataHolder.java	Wed Nov 23 04:07:39 2011
@@ -0,0 +1,78 @@
+/*
+ *  Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ *  Licensed 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.wso2.carbon.qpid.authorization.internal;
+
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.user.core.service.RealmService;
+
+/**
+ * This singleton class holds common properties shared inside the authorization bundle.
+ */
+public class AuthorizationServiceDataHolder {
+
+    private static AuthorizationServiceDataHolder instance = new AuthorizationServiceDataHolder();
+
+    private RegistryService registryService = null;
+    private RealmService realmService = null;
+
+    private AuthorizationServiceDataHolder() {
+    }
+
+    public static AuthorizationServiceDataHolder getInstance() {
+        return instance;
+    }
+
+    /**
+        * Set RegistryService instance received when the bundle starts up
+        *
+        * @param registryService
+        *               RegistryService instance
+        */
+    public void setRegistryService(RegistryService registryService) {
+        this.registryService = registryService;
+    }
+
+    /**
+        * Get stored RegistryService instance
+        *
+        * @return
+        *               RegistryService instance 
+        */
+    public RegistryService getRegistryService() {
+        return registryService;
+    }
+
+    /**
+        * Get stored RealmService instance
+        *
+        * @return
+        *               RealmService instance 
+        */
+    public RealmService getRealmService() {
+        return realmService;
+    }
+
+    /**
+        * Set RealmService instance
+        *
+        * @param realmService
+        *               RealmService instance 
+        */
+    public void setRealmService(RealmService realmService) {
+        this.realmService = realmService;
+    }
+}

Added: branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/qpid/QpidAuthorizationHandler.java
URL: http://wso2.org/svn/browse/wso2/branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/qpid/QpidAuthorizationHandler.java?pathrev=116059
==============================================================================
--- (empty file)
+++ branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/qpid/QpidAuthorizationHandler.java	Wed Nov 23 04:07:39 2011
@@ -0,0 +1,399 @@
+/*
+ *  Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ *  Licensed 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.wso2.carbon.qpid.authorization.qpid;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.server.security.Result;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.wso2.carbon.context.CarbonContext;
+import org.wso2.carbon.qpid.authorization.internal.AuthorizationServiceDataHolder;
+import org.wso2.carbon.qpid.commons.CommonsUtil;
+import org.wso2.carbon.qpid.commons.registry.RegistryClient;
+import org.wso2.carbon.qpid.commons.registry.RegistryClientException;
+import org.wso2.carbon.user.api.UserRealm;
+import org.wso2.carbon.user.api.UserStoreException;
+import org.wso2.carbon.user.core.authorization.TreeNode;
+import org.wso2.carbon.user.core.service.RealmService;
+
+/**
+ * This class includes the actual access control logic
+ */
+public class QpidAuthorizationHandler {
+
+    private static final Log log = LogFactory.getLog(QpidAuthorizationHandler.class);
+
+    private static final String DEFAULT_EXCHANGE = "default";
+    private static final String DIRECT_EXCHANGE = "amq.direct";
+    private static final String TOPIC_EXCHANGE = "amq.topic";
+    private static final String PERMISSION_CHANGE_PERMISSION = "changePermission";
+    private static final String ADMIN_ROLE = "admin";
+    private static final String AT_REPLACE_CHAR="_";
+
+    /**
+        * Handle creating queue
+        *
+        * @param username
+        *              User who is trying to create the queue
+        * @param userRealm
+        *             User's Realm  
+        * @param properties
+        *              NAME, OWNER, DURABLE
+        * @return
+        *              ALLOWED/DENIED
+        * @throws QpidAuthorizationHandlerException
+        */
+    public static Result handleCreateQueue(String username, UserRealm userRealm, ObjectProperties properties)
+            throws QpidAuthorizationHandlerException {
+        try {
+            if (null != userRealm) {
+                String queueName =
+                        getRawQueueName(properties.get(ObjectProperties.Property.NAME));
+
+                //For registry we use a modified queue name
+                String newQname = queueName.replace("@",AT_REPLACE_CHAR);
+                // Store queue details
+                RegistryClient.createQueue(newQname, username);
+
+                String queueID = CommonsUtil.getQueueID(queueName);
+
+                userRealm.getAuthorizationManager().authorizeUser(
+                        username, queueID, TreeNode.Permission.CONSUME.toString().toLowerCase());
+                userRealm.getAuthorizationManager().authorizeUser(
+                        username, queueID, TreeNode.Permission.PUBLISH.toString().toLowerCase());
+                userRealm.getAuthorizationManager().authorizeUser(
+                        username, queueID, PERMISSION_CHANGE_PERMISSION);
+
+                return Result.ALLOWED;
+            }
+        } catch (RegistryClientException e) {
+            throw new QpidAuthorizationHandlerException(e);
+        } catch (UserStoreException e) {
+            throw new QpidAuthorizationHandlerException(e);
+        }
+
+        return Result.DENIED;
+    }
+
+    /**
+        * Handle consuming queue
+        *
+        * IMPORTANT : Consuming an AMQP queue is not as same as consuming a JMS queue. The former is an atomic
+        * operation that is allowed for the user who created the queue where as the latter is the binding to an exchange
+        * based on permission granted.  
+        *
+        * @param username
+        *              User who is trying to consume the queue
+        * @param userRealm
+        *             User's Realm
+        * @param properties
+        *              NAME, OWNER, TEMPORARY
+        * @return
+        *              ALLOWED/DENIED
+        * @throws QpidAuthorizationHandlerException 
+        */
+    public static Result handleConsumeQueue(String username, UserRealm userRealm, ObjectProperties properties)
+            throws QpidAuthorizationHandlerException {
+        try {
+            if (null != userRealm) {
+                // Queue properties
+                String queueName = getRawQueueName(properties.get(ObjectProperties.Property.NAME));
+
+                String queueID = CommonsUtil.getQueueID(queueName);
+
+                if (isAdminUser(username, userRealm)) {
+                    return Result.ALLOWED;
+                } else if (userRealm.getAuthorizationManager().isUserAuthorized(
+                        username, queueID, TreeNode.Permission.CONSUME.toString().toLowerCase())) {
+                    return Result.ALLOWED;
+                }
+            }
+        } catch (UserStoreException e) {
+            throw new QpidAuthorizationHandlerException(e);
+        }
+
+        return Result.DENIED;
+    }
+
+    /**
+         * Authorize binding a queue to an exchange
+         *
+         * @param username
+         *              User who is trying to do the binding
+         * @param userRealm
+         *             User's Realm   
+         * @param properties
+         *              NAME, ROUTING_KEY
+         * @return
+         *              ALLOWED/DENIED
+         * @throws QpidAuthorizationHandlerException 
+         */
+    public static Result handleBindQueue(String username, UserRealm userRealm, ObjectProperties properties)
+            throws QpidAuthorizationHandlerException {
+        try {
+            if (null != userRealm) {
+                // Bind properties
+                String exchangeName =
+                        getRawExchangeName(properties.get(ObjectProperties.Property.NAME));
+                String queueName =
+                        getRawQueueName(properties.get(ObjectProperties.Property.QUEUE_NAME));
+                String routingKey =
+                        getRawRoutingKey(properties.get(ObjectProperties.Property.ROUTING_KEY));
+                
+                if (DEFAULT_EXCHANGE.equals(exchangeName)) {
+                    String queueID = CommonsUtil.getQueueID(queueName);
+
+                    // Authorize
+                    if (isAdminUser(username, userRealm)) {
+                        return Result.ALLOWED;
+                    } else if (userRealm.getAuthorizationManager().isUserAuthorized(
+                            username, queueID,
+                            TreeNode.Permission.CONSUME.toString().toLowerCase())) {
+                        return Result.ALLOWED;
+                    }
+                } else if (DIRECT_EXCHANGE.equals(exchangeName)) {
+                    String queueID = CommonsUtil.getQueueID(queueName);
+
+                    // Authorize
+                    if (isAdminUser(username, userRealm)) {
+                        return Result.ALLOWED;
+                    } else if (userRealm.getAuthorizationManager().isUserAuthorized(
+                            username, queueID,
+                            TreeNode.Permission.CONSUME.toString().toLowerCase())) {
+                        return Result.ALLOWED;
+                    }
+                } else if (TOPIC_EXCHANGE.equals(exchangeName)) {
+
+                    if (CarbonContext.getCurrentContext().getTenantId() > 0) {
+                        // then we need to remove the domain name path from the topic name before saving to the registry
+                        String tenantDomain = CarbonContext.getCurrentContext().getTenantDomain();
+                        routingKey = routingKey.substring(tenantDomain.length() + 1);
+                    }
+                    String topicID = CommonsUtil.getTopicID(routingKey);
+
+                    // Authorize
+                    String newRoutingKey = routingKey.replace("@", AT_REPLACE_CHAR);
+                    String newQName = queueName.replace("@", AT_REPLACE_CHAR);
+                    if (isAdminUser(username, userRealm)) {
+
+                        // Store subscription
+
+
+                        RegistryClient.createSubscription(newRoutingKey, newQName, username);
+                        
+                        return Result.ALLOWED;
+                    } else if (userRealm.getAuthorizationManager().isUserAuthorized(
+                            username, topicID,
+                            TreeNode.Permission.SUBSCRIBE.toString().toLowerCase())) {
+                        // Store subscription
+
+                        RegistryClient.createSubscription(newRoutingKey,newQName, username);
+
+                        return Result.ALLOWED;
+                    }
+                }
+            }
+        } catch (UserStoreException e) {
+            throw new QpidAuthorizationHandlerException(e);
+        } catch (RegistryClientException e) {
+            throw new QpidAuthorizationHandlerException(e);
+        }
+
+        return Result.DENIED;
+    }
+
+    /**
+        * Authorise publishing to a given exchange
+        *
+        * @param username
+        *              User who is trying to publish
+        * @param userRealm
+        *             User's Realm
+        * @param properties
+        *              NAME, ROUTING_KEY
+        * @return
+        *              ALLOWED, DENIED
+        * @throws QpidAuthorizationHandlerException
+        */
+    public static Result handlePublishToExchange(String username, UserRealm userRealm, ObjectProperties properties)
+            throws QpidAuthorizationHandlerException {
+        try {
+            if (null != userRealm) {
+                // Exchange properties
+                String exchangeName = getRawExchangeName(properties.get(ObjectProperties.Property.NAME));
+                String routingKey = getRawRoutingKey(properties.get(ObjectProperties.Property.ROUTING_KEY));
+
+                if (DIRECT_EXCHANGE.equals(exchangeName)) {
+                    // Publish to queue
+                    String queueID = CommonsUtil.getQueueID(routingKey);
+
+                    // Authorize
+                    if (isAdminUser(username, userRealm)) {
+                        return Result.ALLOWED;
+                    } else if (userRealm.getAuthorizationManager().isUserAuthorized(
+                            username, queueID,
+                            TreeNode.Permission.PUBLISH.toString().toLowerCase())) {
+                        return Result.ALLOWED;
+                    }
+                } else if (TOPIC_EXCHANGE.equals(exchangeName)) {
+                    // Publish to topic
+                    if (CarbonContext.getCurrentContext().getTenantId() > 0) {
+                        // then we need to remove the domain name path from the topic name before saving to the registry
+                        String tenantDomain = CarbonContext.getCurrentContext().getTenantDomain();
+                        routingKey = routingKey.substring(tenantDomain.length() + 1);
+                    }
+                    String permissionID = CommonsUtil.getTopicID(routingKey);
+
+                    // Authorize
+                    if (isAdminUser(username, userRealm)) {
+                        return Result.ALLOWED;
+                    } else if (userRealm.getAuthorizationManager().isUserAuthorized(
+                            username, permissionID,
+                            TreeNode.Permission.PUBLISH.toString().toLowerCase())) {
+                        return Result.ALLOWED;
+                    }
+                } else if (DEFAULT_EXCHANGE.equals(exchangeName)) {
+                    // Publish to queue
+                    String queueID = CommonsUtil.getQueueID(routingKey);
+
+                    // Authorize
+                    if (isAdminUser(username, userRealm)) {
+                        return Result.ALLOWED;
+                    } else if (userRealm.getAuthorizationManager().isUserAuthorized(
+                            username, queueID,
+                            TreeNode.Permission.PUBLISH.toString().toLowerCase())) {
+                        return Result.ALLOWED;
+                    }
+                }
+            }
+        } catch (UserStoreException e) {
+            throw new QpidAuthorizationHandlerException(e);
+        }
+
+        return Result.DENIED;
+    }
+
+    public static Result handleUnbindQueue(ObjectProperties properties)
+            throws QpidAuthorizationHandlerException {
+        try {
+            // Bind properties
+            String exchangeName =
+                    getRawExchangeName(properties.get(ObjectProperties.Property.NAME));
+            String queueName =
+                    getRawQueueName(properties.get(ObjectProperties.Property.QUEUE_NAME));
+            String routingKey =
+                    getRawRoutingKey(properties.get(ObjectProperties.Property.ROUTING_KEY));
+
+
+            String newRoutingKey = routingKey.replace("@", AT_REPLACE_CHAR);
+            String newQName = queueName.replace("@", AT_REPLACE_CHAR);
+            if (TOPIC_EXCHANGE.equals(exchangeName)) {
+                // Delete subscription details
+                RegistryClient.deleteSubscription(routingKey, queueName);
+            }
+
+            return Result.ALLOWED;
+        } catch (RegistryClientException e) {
+            throw new QpidAuthorizationHandlerException(e);
+        }
+    }
+
+    /**
+        * Handle deleting queue
+        *
+        * @param properties
+        *              NAME, OWNER, DURABLE
+        * @return
+        *              ALLOWED/DENIED
+        * @throws QpidAuthorizationHandlerException
+        */
+    public static Result handleDeleteQueue(ObjectProperties properties)
+            throws QpidAuthorizationHandlerException {
+        try {
+            String queueName =
+                getRawQueueName(properties.get(ObjectProperties.Property.NAME));
+
+            // Delete queue details
+
+            String newQName = queueName.replace("@", AT_REPLACE_CHAR);
+            RegistryClient.deleteQueue(queueName);
+
+            return Result.ALLOWED;
+        } catch (RegistryClientException e) {
+            throw new QpidAuthorizationHandlerException(e);
+        }
+    }
+
+    /**
+         * Internally durable queue names have the format [client id]:[raw queue name]. This method
+         * extracts raw name from it's internal name..
+         *
+         * @param queueName
+         *          Internal queue name
+         * @return
+         *          Raw queue name
+         */
+    private static String getRawQueueName(String queueName) {
+        if (queueName.indexOf(";") > -1){
+            queueName = queueName.substring(0, queueName.indexOf(";"));
+        }
+        return queueName.substring(queueName.indexOf(":") + 1, queueName.length());
+    }
+
+    /**
+         * Internally durable queue routing keys have the format [client id]:[raw routing key]. This method
+         * extracts raw name from it's internal name..
+         *
+         * @param routingKey
+         *          Internal routing key
+         * @return
+         *          Raw routing key
+         */
+    private static String getRawRoutingKey(String routingKey) {
+        return routingKey.substring(routingKey.indexOf(":") + 1, routingKey.length());
+    }
+
+    /**
+        * Internally default exchange has the name <<default>> that can not be used as Registry node. This method
+        * trims off leading and trailing > and < characters and returns "default"
+        *
+        * @param exchangeName
+        *               <<default>> for the default exchange
+        * @return
+        *               default for <<default>>
+        */
+    private static String getRawExchangeName(String exchangeName) {
+        return exchangeName.equals("<<default>>") ? DEFAULT_EXCHANGE : exchangeName;
+    }
+
+    private static boolean isAdminUser(String username, UserRealm userRealm) {
+        try {
+            String[] userRoles = userRealm.getUserStoreManager().getRoleListOfUser(username);
+
+            for (String userRole:userRoles) {
+                if (ADMIN_ROLE.equals(userRole)) {
+                    return true;
+                }
+            }
+        } catch (UserStoreException e) {
+            // do nothing
+        }
+
+        return false;
+    }
+}
+

Added: branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/qpid/QpidAuthorizationHandlerException.java
URL: http://wso2.org/svn/browse/wso2/branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/qpid/QpidAuthorizationHandlerException.java?pathrev=116059
==============================================================================
--- (empty file)
+++ branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/qpid/QpidAuthorizationHandlerException.java	Wed Nov 23 04:07:39 2011
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ *  Licensed 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.wso2.carbon.qpid.authorization.qpid;
+
+public class QpidAuthorizationHandlerException extends Exception {
+
+    public QpidAuthorizationHandlerException() {
+        super();
+    }
+
+    public QpidAuthorizationHandlerException(Throwable cause) {
+        super(cause);
+    }
+
+    public QpidAuthorizationHandlerException(String message) {
+        super(message);
+    }
+
+    public QpidAuthorizationHandlerException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Added: branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/qpid/QpidAuthorizationPlugin.java
URL: http://wso2.org/svn/browse/wso2/branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/qpid/QpidAuthorizationPlugin.java?pathrev=116059
==============================================================================
--- (empty file)
+++ branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/qpid/QpidAuthorizationPlugin.java	Wed Nov 23 04:07:39 2011
@@ -0,0 +1,209 @@
+/*
+ *  Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ *  Licensed 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.wso2.carbon.qpid.authorization.service.qpid;
+
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.security.AbstractPlugin;
+import org.apache.qpid.server.security.Result;
+import org.apache.qpid.server.security.SecurityPluginFactory;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.log4j.Logger;
+import org.wso2.carbon.qpid.authorization.internal.AuthorizationServiceDataHolder;
+import org.wso2.carbon.qpid.authorization.qpid.QpidAuthorizationHandler;
+import org.wso2.carbon.qpid.authorization.qpid.QpidAuthorizationHandlerException;
+import org.wso2.carbon.qpid.commons.registry.RegistryClient;
+import org.wso2.carbon.registry.core.exceptions.RegistryException;
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.registry.core.session.UserRegistry;
+import org.wso2.carbon.user.api.UserRealm;
+import java.security.Principal;
+import org.apache.commons.configuration.ConfigurationException;
+import org.wso2.carbon.user.api.UserStoreException;
+import org.wso2.carbon.CarbonConstants;
+import org.wso2.carbon.core.multitenancy.SuperTenantCarbonContext;
+import org.wso2.carbon.context.CarbonContext;
+import org.wso2.carbon.user.core.service.RealmService;
+
+/**
+ * Qpid access control class based on Carbon Authorization Manager
+ */
+public class QpidAuthorizationPlugin extends AbstractPlugin {
+
+    private static final Logger logger = Logger.getLogger(QpidAuthorizationPlugin.class);
+
+    private static final String DOMAIN_NAME_SEPARATOR = "!";
+
+    /**
+        * Factory method for QpidAuthorizationPlugin
+        */
+    public static final SecurityPluginFactory<QpidAuthorizationPlugin>
+            FACTORY = new SecurityPluginFactory<QpidAuthorizationPlugin>()
+    {
+        public QpidAuthorizationPlugin newInstance(ConfigurationPlugin config)
+                throws ConfigurationException {
+            QpidAuthorizationPlugin plugin = new QpidAuthorizationPlugin();
+            return plugin;
+        }
+        
+        public String getPluginName() {
+            return QpidAuthorizationPlugin.class.getName();
+        }
+
+        public Class<QpidAuthorizationPlugin> getPluginClass() {
+            return QpidAuthorizationPlugin.class;
+        }
+    };
+
+    /**
+        * Authorize access to broker
+        *
+        * @param objectType
+        *               We only control access to virtual host 
+        * @param instance
+        * @return
+        *               Authorization result
+        */
+    public Result access(ObjectType objectType, Object instance) {
+        try {
+            Principal principal = SecurityManager.getThreadPrincipal();
+            if (principal == null) { // No user associated with the thread
+                return getDefault();
+            }
+
+            // Allow access to virtual host for all logged in users. Authorization happens only if a user is authenticated.
+            // So, at this point, the user is logged in.
+            if (objectType == ObjectType.VIRTUALHOST) {
+                return Result.ALLOWED;
+            }
+        } catch (Exception e) {
+            // Do nothing
+        }
+
+        return Result.DENIED;
+    }
+
+    /**
+        * Authorize operations inside broker
+        * 
+        * @param operation
+        *               Operation on broker object (CONSUME, PUBLISH, etc)
+        * @param objectType
+        *               Type of object (EXCHANGE, QUEUE, etc)
+        * @param properties
+        *               Properties attached to the operation 
+        * @return
+        *               ALLOWED/DENIED 
+        */
+    public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
+    {
+        try {
+
+            // Get username from tenant username
+            SuperTenantCarbonContext.startTenantFlow();
+            switch (operation) { // These operations do not need users associated with them
+                case UNBIND:
+                    return QpidAuthorizationHandler.handleUnbindQueue(properties);
+                case DELETE:
+                    if (ObjectType.EXCHANGE == objectType) {
+                        return Result.ALLOWED;
+                    } else if (ObjectType.QUEUE == objectType) {
+                        return QpidAuthorizationHandler.handleDeleteQueue(properties);
+                    }
+            }
+
+            Principal principal = SecurityManager.getThreadPrincipal();
+            if (principal == null) { // No user associated with the thread
+                return getDefault();
+            }
+
+            String username = principal.getName();
+
+            // Get User Realm
+            UserRealm userRealm = getUserRealm(username);
+
+            if (username.indexOf(DOMAIN_NAME_SEPARATOR) > -1){
+                String tenantDomain = username.substring(username.indexOf(DOMAIN_NAME_SEPARATOR) + 1);
+                SuperTenantCarbonContext.getCurrentContext().setTenantDomain(tenantDomain);
+                SuperTenantCarbonContext.getCurrentContext().getTenantId(true);
+            } else {
+                SuperTenantCarbonContext.getCurrentContext().setTenantId(0);
+            }
+
+            int domainNameSeparatorIndex = username.indexOf(DOMAIN_NAME_SEPARATOR);
+            if (-1 != domainNameSeparatorIndex) {
+                username = username.substring(0, domainNameSeparatorIndex);
+            }
+            switch (operation) {
+                case CREATE:
+                    if (ObjectType.EXCHANGE == objectType) {
+                        return Result.ALLOWED;
+                    } else if (ObjectType.QUEUE == objectType) {
+                        return QpidAuthorizationHandler.handleCreateQueue(
+                                username, userRealm, properties);
+                    }
+                case BIND:
+                    return QpidAuthorizationHandler.handleBindQueue(
+                            username, userRealm, properties);
+                case PUBLISH:
+                    return QpidAuthorizationHandler.handlePublishToExchange(
+                            username, userRealm, properties);
+                case CONSUME:
+                    return QpidAuthorizationHandler.handleConsumeQueue(
+                            username, userRealm, properties);
+            }
+        } catch (Exception e) {
+            logger.error("Error while invoking QpidAuthorizationHandler", e);
+        } finally {
+            SuperTenantCarbonContext.endTenantFlow();
+        }
+        
+        return Result.DENIED;
+    }
+
+    private String getRawQueueName(String queueName) {
+        return queueName.substring(queueName.indexOf(":") + 1, queueName.length());
+    }
+
+    private static UserRealm getUserRealm(String username) {
+        UserRealm userRealm = null;
+
+        RealmService realmService = AuthorizationServiceDataHolder.getInstance().getRealmService();
+        if (null != realmService) {
+            try {
+                // Get tenant ID
+                int tenantID = 0;
+                int domainNameSeparatorIndex = username.indexOf(DOMAIN_NAME_SEPARATOR);
+                if (-1 != domainNameSeparatorIndex) { // Service case
+                    String domainName = username.substring(domainNameSeparatorIndex + 1);
+                    tenantID = realmService.getTenantManager().getTenantId(domainName);
+                }
+
+                // Get Realm
+                userRealm = realmService.getTenantUserRealm(tenantID);
+            } catch (UserStoreException e) {
+                logger.warn("Error while getting tenant user realm for user " + username);
+            } catch (NullPointerException e) {
+                logger.error("Error while accessing the realm service : " + e.getMessage());
+            }
+        }
+
+        return userRealm;
+    }
+}

Added: branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/qpid/QpidAuthorizationPluginConfiguration.java
URL: http://wso2.org/svn/browse/wso2/branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/qpid/QpidAuthorizationPluginConfiguration.java?pathrev=116059
==============================================================================
--- (empty file)
+++ branches/carbon/3.2.0/components/qpid/org.wso2.carbon.qpid.authorization/3.2.3/src/main/java/org/wso2/carbon/qpid/authorization/service/qpid/QpidAuthorizationPluginConfiguration.java	Wed Nov 23 04:07:39 2011
@@ -0,0 +1,53 @@
+/*
+ *  Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ *  Licensed 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.wso2.carbon.qpid.authorization.service.qpid;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This is the configuration class for QpidAuthorizationPlugin that is based on Qpid plugin configuration model.
+ * This is not actually used as QpidAuthorizationPlugin loads configuration off Carbon Registry.
+ */
+public class QpidAuthorizationPluginConfiguration extends ConfigurationPlugin {
+
+    /**
+        * Factory method for QpidAuthorizationPluginConfiguration
+        */
+    public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
+    {
+        public ConfigurationPlugin newInstance(String path, Configuration config)
+                throws ConfigurationException
+        {
+            ConfigurationPlugin instance = new QpidAuthorizationPluginConfiguration();
+            return instance;
+        }
+
+        public List<String> getParentPaths()
+        {
+            return Arrays.asList("");
+        }
+    };
+
+    public String[] getElementsProcessed() {
+        return new String[]{""};
+    }
+}


More information about the Carbon-commits mailing list