001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.security;
018
019import java.lang.reflect.Constructor;
020import java.lang.reflect.Method;
021import java.util.Collections;
022import java.util.HashSet;
023import java.util.Set;
024import java.util.StringTokenizer;
025
026import org.apache.activemq.filter.DestinationMapEntry;
027
028/**
029 * Represents an entry in a {@link DefaultAuthorizationMap} for assigning
030 * different operations (read, write, admin) of user roles to a specific
031 * destination or a hierarchical wildcard area of destinations.
032 *
033 * @org.apache.xbean.XBean
034 *
035 */
036@SuppressWarnings("rawtypes")
037public class AuthorizationEntry extends DestinationMapEntry {
038
039    private Set<Object> readACLs = emptySet();
040    private Set<Object> writeACLs = emptySet();
041    private Set<Object> adminACLs = emptySet();
042
043    private String adminRoles;
044    private String readRoles;
045    private String writeRoles;
046
047    private String groupClass = "org.apache.activemq.jaas.GroupPrincipal";
048
049    public String getGroupClass() {
050        return groupClass;
051    }
052
053    @SuppressWarnings("unchecked")
054    private Set<Object> emptySet() {
055        return Collections.EMPTY_SET;
056    }
057
058    public void setGroupClass(String groupClass) {
059        this.groupClass = groupClass;
060    }
061
062    public Set<Object> getAdminACLs() {
063        return adminACLs;
064    }
065
066    public void setAdminACLs(Set<Object> adminACLs) {
067        this.adminACLs = adminACLs;
068    }
069
070    public Set<Object> getReadACLs() {
071        return readACLs;
072    }
073
074    public void setReadACLs(Set<Object> readACLs) {
075        this.readACLs = readACLs;
076    }
077
078    public Set<Object> getWriteACLs() {
079        return writeACLs;
080    }
081
082    public void setWriteACLs(Set<Object> writeACLs) {
083        this.writeACLs = writeACLs;
084    }
085
086    // helper methods for easier configuration in Spring
087    // ACLs are already set in the afterPropertiesSet method to ensure that
088    // groupClass is set first before
089    // calling parceACLs() on any of the roles. We still need to add the call to
090    // parceACLs inside the helper
091    // methods for instances where we configure security programatically without
092    // using xbean
093    // -------------------------------------------------------------------------
094    public void setAdmin(String roles) throws Exception {
095        adminRoles = roles;
096        setAdminACLs(parseACLs(adminRoles));
097    }
098
099    public void setRead(String roles) throws Exception {
100        readRoles = roles;
101        setReadACLs(parseACLs(readRoles));
102    }
103
104    public void setWrite(String roles) throws Exception {
105        writeRoles = roles;
106        setWriteACLs(parseACLs(writeRoles));
107    }
108
109    protected Set<Object> parseACLs(String roles) throws Exception {
110        Set<Object> answer = new HashSet<Object>();
111        StringTokenizer iter = new StringTokenizer(roles, ",");
112        while (iter.hasMoreTokens()) {
113
114            String name = iter.nextToken().trim();
115            Object[] param = new Object[]{name};
116
117            try {
118                Class<?> cls = Class.forName(groupClass);
119
120                Constructor<?>[] constructors = cls.getConstructors();
121                int i;
122                for (i = 0; i < constructors.length; i++) {
123                    Class<?>[] paramTypes = constructors[i].getParameterTypes();
124                    if (paramTypes.length != 0 && paramTypes[0].equals(String.class)) {
125                        break;
126                    }
127                }
128                if (i < constructors.length) {
129                    Object instance = constructors[i].newInstance(param);
130                    answer.add(instance);
131                } else {
132                    Object instance = cls.newInstance();
133                    Method[] methods = cls.getMethods();
134                    i = 0;
135                    for (i = 0; i < methods.length; i++) {
136                        Class<?>[] paramTypes = methods[i].getParameterTypes();
137                        if (paramTypes.length != 0 && methods[i].getName().equals("setName") && paramTypes[0].equals(String.class)) {
138                            break;
139                        }
140                    }
141
142                    if (i < methods.length) {
143                        methods[i].invoke(instance, param);
144                        answer.add(instance);
145                    } else {
146                        throw new NoSuchMethodException();
147                    }
148                }
149            } catch (Exception e) {
150                throw e;
151            }
152        }
153        return answer;
154    }
155
156    public void afterPropertiesSet() throws Exception {
157        super.afterPropertiesSet();
158
159        if (adminRoles != null) {
160            setAdminACLs(parseACLs(adminRoles));
161        }
162
163        if (writeRoles != null) {
164            setWriteACLs(parseACLs(writeRoles));
165        }
166
167        if (readRoles != null) {
168            setReadACLs(parseACLs(readRoles));
169        }
170
171    }
172}