extensions/net.sf.basedb.otp/trunk/src/net/sf/basedb/otp/Otp.java

Code
Comments
Other
Rev Date Author Line
4846 12 Jun 18 nicklas 1 /**
4846 12 Jun 18 nicklas 2   $Id $
4846 12 Jun 18 nicklas 3
4846 12 Jun 18 nicklas 4   Copyright (C) 2014 Nicklas Nordborg
4846 12 Jun 18 nicklas 5
4846 12 Jun 18 nicklas 6   This file is part of BASE - BioArray Software Environment.
4846 12 Jun 18 nicklas 7   Available at http://base.thep.lu.se/
4846 12 Jun 18 nicklas 8
4846 12 Jun 18 nicklas 9   BASE is free software; you can redistribute it and/or
4846 12 Jun 18 nicklas 10   modify it under the terms of the GNU General Public License
4846 12 Jun 18 nicklas 11   as published by the Free Software Foundation; either version 3
4846 12 Jun 18 nicklas 12   of the License, or (at your option) any later version.
4846 12 Jun 18 nicklas 13
4846 12 Jun 18 nicklas 14   BASE is distributed in the hope that it will be useful,
4846 12 Jun 18 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
4846 12 Jun 18 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4846 12 Jun 18 nicklas 17   GNU General Public License for more details.
4846 12 Jun 18 nicklas 18
4846 12 Jun 18 nicklas 19   You should have received a copy of the GNU General Public License
4846 12 Jun 18 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
4846 12 Jun 18 nicklas 21 */
4846 12 Jun 18 nicklas 22 package net.sf.basedb.otp;
4846 12 Jun 18 nicklas 23
4846 12 Jun 18 nicklas 24
5183 06 Dec 18 nicklas 25 import java.io.File;
4848 13 Jun 18 nicklas 26 import java.io.InputStream;
4848 13 Jun 18 nicklas 27 import java.net.URL;
4848 13 Jun 18 nicklas 28 import java.util.Arrays;
4848 13 Jun 18 nicklas 29 import java.util.HashSet;
4848 13 Jun 18 nicklas 30 import java.util.Properties;
4848 13 Jun 18 nicklas 31 import java.util.Set;
4848 13 Jun 18 nicklas 32
4848 13 Jun 18 nicklas 33 import net.sf.basedb.core.ConfigurationException;
4846 12 Jun 18 nicklas 34 import net.sf.basedb.core.authentication.AuthenticationMethod;
5183 06 Dec 18 nicklas 35 import net.sf.basedb.util.FileUtil;
4846 12 Jun 18 nicklas 36
4846 12 Jun 18 nicklas 37 /**
4846 12 Jun 18 nicklas 38   Global constants for the OTP package.
4846 12 Jun 18 nicklas 39   @author Nicklas
4846 12 Jun 18 nicklas 40   @since 1.0
4846 12 Jun 18 nicklas 41 */
4846 12 Jun 18 nicklas 42 public final class Otp 
4846 12 Jun 18 nicklas 43 {
4846 12 Jun 18 nicklas 44   /**
4846 12 Jun 18 nicklas 45     The current version of this package.
4846 12 Jun 18 nicklas 46   */
5563 14 Aug 19 nicklas 47   public static final String VERSION = "1.4-dev";
4846 12 Jun 18 nicklas 48
4848 13 Jun 18 nicklas 49   /**
4848 13 Jun 18 nicklas 50     Authentication method where a user can login with username and OTP only.
4848 13 Jun 18 nicklas 51   */
5157 30 Nov 18 nicklas 52   public static final AuthenticationMethod OTP_ONLY_AUTHENTICATION_METHOD = AuthenticationMethod.getInstance("otp-only");
4846 12 Jun 18 nicklas 53
4848 13 Jun 18 nicklas 54   /**
4848 13 Jun 18 nicklas 55     Authentication method where a user need to login with username, password and OTP.
4848 13 Jun 18 nicklas 56   */
4848 13 Jun 18 nicklas 57   public static final AuthenticationMethod OTP_PASSWORD_AUTHENTICATION_METHOD = AuthenticationMethod.getInstance("otp+password");
4846 12 Jun 18 nicklas 58   
4851 14 Jun 18 nicklas 59   /**
4851 14 Jun 18 nicklas 60     A flag to indicate that we are in OTP setup mode. This will
4851 14 Jun 18 nicklas 61     trigger the SetupOtpAuthenticationManager to be used instead 
4851 14 Jun 18 nicklas 62     of the regular authentication manager.
4851 14 Jun 18 nicklas 63    */
5153 28 Nov 18 nicklas 64   public static final String SETUP_MODE = "net.sf.basedb.otp.otp-setup";
4851 14 Jun 18 nicklas 65
5183 06 Dec 18 nicklas 66   private static File configFile;
5183 06 Dec 18 nicklas 67   private static long configFileLastModifed;
4848 13 Jun 18 nicklas 68   private static Properties config;
5183 06 Dec 18 nicklas 69   private static AuthenticationMethod authMethod;
4848 13 Jun 18 nicklas 70   private static Set<String> noOtpLogin;
4848 13 Jun 18 nicklas 71   private static Set<String> requireOtpLogin;
4848 13 Jun 18 nicklas 72
4848 13 Jun 18 nicklas 73   /**
5157 30 Nov 18 nicklas 74     @since 1.2
5157 30 Nov 18 nicklas 75   */
5157 30 Nov 18 nicklas 76   private static Set<String> allowedAuthenticationMethods;
5157 30 Nov 18 nicklas 77
5157 30 Nov 18 nicklas 78   /**
4848 13 Jun 18 nicklas 79     Load configuration file: /base-otp.properties
5183 06 Dec 18 nicklas 80     If checkModified=true changes to the configuration file are detected
5183 06 Dec 18 nicklas 81     and reloaded if needed.
4848 13 Jun 18 nicklas 82   */
5183 06 Dec 18 nicklas 83   public static synchronized final Properties getConfig(boolean checkModified)
4848 13 Jun 18 nicklas 84   {
5183 06 Dec 18 nicklas 85     if (checkModified && configFile != null && configFile.lastModified() != configFileLastModifed)
5183 06 Dec 18 nicklas 86     {
5183 06 Dec 18 nicklas 87       // The configuration has changed, reset configuration and force reload
5183 06 Dec 18 nicklas 88       config = null;
5183 06 Dec 18 nicklas 89       configFile = null;
5183 06 Dec 18 nicklas 90     }
4848 13 Jun 18 nicklas 91     if (config == null)
4848 13 Jun 18 nicklas 92     {
5183 06 Dec 18 nicklas 93       InputStream is = null;
4848 13 Jun 18 nicklas 94       try
4848 13 Jun 18 nicklas 95       {
4848 13 Jun 18 nicklas 96         URL configUrl = Otp.class.getResource("/base-otp.properties");
5183 06 Dec 18 nicklas 97         is = configUrl == null ? null : configUrl.openStream();
4848 13 Jun 18 nicklas 98         if (is == null)
4848 13 Jun 18 nicklas 99         {
4848 13 Jun 18 nicklas 100           throw new ConfigurationException("Can't find the configuration file. " +
4848 13 Jun 18 nicklas 101               "Make sure '/base-otp.properties' is in the CLASSPATH.");
4848 13 Jun 18 nicklas 102         }
5183 06 Dec 18 nicklas 103         if (configUrl.getProtocol().equals("file"))
5183 06 Dec 18 nicklas 104         {
5183 06 Dec 18 nicklas 105           File f = new File(configUrl.getPath());
5183 06 Dec 18 nicklas 106           if (f.exists())
5183 06 Dec 18 nicklas 107           {
5183 06 Dec 18 nicklas 108             configFile = f;
5183 06 Dec 18 nicklas 109             configFileLastModifed = configFile.lastModified();
5183 06 Dec 18 nicklas 110           }
5183 06 Dec 18 nicklas 111         }
4848 13 Jun 18 nicklas 112         config = new Properties();
4848 13 Jun 18 nicklas 113         config.load(is);
4848 13 Jun 18 nicklas 114       }
4848 13 Jun 18 nicklas 115       catch (Exception ex)
4848 13 Jun 18 nicklas 116       {
4848 13 Jun 18 nicklas 117         throw new ConfigurationException(ex.getMessage(), ex);
4848 13 Jun 18 nicklas 118       }
5183 06 Dec 18 nicklas 119       finally
5183 06 Dec 18 nicklas 120       {
5183 06 Dec 18 nicklas 121         FileUtil.close(is);
5183 06 Dec 18 nicklas 122       }
4848 13 Jun 18 nicklas 123       
5183 06 Dec 18 nicklas 124       String loginMethod = config.getProperty("login-method");
5183 06 Dec 18 nicklas 125       authMethod = "otp-only".equals(loginMethod) ?  OTP_ONLY_AUTHENTICATION_METHOD : OTP_PASSWORD_AUTHENTICATION_METHOD;
5183 06 Dec 18 nicklas 126       
4848 13 Jun 18 nicklas 127       String noOtp  = config.getProperty("no-otp");
4848 13 Jun 18 nicklas 128       if (noOtp != null)
4848 13 Jun 18 nicklas 129       {
4848 13 Jun 18 nicklas 130         noOtpLogin = new HashSet<String>(Arrays.asList(noOtp.split("[\\s,]+")));
4848 13 Jun 18 nicklas 131       }
4848 13 Jun 18 nicklas 132       
4848 13 Jun 18 nicklas 133       String requireOtp  = config.getProperty("require-otp");
4848 13 Jun 18 nicklas 134       if (requireOtp != null)
4848 13 Jun 18 nicklas 135       {
4848 13 Jun 18 nicklas 136         requireOtpLogin = new HashSet<String>(Arrays.asList(requireOtp.split("[\\s,]+")));
4848 13 Jun 18 nicklas 137       }
5157 30 Nov 18 nicklas 138
5157 30 Nov 18 nicklas 139       String otherMethods = config.getProperty("allow-other-authentication");
5157 30 Nov 18 nicklas 140       if (otherMethods != null)
5157 30 Nov 18 nicklas 141       {
5157 30 Nov 18 nicklas 142         allowedAuthenticationMethods = new HashSet<String>(Arrays.asList(otherMethods.split("[\\s,]+")));
5157 30 Nov 18 nicklas 143       }
4848 13 Jun 18 nicklas 144     }
4848 13 Jun 18 nicklas 145     return config;
4848 13 Jun 18 nicklas 146   }
4848 13 Jun 18 nicklas 147   
4848 13 Jun 18 nicklas 148   
4848 13 Jun 18 nicklas 149   /**
4848 13 Jun 18 nicklas 150     Check if OTP login has been disabled for the given client id. 
4848 13 Jun 18 nicklas 151     To disable a client, the id should be listed in no-otp setting
4848 13 Jun 18 nicklas 152     in base-otp.properties configuration file.
4848 13 Jun 18 nicklas 153     
4848 13 Jun 18 nicklas 154     @param clientId The external id of the client application
4848 13 Jun 18 nicklas 155     @return TRUE if OTP is disabled, FALSE if no
4848 13 Jun 18 nicklas 156   */
4848 13 Jun 18 nicklas 157   public static boolean isOtpDisabledForClient(String clientId)
4848 13 Jun 18 nicklas 158   {
4848 13 Jun 18 nicklas 159     return clientId != null && noOtpLogin != null && noOtpLogin.contains(clientId);
4848 13 Jun 18 nicklas 160   }
4848 13 Jun 18 nicklas 161   
4848 13 Jun 18 nicklas 162   /**
4848 13 Jun 18 nicklas 163     Check if OTP login is required for the given client id. 
4848 13 Jun 18 nicklas 164     To require a client to use OTP, the id should be listed in 
4848 13 Jun 18 nicklas 165     the require-otp setting in base-otp.properties configuration file.
4848 13 Jun 18 nicklas 166     
4848 13 Jun 18 nicklas 167     @param clientId The external id of the client application
4848 13 Jun 18 nicklas 168     @return TRUE if OTP is required, FALSE if not
4848 13 Jun 18 nicklas 169   */
4848 13 Jun 18 nicklas 170   public static boolean isOtpRequiredForClient(String clientId)
4848 13 Jun 18 nicklas 171   {
4848 13 Jun 18 nicklas 172     return clientId != null && requireOtpLogin != null && requireOtpLogin.contains(clientId);
4848 13 Jun 18 nicklas 173   }
4918 08 Aug 18 nicklas 174   
4918 08 Aug 18 nicklas 175   /**
5157 30 Nov 18 nicklas 176     Check if the authentication method is allowed. By default the {@link #getAuthenticationMethod()} 
5157 30 Nov 18 nicklas 177     is the only one allowed, but also methods listed in the 'allow-other-authentication'
5157 30 Nov 18 nicklas 178     setting in the 'base-otp.properties' file.
5157 30 Nov 18 nicklas 179   
5157 30 Nov 18 nicklas 180     @param auth The authentication method to check
5157 30 Nov 18 nicklas 181     @return TRUE if the authentication method is allowed, FALSE if not
5157 30 Nov 18 nicklas 182     @since 1.2
5157 30 Nov 18 nicklas 183   */
5157 30 Nov 18 nicklas 184   public static boolean isAuthenticationMethodAllowed(AuthenticationMethod auth)
5157 30 Nov 18 nicklas 185   {
5157 30 Nov 18 nicklas 186     if (auth == null) return false;
5157 30 Nov 18 nicklas 187     if (auth == getAuthenticationMethod()) return true;
5157 30 Nov 18 nicklas 188     if (allowedAuthenticationMethods == null) return false;
5157 30 Nov 18 nicklas 189     return allowedAuthenticationMethods.contains("*") || allowedAuthenticationMethods.contains(auth.getMethod());
5157 30 Nov 18 nicklas 190   }
5157 30 Nov 18 nicklas 191
5157 30 Nov 18 nicklas 192   
5157 30 Nov 18 nicklas 193   /**
4918 08 Aug 18 nicklas 194     Get the authentication method to use:
4918 08 Aug 18 nicklas 195     {@link #OTP_ONLY_AUTHENTICATION_METHOD} or 
4918 08 Aug 18 nicklas 196     {@link #OTP_PASSWORD_AUTHENTICATION_METHOD}.
4918 08 Aug 18 nicklas 197   */
4918 08 Aug 18 nicklas 198   public static AuthenticationMethod getAuthenticationMethod()
4918 08 Aug 18 nicklas 199   {
5183 06 Dec 18 nicklas 200     return authMethod;
4918 08 Aug 18 nicklas 201   }
4848 13 Jun 18 nicklas 202
4918 08 Aug 18 nicklas 203
4846 12 Jun 18 nicklas 204 }