/**********************************************************************************
* $URL: $
* $Id: $
***********************************************************************************
*
* Copyright (c) 2008 The Sakai Foundation.
*
* Licensed under the Educational Community License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ecl1.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.login.impl;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.component.api.ServerConfigurationService;
import org.sakaiproject.event.api.UsageSessionService;
import org.sakaiproject.login.api.Login;
import org.sakaiproject.login.api.LoginAdvisor;
import org.sakaiproject.login.api.LoginCredentials;
import org.sakaiproject.login.api.LoginRenderEngine;
import org.sakaiproject.login.api.LoginService;
import org.sakaiproject.user.api.Authentication;
import org.sakaiproject.user.api.AuthenticationException;
import org.sakaiproject.user.api.Evidence;
import org.sakaiproject.user.api.AuthenticationManager;
import org.sakaiproject.util.IdPwEvidence;
public abstract class LoginServiceComponent implements LoginService {
protected abstract AuthenticationManager authenticationManager();
protected abstract ServerConfigurationService serverConfigurationService();
protected abstract UsageSessionService usageSessionService();
private Map<String, LoginRenderEngine> renderEngines = new ConcurrentHashMap<String, LoginRenderEngine>();
private LoginAdvisor loginAdvisor = null;
public void addRenderEngine(String context, LoginRenderEngine vengine) {
renderEngines.put(context, vengine);
}
public void authenticate(LoginCredentials credentials) throws LoginException {
LoginAdvisor loginAdvisor = resolveLoginAdvisor();
// Only bother checking login credentials and/or imposing a penalty when the protection level is set
boolean isAdvisorEnabled = loginAdvisor != null && loginAdvisor.isAdvisorEnabled();
// authenticate
try
{
String eid = credentials.getIdentifier();
String pw = credentials.getPassword();
boolean isEidEmpty = (eid == null) || (eid.length() == 0);
boolean isPwEmpty = (pw == null) || (pw.length() == 0);
if (isAdvisorEnabled) {
if (!loginAdvisor.checkCredentials(credentials)) {
throw new LoginException(Login.EXCEPTION_INVALID_CREDENTIALS);
}
}
if (isEidEmpty || isPwEmpty)
{
throw new AuthenticationException("missing-fields");
}
// Do NOT trim the password, since many authentication systems allow whitespace.
eid = eid.trim();
Evidence e = new IdPwEvidence(eid, pw);
Authentication a = authenticationManager().authenticate(e);
// login the user
if (usageSessionService().login(a, credentials.getRequest()))
{
if (isAdvisorEnabled)
loginAdvisor.setSuccess(credentials);
}
else
{
if (isAdvisorEnabled)
loginAdvisor.setFailure(credentials);
throw new LoginException(Login.EXCEPTION_INVALID);
}
}
catch (AuthenticationException ex)
{
if (ex.getMessage().equals("missing-fields"))
throw new LoginException(Login.EXCEPTION_MISSING_CREDENTIALS);
/**
* If the Authentication Exception Equals Disabled then
* re throw the message to the top.
*/
if (ex.getMessage().equals(Login.EXCEPTION_DISABLED))
throw new LoginException(Login.EXCEPTION_DISABLED);
boolean isPenaltyImposed = false;
if (isAdvisorEnabled) {
loginAdvisor.setFailure(credentials);
isPenaltyImposed = !loginAdvisor.checkCredentials(credentials);
}
if (isPenaltyImposed)
throw new LoginException(Login.EXCEPTION_INVALID_WITH_PENALTY);
else
throw new LoginException(Login.EXCEPTION_INVALID);
}
}
public String getLoginAdvice(LoginCredentials credentials) {
LoginAdvisor loginAdvisor = resolveLoginAdvisor();
// Only bother checking login credentials and/or imposing a penalty when the protection level is set
boolean isAdvisorEnabled = loginAdvisor != null && loginAdvisor.isAdvisorEnabled();
if (isAdvisorEnabled) {
return loginAdvisor.getLoginAdvice(credentials);
}
return "";
}
public LoginRenderEngine getRenderEngine(String context, HttpServletRequest request)
{
// at this point we ignore request but we might use ut to return more
// than one render engine
if (context == null || context.length() == 0)
{
context = Login.DEFAULT_LOGIN_CONTEXT;
}
return (LoginRenderEngine) renderEngines.get(context);
}
public boolean hasLoginAdvice() {
LoginAdvisor loginAdvisor = resolveLoginAdvisor();
return loginAdvisor != null && loginAdvisor.isAdvisorEnabled();
}
public void removeRenderEngine(String context, LoginRenderEngine vengine) {
renderEngines.remove(context);
}
private LoginAdvisor resolveLoginAdvisor() {
if (loginAdvisor == null) {
loginAdvisor = (LoginAdvisor)ComponentManager.get(LoginAdvisor.class);
}
return loginAdvisor;
}
}