/*
* Authenticate.java
*
* Copyright (c) 2013, Instituto Superior Técnico. All rights reserved.
*
* This file is part of bennu-core.
*
* bennu-core is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* bennu-core is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with bennu-core. If not, see
* <http://www.gnu.org/licenses/>.
*/
package org.fenixedu.bennu.core.security;
import java.util.Collection;
import java.util.Locale;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.fenixedu.bennu.core.domain.User;
import org.fenixedu.bennu.core.domain.exceptions.AuthorizationException;
import org.fenixedu.bennu.core.i18n.I18NFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pt.ist.fenixframework.FenixFramework;
public class Authenticate {
private static final Logger logger = LoggerFactory.getLogger(Authenticate.class);
private static final String LOGGED_USER_ATTRIBUTE = "LOGGED_USER_ATTRIBUTE";
private static final InheritableThreadLocal<User> loggedUser = new InheritableThreadLocal<>();
private static final Collection<UserAuthenticationListener> userAuthenticationListeners = new ConcurrentLinkedQueue<>();
/**
* Logs in the given User, associating it with the browser session for the current user.
*
* @param request
* The request that triggered the login
* @param response
* The response associated with the request that triggered the login
* @param user
* The user to log in
* @return
* The logged in user
* @throws AuthorizationException
* If the provided user is {@code null} or if the user has its login expired
*/
public static User login(HttpServletRequest request, HttpServletResponse response, User user) {
if (user == null || user.isLoginExpired()) {
throw AuthorizationException.authenticationFailed();
}
HttpSession session = request.getSession();
loggedUser.set(user);
session.setAttribute(LOGGED_USER_ATTRIBUTE, user);
final Locale preferredLocale = user.getProfile().getPreferredLocale();
if (preferredLocale != null) {
I18NFilter.updateLocale(preferredLocale, request, response);
}
fireLoginListeners(request, response, user);
logger.debug("Logged in user: " + user.getUsername());
return user;
}
/**
* Invalidates the current session, logging out the current user.
*
* Calling this method will cause subsequent calls to {{@link #getUser()} to return {@code null}.
*
* @param request
* The request that triggered the logout
* @param response
* The response associated with the requires that triggered the logout
*/
public static void logout(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession(false);
if (session != null) {
User user = (User) session.getAttribute(LOGGED_USER_ATTRIBUTE);
if (user != null) {
fireLogoutListeners(request, response, user);
}
session.invalidate();
}
loggedUser.set(null);
}
public static void mock(User user) {
loggedUser.set(user);
}
public static void unmock() {
loggedUser.set(null);
}
public static User getUser() {
return loggedUser.get();
}
public static boolean isLogged() {
return loggedUser.get() != null;
}
static void updateFromSession(HttpSession session) {
User user = (User) (session == null ? null : session.getAttribute(LOGGED_USER_ATTRIBUTE));
if (user != null && FenixFramework.isDomainObjectValid(user)) {
loggedUser.set(user);
} else {
loggedUser.set(null);
}
}
static void clear() {
loggedUser.set(null);
}
public static void addUserAuthenticationListener(UserAuthenticationListener listener) {
userAuthenticationListeners.add(listener);
}
public static void removeUserAuthenticationListener(UserAuthenticationListener listener) {
userAuthenticationListeners.remove(listener);
}
private static void fireLoginListeners(HttpServletRequest request, HttpServletResponse response, final User user) {
for (UserAuthenticationListener listener : userAuthenticationListeners) {
listener.onLogin(request, response, user);
}
}
private static void fireLogoutListeners(HttpServletRequest request, HttpServletResponse response, final User user) {
for (UserAuthenticationListener listener : userAuthenticationListeners) {
listener.onLogout(request, response, user);
}
}
}