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     */
017    package org.apache.activemq.security;
018    
019    import java.lang.reflect.Constructor;
020    import java.lang.reflect.Method;
021    import java.util.Collections;
022    import java.util.HashSet;
023    import java.util.Set;
024    import java.util.StringTokenizer;
025    
026    import 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    public 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    }