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    @SuppressWarnings("rawtypes")
037    public 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    }