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.shiro.env;
018
019import org.apache.activemq.shiro.authz.ActiveMQPermissionResolver;
020import org.apache.activemq.shiro.mgt.DefaultActiveMqSecurityManager;
021import org.apache.shiro.ShiroException;
022import org.apache.shiro.config.ConfigurationException;
023import org.apache.shiro.config.Ini;
024import org.apache.shiro.config.IniSecurityManagerFactory;
025import org.apache.shiro.env.DefaultEnvironment;
026import org.apache.shiro.io.ResourceUtils;
027import org.apache.shiro.mgt.SecurityManager;
028import org.apache.shiro.realm.Realm;
029import org.apache.shiro.realm.text.IniRealm;
030import org.apache.shiro.util.Initializable;
031import org.apache.shiro.util.LifecycleUtils;
032
033import java.util.Map;
034
035/**
036 * @since 5.10.0
037 */
038public class IniEnvironment extends DefaultEnvironment implements Initializable {
039
040    private Ini ini;
041    private String iniConfig;
042    private String iniResourePath;
043
044    public IniEnvironment() {
045    }
046
047    public IniEnvironment(Ini ini) {
048        this.ini = ini;
049        init();
050    }
051
052    public IniEnvironment(String iniConfig) {
053        Ini ini = new Ini();
054        ini.load(iniConfig);
055        this.ini = ini;
056        init();
057    }
058
059    public void setIni(Ini ini) {
060        this.ini = ini;
061    }
062
063    public void setIniConfig(String config) {
064        this.iniConfig = config;
065    }
066
067    public void setIniResourcePath(String iniResourcePath) {
068        this.iniResourePath = iniResourcePath;
069    }
070
071    @Override
072    public void init() throws ShiroException {
073        //this.environment and this.securityManager are null.  Try Ini config:
074        Ini ini = this.ini;
075        if (ini != null) {
076            apply(ini);
077        }
078
079        if (this.objects.isEmpty() && this.iniConfig != null) {
080            ini = new Ini();
081            ini.load(this.iniConfig);
082            apply(ini);
083        }
084
085        if (this.objects.isEmpty() && this.iniResourePath != null) {
086            ini = new Ini();
087            ini.loadFromPath(this.iniResourePath);
088            apply(ini);
089        }
090
091        if (this.objects.isEmpty()) {
092            if (ResourceUtils.resourceExists("classpath:shiro.ini")) {
093                ini = new Ini();
094                ini.loadFromPath("classpath:shiro.ini");
095                apply(ini);
096            }
097        }
098
099        if (this.objects.isEmpty()) {
100            String msg = "Configuration error.  All heuristics for acquiring Shiro INI config " +
101                    "have been exhausted.  Ensure you configure one of the following properties: " +
102                    "1) ini 2) iniConfig 3) iniResourcePath and the Ini sections are not empty.";
103            throw new ConfigurationException(msg);
104        }
105
106        LifecycleUtils.init(this.objects.values());
107    }
108
109    protected void apply(Ini ini) {
110        if (ini != null && !ini.isEmpty()) {
111            Map<String, ?> objects = createObjects(ini);
112            this.ini = ini;
113            this.objects.clear();
114            this.objects.putAll(objects);
115        }
116    }
117
118    private Map<String, ?> createObjects(Ini ini) {
119        IniSecurityManagerFactory factory = new IniSecurityManagerFactory(ini) {
120
121            @Override
122            protected SecurityManager createDefaultInstance() {
123                return new DefaultActiveMqSecurityManager();
124            }
125
126            @Override
127            protected Realm createRealm(Ini ini) {
128                IniRealm realm = (IniRealm)super.createRealm(ini);
129                realm.setPermissionResolver(new ActiveMQPermissionResolver());
130                return realm;
131            }
132        };
133        factory.getInstance(); //trigger beans creation
134        return factory.getBeans();
135    }
136}