| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| * |
| */ |
| |
| package org.apache.qpid.server.security.access.plugins; |
| |
| import org.apache.commons.configuration.Configuration; |
| import org.apache.log4j.Logger; |
| import org.apache.qpid.AMQConnectionException; |
| import org.apache.qpid.framing.AMQMethodBody; |
| import org.apache.qpid.framing.AMQShortString; |
| import org.apache.qpid.framing.BasicConsumeBody; |
| import org.apache.qpid.framing.BasicPublishBody; |
| |
| import org.apache.qpid.protocol.AMQConstant; |
| import org.apache.qpid.server.exchange.Exchange; |
| import org.apache.qpid.server.protocol.AMQProtocolSession; |
| import org.apache.qpid.server.security.access.ACLManager; |
| import org.apache.qpid.server.security.access.ACLPlugin; |
| import org.apache.qpid.server.security.access.AccessResult; |
| import org.apache.qpid.server.security.access.Permission; |
| import org.apache.qpid.server.security.access.PrincipalPermissions; |
| |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| /** |
| * This uses the default |
| */ |
| public class SimpleXML implements ACLPlugin |
| { |
| private Map<String, PrincipalPermissions> _users; |
| private final AccessResult GRANTED = new AccessResult(this, AccessResult.AccessStatus.GRANTED); |
| |
| public SimpleXML() |
| { |
| _users = new ConcurrentHashMap<String, PrincipalPermissions>(); |
| } |
| |
| public void setConfiguaration(Configuration config) |
| { |
| processConfig(config); |
| } |
| |
| private void processConfig(Configuration config) |
| { |
| processPublish(config); |
| |
| processConsume(config); |
| |
| processCreate(config); |
| } |
| |
| /** |
| * Publish format takes |
| * Exchange + Routing Key Pairs |
| * |
| * @param config XML Configuration |
| */ |
| private void processPublish(Configuration config) |
| { |
| Configuration publishConfig = config.subset("security.access_control_list.publish"); |
| |
| //Process users that have full publish permission |
| String[] users = publishConfig.getStringArray("users.user"); |
| |
| for (String user : users) |
| { |
| grant(Permission.PUBLISH, user); |
| } |
| |
| // Process exchange limited users |
| int exchangeCount = 0; |
| Configuration exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")"); |
| |
| while (!exchangeConfig.isEmpty()) |
| { |
| //Get Exchange Name |
| AMQShortString exchangeName = new AMQShortString(exchangeConfig.getString("name")); |
| |
| //Get Routing Keys |
| int keyCount = 0; |
| Configuration routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")"); |
| |
| while (!routingkeyConfig.isEmpty()) |
| { |
| //Get RoutingKey Value |
| AMQShortString routingKeyValue = new AMQShortString(routingkeyConfig.getString("value")); |
| |
| //Apply Exchange + RoutingKey permissions to Users |
| users = routingkeyConfig.getStringArray("users.user"); |
| for (String user : users) |
| { |
| grant(Permission.PUBLISH, user, exchangeName, routingKeyValue); |
| } |
| |
| //Apply permissions to Groups |
| |
| // Check for more configs |
| keyCount++; |
| routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")"); |
| } |
| |
| //Apply Exchange wide permissions to Users |
| users = exchangeConfig.getStringArray("exchange(" + exchangeCount + ").users.user"); |
| |
| for (String user : users) |
| { |
| grant(Permission.PUBLISH, user, exchangeName); |
| } |
| |
| //Apply permissions to Groups |
| exchangeCount++; |
| exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")"); |
| } |
| } |
| |
| private void grant(Permission permission, String user, Object... parameters) |
| { |
| PrincipalPermissions permissions = _users.get(user); |
| |
| if (permissions == null) |
| { |
| permissions = new PrincipalPermissions(user); |
| } |
| |
| _users.put(user, permissions); |
| permissions.grant(permission, parameters); |
| } |
| |
| private void processConsume(Configuration config) |
| { |
| Configuration consumeConfig = config.subset("security.access_control_list.consume"); |
| |
| // Process queue limited users |
| int queueCount = 0; |
| Configuration queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")"); |
| |
| while (!queueConfig.isEmpty()) |
| { |
| //Get queue Name |
| AMQShortString queueName = new AMQShortString(queueConfig.getString("name")); |
| // if there is no name then there may be a temporary element |
| boolean temporary = queueConfig.containsKey("temporary"); |
| boolean ownQueues = queueConfig.containsKey("own_queues"); |
| |
| //Process permissions for this queue |
| String[] users = queueConfig.getStringArray("users.user"); |
| for (String user : users) |
| { |
| grant(Permission.CONSUME, user, queueName, temporary, ownQueues); |
| } |
| |
| //See if we have another config |
| queueCount++; |
| queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")"); |
| } |
| |
| // Process users that have full consume permission |
| String[] users = consumeConfig.getStringArray("users.user"); |
| |
| for (String user : users) |
| { |
| grant(Permission.CONSUME, user); |
| } |
| } |
| |
| private void processCreate(Configuration config) |
| { |
| Configuration createConfig = config.subset("security.access_control_list.create"); |
| |
| // Process create permissions for queue creation |
| int queueCount = 0; |
| Configuration queueConfig = createConfig.subset("queues.queue(" + queueCount + ")"); |
| |
| while (!queueConfig.isEmpty()) |
| { |
| //Get queue Name |
| AMQShortString queueName = new AMQShortString(queueConfig.getString("name")); |
| |
| // if there is no name then there may be a temporary element |
| boolean temporary = queueConfig.containsKey("temporary"); |
| |
| int exchangeCount = 0; |
| Configuration exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); |
| |
| while (!exchangeConfig.isEmpty()) |
| { |
| |
| AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name")); |
| AMQShortString routingKey = new AMQShortString(exchangeConfig.getString("routing_key")); |
| |
| //Process permissions for this queue |
| String[] users = exchangeConfig.getStringArray("users.user"); |
| for (String user : users) |
| { |
| grant(Permission.CREATE, user, temporary, |
| (queueName.equals("") ? null : queueName), |
| (exchange.equals("") ? null : exchange), |
| (routingKey.equals("") ? null : routingKey)); |
| } |
| |
| //See if we have another config |
| exchangeCount++; |
| exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); |
| } |
| |
| // Process users that are not bound to an exchange |
| String[] users = queueConfig.getStringArray("users.user"); |
| |
| for (String user : users) |
| { |
| grant(Permission.CREATE, user, temporary, queueName); |
| } |
| |
| //See if we have another config |
| queueCount++; |
| queueConfig = createConfig.subset("queues.queue(" + queueCount + ")"); |
| } |
| |
| // Process create permissions for exchange creation |
| int exchangeCount = 0; |
| Configuration exchangeConfig = createConfig.subset("exchanges.exchange(" + exchangeCount + ")"); |
| |
| while (!exchangeConfig.isEmpty()) |
| { |
| AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name")); |
| AMQShortString clazz = new AMQShortString(exchangeConfig.getString("class")); |
| |
| //Process permissions for this queue |
| String[] users = exchangeConfig.getStringArray("users.user"); |
| for (String user : users) |
| { |
| grant(Permission.CREATE, user, exchange, clazz); |
| } |
| |
| //See if we have another config |
| exchangeCount++; |
| exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); |
| } |
| |
| // Process users that have full create permission |
| String[] users = createConfig.getStringArray("users.user"); |
| |
| for (String user : users) |
| { |
| grant(Permission.CREATE, user); |
| } |
| |
| |
| } |
| |
| public String getPluginName() |
| { |
| return "Simple"; |
| } |
| |
| public AccessResult authorise(AMQProtocolSession session, Permission permission, AMQMethodBody body, Object... parameters) throws AMQConnectionException |
| { |
| String error = ""; |
| |
| if (ACLManager.getLogger().isInfoEnabled()) |
| { |
| ACLManager.getLogger().info("Simple Authorisation processing user:" + session.getAuthorizedID() + " for :" + permission.toString() |
| + " on " + body.getClass().getSimpleName() |
| + (parameters == null || parameters.length == 0 ? "" : "-" + AllowAll.accessablesToString(parameters))); |
| } |
| |
| String username = session.getAuthorizedID().getName(); |
| |
| //Get the Users Permissions |
| PrincipalPermissions permissions = _users.get(username); |
| |
| if (permissions != null) |
| { |
| switch (permission) |
| { |
| case ACCESS: |
| return GRANTED; |
| case BIND: // Body QueueDeclareBody - Parameters : Exchange, Queue, QueueName |
| // Body QueueBindBody - Paramters : Exchange, Queue, QueueName |
| if (parameters.length == 3) |
| { |
| // Parameters : Exchange, Queue, RoutingKey |
| if (permissions.authorise(Permission.BIND, body, parameters[0], parameters[1], parameters[2])) |
| { |
| return GRANTED; |
| } |
| } |
| break; |
| case CONSUME: // Parameters : none |
| if (parameters.length == 1 && permissions.authorise(Permission.CONSUME, parameters[0])) |
| { |
| return GRANTED; |
| } |
| break; |
| case CREATE: // Body : QueueDeclareBody | ExchangeDeclareBody - Parameters : none |
| if (permissions.authorise(Permission.CREATE, body)) |
| { |
| return GRANTED; |
| } |
| break; |
| case PUBLISH: // Body : BasicPublishBody Parameters : exchange |
| if (parameters.length == 1 && parameters[0] instanceof Exchange) |
| { |
| if (permissions.authorise(Permission.PUBLISH, ((Exchange) parameters[0]).getName(), |
| ((BasicPublishBody) body).getRoutingKey())) |
| { |
| return GRANTED; |
| } |
| } |
| break; |
| case PURGE: |
| break; |
| case DELETE: |
| break; |
| case UNBIND: |
| break; |
| } |
| } |
| |
| //todo potential refactor this ConnectionException Out of here |
| throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, error); |
| } |
| } |