/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/
package org.olat.user;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.olat.NewControllerFactory;
import org.olat.basesecurity.Constants;
import org.olat.basesecurity.Manager;
import org.olat.basesecurity.ManagerFactory;
import org.olat.basesecurity.SecurityGroup;
import org.olat.core.CoreSpringFactory;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.configuration.OLATModule;
import org.olat.core.id.Identity;
import org.olat.core.id.User;
import org.olat.core.id.UserConstants;
import org.olat.core.logging.OLATRuntimeException;
import org.olat.core.logging.StartupException;
import org.olat.core.logging.Tracing;
import org.olat.core.util.Encoder;
import org.olat.core.util.WebappHelper;
import org.olat.login.AfterLoginConfig;
import org.olat.login.AfterLoginInterceptionManager;
import org.olat.login.OLATAuthenticationController;
import org.olat.user.propertyhandlers.UserPropertyHandler;
import com.anthonyeden.lib.config.Configuration;
/**
* Desciption: The user module represents an implementation of
* the OLAT user with its database object, business managers and page actions.
*
* @author Florian Gnägi
*/
public class UserModule implements OLATModule {
private static final String ADMIN_USER_NAME_DEFAULT_VALUE = "administrator";
private static List loginBlacklist = new ArrayList();
private static boolean hasTestUsers = false;
private Manager securityManager;
private SecurityGroup adminGroup, authorGroup, olatuserGroup, anonymousGroup, groupmanagerGroup, usermanagerGroup;
private static boolean pwdchangeallowed;
private static String adminUserName;
/**
* @see org.olat.core.configuration.OLATModule#init(com.anthonyeden.lib.config.Configuration)
*/
public void init(Configuration configuration) {
Configuration pwdch = configuration.getChild("pwdchange");
pwdchangeallowed = Boolean.valueOf(pwdch.getAttribute("allowed")).booleanValue();
// Pre-load login blacklist
File fBlacklist = new File(WebappHelper.getContextRoot() + "/WEB-INF/blacklist.txt");
if (fBlacklist.exists()) {
BufferedReader fReader = null;
try {
fReader = new BufferedReader(new FileReader(fBlacklist));
int count = 0;
while (fReader.ready()) {
String regexp = fReader.readLine();
if (regexp.startsWith("##")) continue;
else {
try {
Pattern.compile(regexp);
} catch (PatternSyntaxException pse) {
throw new StartupException("Invalid pattern syntax in blacklist. Pattern: " + regexp);
}
loginBlacklist.add(regexp);
count++;
}
}
Tracing.logInfo("Successfully added " + count + " entries to login blacklist.", UserModule.class);
} catch (Exception e) {
throw new StartupException("Unable to read blacklist. Please fix.");
} finally {
if (fReader != null) try {
fReader.close();
} catch (Exception e) {
// ok in finally block.
}
}
}
// Autogeneration of test users
String generateTestUsers = configuration.getChildValue("generateTestUsers");
if (generateTestUsers == null) hasTestUsers = false;
else {
if (generateTestUsers.equals("true")) {
hasTestUsers = true;
} else if (generateTestUsers.equals("false")) {
hasTestUsers = false;
} else {
throw new StartupException("UserModule configuration Element 'generateTestUsers' was set to '" + generateTestUsers
+ "' but only value 'true' or 'false' is allowed.");
}
}
// Check if default users exists, if not create them
securityManager = ManagerFactory.getManager();
adminGroup = securityManager.findSecurityGroupByName(Constants.GROUP_ADMIN);
authorGroup = securityManager.findSecurityGroupByName(Constants.GROUP_AUTHORS);
olatuserGroup = securityManager.findSecurityGroupByName(Constants.GROUP_OLATUSERS);
anonymousGroup = securityManager.findSecurityGroupByName(Constants.GROUP_ANONYMOUS);
groupmanagerGroup = securityManager.findSecurityGroupByName(Constants.GROUP_GROUPMANAGERS);
usermanagerGroup = securityManager.findSecurityGroupByName(Constants.GROUP_USERMANAGERS);
// read user editable fields configuration
Configuration defaultUsers = configuration.getChild("defaultUsers");
if (defaultUsers != null) {
List usersList = defaultUsers.getChildren();
for (Iterator iter = usersList.iterator(); iter.hasNext();) {
Configuration user = (Configuration) iter.next();
createUser(user);
}
}
if (hasTestUsers) {
// read user editable fields configuration
Configuration testUsers = configuration.getChild("testUsers");
if (testUsers != null) {
List usersList = testUsers.getChildren();
for (Iterator iter = usersList.iterator(); iter.hasNext();) {
Configuration user = (Configuration) iter.next();
createUser(user);
}
}
}
// Cleanup, otherwhise this subjects will have problems in normal OLAT
// operation
DBFactory.getInstance(false).intermediateCommit();
adminUserName = configuration.getChildValue("adminUserName");
if (adminUserName == null) {
adminUserName = ADMIN_USER_NAME_DEFAULT_VALUE;
}
// Check if user manager is configured properly and has user property
// handlers for the mandatory user properties used in OLAT
checkMandatoryUserProperty(UserConstants.FIRSTNAME);
checkMandatoryUserProperty(UserConstants.LASTNAME);
checkMandatoryUserProperty(UserConstants.EMAIL);
// Add controller factory extension point to launch user profile controller
NewControllerFactory.getInstance().addContextEntryControllerCreator(Identity.class.getSimpleName(),
new IdentityContextEntryControllerCreator());
// Append AfterLoginControllers if any configured
if (CoreSpringFactory.containsBean("org.olat.user.AfterLoginConfig")) {
AfterLoginConfig aLConf = (AfterLoginConfig) CoreSpringFactory.getBean("org.olat.user.AfterLoginConfig");
if (aLConf != null) {
AfterLoginInterceptionManager.getInstance().addAfterLoginControllerConfig(aLConf);
}
}
}
private void checkMandatoryUserProperty(String userPropertyIdentifyer) {
UserManager um = UserManager.getInstance();
List<UserPropertyHandler> propertyHandlers = um.getUserPropertiesConfig().getAllUserPropertyHandlers();
boolean propertyDefined = false;
for (UserPropertyHandler propertyHandler : propertyHandlers) {
if (propertyHandler.getName().equals(userPropertyIdentifyer)) {
propertyDefined = true;
break;
}
}
if ( ! propertyDefined) {
throw new StartupException("The user property handler for the mandatory user property "
+ userPropertyIdentifyer + " is not defined. Check your olat_userconfig.xml file!");
}
}
/**
* @see org.olat.core.configuration.OLATModule#destroy()
*/
public void destroy() {
// nothing to do here.
}
/**
* Method to create a user with the given configuration
*
* @return Identity or null
*/
private Identity createUser(Configuration user) {
String username = user.getAttribute("username");
String firstname = user.getAttribute("firstname");
String lastname = user.getAttribute("lastname");
String email = user.getAttribute("email");
String pwd = user.getAttribute("pwd");
String language = user.getAttribute("language");
Identity identity;
identity = securityManager.findIdentityByName(username);
if (identity == null) {
// Create new user and subject
User newUser = new UserImpl(firstname, lastname, email);
newUser.getPreferences().setLanguage(language);
newUser.getPreferences().setInformSessionTimeout(true);
// Now finally create that user thing on the database with all
// credentials, person etc. in one transation context!
identity = ManagerFactory.getManager().createAndPersistIdentityAndUser(username, newUser, OLATAuthenticationController.PROVIDER_OLAT,
username, Encoder.encrypt(pwd));
if (identity == null) {
throw new OLATRuntimeException(this.getClass(), "Error, could not create user and subject with name " + username, null);
} else {
Boolean isGuest = Boolean.valueOf(user.getAttribute("isGuest"));
Boolean isAuthor = Boolean.valueOf(user.getAttribute("isAuthor"));
Boolean isAdmin = Boolean.valueOf(user.getAttribute("isAdmin"));
Boolean isUserManager = Boolean.valueOf(user.getAttribute("isUserManager"));
Boolean isGroupManager = Boolean.valueOf(user.getAttribute("isGroupManager"));
if (isGuest.booleanValue()) {
securityManager.addIdentityToSecurityGroup(identity, anonymousGroup);
Tracing.logInfo("Created anonymous user " + username, UserModule.class);
} else {
if (isAdmin.booleanValue()) {
securityManager.addIdentityToSecurityGroup(identity, adminGroup);
securityManager.addIdentityToSecurityGroup(identity, olatuserGroup);
Tracing.logInfo("Created admin user " + username, UserModule.class);
} else if (isAuthor.booleanValue()) {
securityManager.addIdentityToSecurityGroup(identity, authorGroup);
securityManager.addIdentityToSecurityGroup(identity, olatuserGroup);
Tracing.logInfo("Created author user " + username, UserModule.class);
} else if (isUserManager.booleanValue()) {
securityManager.addIdentityToSecurityGroup(identity, usermanagerGroup);
securityManager.addIdentityToSecurityGroup(identity, olatuserGroup);
Tracing.logInfo("Created userManager user " + username, UserModule.class);
} else if (isGroupManager.booleanValue()) {
securityManager.addIdentityToSecurityGroup(identity, groupmanagerGroup);
securityManager.addIdentityToSecurityGroup(identity, olatuserGroup);
Tracing.logInfo("Created groupManager user " + username, UserModule.class);
} else {
securityManager.addIdentityToSecurityGroup(identity, olatuserGroup);
Tracing.logInfo("Created user " + username, UserModule.class);
}
}
}
}
return identity;
}
/**
* @return List of logins on blacklist.
*/
public static List getLoginBlacklist() {
return loginBlacklist;
}
public static boolean isPwdchangeallowed() {
return pwdchangeallowed;
}
public static String getAdminUserName() {
return adminUserName;
}
}