001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2012 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.server.ui;
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.slf4j.Logger;
024    import org.slf4j.LoggerFactory;
025    import org.sonar.api.CoreProperties;
026    import org.sonar.api.ServerComponent;
027    import org.sonar.api.config.Settings;
028    import org.sonar.api.security.LoginPasswordAuthenticator;
029    import org.sonar.api.security.SecurityRealm;
030    import org.sonar.api.utils.SonarException;
031    
032    /**
033     * @since 2.14
034     */
035    public class SecurityRealmFactory implements ServerComponent {
036    
037      private static final Logger INFO = LoggerFactory.getLogger("org.sonar.INFO");
038    
039      private final boolean ignoreStartupFailure;
040      private final SecurityRealm realm;
041    
042      static final String REALM_PROPERTY = "sonar.security.realm";
043    
044      public SecurityRealmFactory(Settings settings, SecurityRealm[] realms, LoginPasswordAuthenticator[] authenticators) {
045        ignoreStartupFailure = settings.getBoolean(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE);
046        String realmName = settings.getString(REALM_PROPERTY);
047        String className = settings.getString(CoreProperties.CORE_AUTHENTICATOR_CLASS);
048        SecurityRealm selectedRealm = null;
049        if (!StringUtils.isEmpty(realmName)) {
050          selectedRealm = selectRealm(realms, realmName);
051          if (selectedRealm == null) {
052            throw new SonarException("Realm '" + realmName + "' not found. Please check the property '" + REALM_PROPERTY + "' in conf/sonar.properties");
053          }
054        }
055        if (selectedRealm == null && !StringUtils.isEmpty(className)) {
056          LoginPasswordAuthenticator authenticator = selectAuthenticator(authenticators, className);
057          if (authenticator == null) {
058            throw new SonarException("Authenticator '" + className + "' not found. Please check the property '" + CoreProperties.CORE_AUTHENTICATOR_CLASS
059              + "' in conf/sonar.properties");
060          }
061          selectedRealm = new CompatibilityRealm(authenticator);
062        }
063        realm = selectedRealm;
064      }
065    
066      public SecurityRealmFactory(Settings settings, LoginPasswordAuthenticator[] authenticators) {
067        this(settings, null, authenticators);
068      }
069    
070      public SecurityRealmFactory(Settings settings, SecurityRealm[] realms) {
071        this(settings, realms, null);
072      }
073    
074      public SecurityRealmFactory(Settings settings) {
075        this(settings, null, null);
076      }
077    
078      public void start() {
079        if (realm != null) {
080          try {
081            INFO.info("Security realm: " + realm.getName());
082            realm.init();
083            INFO.info("Security realm started");
084          } catch (RuntimeException e) {
085            if (ignoreStartupFailure) {
086              INFO.error("IGNORED - Security realm fails to start: " + e.getMessage());
087            } else {
088              throw new SonarException("Security realm fails to start: " + e.getMessage(), e);
089            }
090          }
091        }
092      }
093    
094      public SecurityRealm getRealm() {
095        return realm;
096      }
097    
098      private static SecurityRealm selectRealm(SecurityRealm[] realms, String realmName) {
099        if (realms != null) {
100          for (SecurityRealm realm : realms) {
101            if (StringUtils.equals(realmName, realm.getName())) {
102              return realm;
103            }
104          }
105        }
106        return null;
107      }
108    
109      private static LoginPasswordAuthenticator selectAuthenticator(LoginPasswordAuthenticator[] authenticators, String className) {
110        if (authenticators != null) {
111          for (LoginPasswordAuthenticator lpa : authenticators) {
112            if (lpa.getClass().getName().equals(className)) {
113              return lpa;
114            }
115          }
116        }
117        return null;
118      }
119    
120    }