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 */
036public class AuthorizationEntry extends DestinationMapEntry {
037
038    private Set<Object> readACLs = emptySet();
039    private Set<Object> writeACLs = emptySet();
040    private Set<Object> adminACLs = emptySet();
041
042    private String adminRoles;
043    private String readRoles;
044    private String writeRoles;
045
046    private String groupClass = "org.apache.activemq.jaas.GroupPrincipal";
047
048    public String getGroupClass() {
049        return groupClass;
050    }
051
052    @SuppressWarnings("unchecked")
053    private Set<Object> emptySet() {
054        return Collections.EMPTY_SET;
055    }
056
057    public void setGroupClass(String groupClass) {
058        this.groupClass = groupClass;
059    }
060
061    public Set<Object> getAdminACLs() {
062        return adminACLs;
063    }
064
065    public void setAdminACLs(Set<Object> adminACLs) {
066        this.adminACLs = adminACLs;
067    }
068
069    public Set<Object> getReadACLs() {
070        return readACLs;
071    }
072
073    public void setReadACLs(Set<Object> readACLs) {
074        this.readACLs = readACLs;
075    }
076
077    public Set<Object> getWriteACLs() {
078        return writeACLs;
079    }
080
081    public void setWriteACLs(Set<Object> writeACLs) {
082        this.writeACLs = writeACLs;
083    }
084
085    // helper methods for easier configuration in Spring
086    // ACLs are already set in the afterPropertiesSet method to ensure that
087    // groupClass is set first before
088    // calling parceACLs() on any of the roles. We still need to add the call to
089    // parceACLs inside the helper
090    // methods for instances where we configure security programatically without
091    // using xbean
092    // -------------------------------------------------------------------------
093    public void setAdmin(String roles) throws Exception {
094        adminRoles = roles;
095        setAdminACLs(parseACLs(adminRoles));
096    }
097
098    public void setRead(String roles) throws Exception {
099        readRoles = roles;
100        setReadACLs(parseACLs(readRoles));
101    }
102
103    public void setWrite(String roles) throws Exception {
104        writeRoles = roles;
105        setWriteACLs(parseACLs(writeRoles));
106    }
107
108    protected Set<Object> parseACLs(String roles) throws Exception {
109        Set<Object> answer = new HashSet<Object>();
110        StringTokenizer iter = new StringTokenizer(roles, ",");
111        while (iter.hasMoreTokens()) {
112            String name = iter.nextToken().trim();
113            Class[] paramClass = new Class[1];
114            paramClass[0] = String.class;
115
116            Object[] param = new Object[1];
117            param[0] = name;
118
119            try {
120                Class cls = Class.forName(groupClass);
121
122                Constructor[] constructors = cls.getConstructors();
123                int i;
124                for (i = 0; i < constructors.length; i++) {
125                    Class[] paramTypes = constructors[i].getParameterTypes();
126                    if (paramTypes.length != 0 && paramTypes[0].equals(paramClass[0])) {
127                        break;
128                    }
129                }
130                if (i < constructors.length) {
131                    Object instance = constructors[i].newInstance(param);
132                    answer.add(instance);
133                } else {
134                    Object instance = cls.newInstance();
135                    Method[] methods = cls.getMethods();
136                    i = 0;
137                    for (i = 0; i < methods.length; i++) {
138                        Class[] paramTypes = methods[i].getParameterTypes();
139                        if (paramTypes.length != 0 && methods[i].getName().equals("setName") && paramTypes[0].equals(paramClass[0])) {
140                            break;
141                        }
142                    }
143
144                    if (i < methods.length) {
145                        methods[i].invoke(instance, param);
146                        answer.add(instance);
147                    } else {
148                        throw new NoSuchMethodException();
149                    }
150                }
151            } catch (Exception e) {
152                throw e;
153            }
154        }
155        return answer;
156    }
157
158    public void afterPropertiesSet() throws Exception {
159        super.afterPropertiesSet();
160
161        if (adminRoles != null) {
162            setAdminACLs(parseACLs(adminRoles));
163        }
164
165        if (writeRoles != null) {
166            setWriteACLs(parseACLs(writeRoles));
167        }
168
169        if (readRoles != null) {
170            setReadACLs(parseACLs(readRoles));
171        }
172
173    }
174}