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