/**
* This file is part of Faktotum.
*
*
* Faktotum is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Faktotum 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Faktotum.
*
* If not, see <http://www.gnu.org/licenses/>.
*/
package de.romankreisel.faktotum.handlers;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.Cookie;
import de.romankreisel.faktotum.beans.AuthenticationBean;
import de.romankreisel.faktotum.beans.BundesbruderBean;
import de.romankreisel.faktotum.beans.SettingBean;
import de.romankreisel.faktotum.datamodel.BundesbruderEntity;
import de.romankreisel.faktotum.datamodel.BundesbruderEntity.Permission;
import de.romankreisel.faktotum.exceptions.InvalidPasswordException;
import de.romankreisel.faktotum.exceptions.UnknownUserException;
/**
* @author Roman Kreisel <mail@romankreisel.de>
*
*/
@ManagedBean
@SessionScoped
public class AuthenticationHandler extends FaktotumHandler {
/**
*
*/
private static final long serialVersionUID = 7559007508985554866L;
@EJB
private AuthenticationBean authenticationBean;
@EJB
private BundesbruderBean bundesbruderBean;
private String userName;
private String password;
private boolean rememberMe = false;
private BundesbruderEntity loggedInBundesbruder;
@EJB
private SettingBean settingBean;
private final String COOKIE_SESSION_KEY = "FaktotumSessionKey";
private final String COOKIE_USER_NAME = "FaktotumUserName";
public void checkLogin() throws IOException {
String loginPath = "/login.xhtml";
String initPath = "/init.xhtml";
String homePath = "/pages/home.xhtml";
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
if (!this.isLoggedIn()) {
this.getLogger().fine("Request for " + externalContext.getRequestServletPath() + " prior authentication");
if (this.bundesbruderBean.getBundesbruderCount() > 0) {
this.getLogger().fine("Redirecting to Login-Page");
if (!externalContext.getRequestServletPath().equals(loginPath)) {
externalContext.redirect(externalContext.getRequestContextPath() + loginPath);
}
} else {
this.getLogger().info("No BBBB available in database, redirecting to initial Setup-Page!");
if (!externalContext.getRequestServletPath().equals(initPath)) {
externalContext.redirect(externalContext.getRequestContextPath() + initPath);
}
}
} else if (externalContext.getRequestServletPath().equals(loginPath)) {
externalContext.redirect(externalContext.getRequestContextPath() + homePath);
}
}
public Long getBundesbruderCount() {
return this.bundesbruderBean.getBundesbruderCount();
}
public BundesbruderEntity getLoggedInBundesbruder() {
return this.loggedInBundesbruder;
}
public boolean getMayAdministrateSystem() {
return this.isSystemAdministrator();
}
public boolean getMayEditMembership() {
if (this.isMembershipAdministrator() || this.isSystemAdministrator()) {
return true;
}
return false;
}
public boolean getMayEditMembership(BundesbruderEntity bundesbruderEntity) {
if (bundesbruderEntity != null) {
if (bundesbruderEntity.getMemberStatus() != null) {
if (bundesbruderEntity.getMemberStatus().isStudent()) {
return this.getMayEditMembershipActiveStudents();
}
}
return this.getMayEditMembership();
}
return false;
}
public boolean getMayEditMembershipActiveStudents() {
if (this.getMayEditMembership() || this.isMembershipAdministratorOnlyActiveStudents()) {
return true;
}
return false;
}
/**
* @return the password
*/
public String getPassword() {
return this.password;
}
/**
* @return the userName
*/
public String getUserName() {
return this.userName;
}
/**
* @return
*/
private String getValueFromCookie(String valueName) {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
Map<String, Object> cookieMap = externalContext.getRequestCookieMap();
if (cookieMap != null && cookieMap.containsKey(valueName) && cookieMap.get(valueName) != null) {
Object sessionKeyObject = cookieMap.get(valueName);
if (sessionKeyObject instanceof Cookie) {
return ((Cookie) sessionKeyObject).getValue();
}
}
return null;
}
/**
* This method checks whether the user has logged in or not
*
* If not, it will try to restore a persisted session, if available
*
* @return
*/
public boolean isLoggedIn() {
if (this.getLoggedInBundesbruder() != null) {
return true;
}
this.setLoggedInBundesbruder(this.authenticationBean.loginWithCookie(this.getValueFromCookie(this.COOKIE_SESSION_KEY),
this.getValueFromCookie(this.COOKIE_USER_NAME)));
return this.getLoggedInBundesbruder() != null;
}
public boolean isMembershipAdministrator() {
if (this.getLoggedInBundesbruder() == null || this.getLoggedInBundesbruder().getPermissions() == null) {
return false;
}
return this.getLoggedInBundesbruder().getPermissions().contains(Permission.MEMBERSHIP_ADMINISTRATION);
}
public boolean isMembershipAdministratorOnlyActiveStudents() {
if (this.getLoggedInBundesbruder() == null || this.getLoggedInBundesbruder().getPermissions() == null) {
return false;
}
return this.getLoggedInBundesbruder().getPermissions().contains(Permission.STUDENT_MEMBERSHIP_ADMINISTRATION);
}
/**
* @return the rememberMe
*/
public boolean isRememberMe() {
return this.rememberMe;
}
public boolean isSystemAdministrator() {
if (this.getLoggedInBundesbruder() == null || this.getLoggedInBundesbruder().getPermissions() == null) {
return false;
}
return this.getLoggedInBundesbruder().getPermissions().contains(Permission.SYSTEM_ADMINISTRATION);
}
public String login() {
FacesContext context = FacesContext.getCurrentInstance();
try {
this.setLoggedInBundesbruder(this.authenticationBean.login(this.userName, this.password));
this.getLogger().info(
"User " + (this.getLoggedInBundesbruder() != null ? this.getLoggedInBundesbruder().getUserName() : "\"null\"") + " logged in!");
if (this.getLoggedInBundesbruder() != null && this.isRememberMe()) {
// generate session key
String sessionKey = UUID.randomUUID().toString();
// store key into cookie
Map<String, Object> cookieProperties = new HashMap<String, Object>();
// cookie will expire after 1 year
cookieProperties.put("maxAge", this.settingBean.getIntegerSettingValue(SettingBean.SETTING_LONG_AUTH_SESSION_MAXAGE));
FacesContext.getCurrentInstance().getExternalContext().addResponseCookie(this.COOKIE_SESSION_KEY, sessionKey, cookieProperties);
FacesContext.getCurrentInstance().getExternalContext().addResponseCookie(this.COOKIE_USER_NAME, this.userName, cookieProperties);
this.authenticationBean.persistSession(sessionKey, this.getLoggedInBundesbruder());
}
return "home";
} catch (UnknownUserException e) {
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Login Fehlgeschlagen!", "Unbekannter Benutzername"));
this.getLogger().warning("Login failed, unknown username " + this.userName);
} catch (InvalidPasswordException e) {
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Login Fehlgeschlagen!", "Ungültiges Kennwort"));
this.getLogger().warning("Login failed, invalid password for username " + this.userName);
}
return null;
}
public String logout() {
BundesbruderEntity loggedOutBundesbruder = this.getLoggedInBundesbruder();
this.setLoggedInBundesbruder(null);
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
this.getLogger().info("User " + (loggedOutBundesbruder != null ? loggedOutBundesbruder.getUserName() : "\"null\"") + " logged out!");
this.authenticationBean.removeSession(this.getValueFromCookie(this.COOKIE_SESSION_KEY), this.getValueFromCookie(this.COOKIE_USER_NAME));
Map<String, Object> cookieProperties = new HashMap<String, Object>();
// cookie will expire NOW
cookieProperties.put("maxAge", new Integer(0));
FacesContext.getCurrentInstance().getExternalContext().addResponseCookie(this.COOKIE_USER_NAME, "", cookieProperties);
FacesContext.getCurrentInstance().getExternalContext().addResponseCookie(this.COOKIE_SESSION_KEY, "", cookieProperties);
this.getLogger().fine(
"Session cookie was removed from client, for user " + (loggedOutBundesbruder != null ? loggedOutBundesbruder.getUserName() : "\"null\""));
return "home";
}
/**
* @param loggedInBundesbruder
* the loggedInBundesbruder to set
*/
public void setLoggedInBundesbruder(BundesbruderEntity loggedInBundesbruder) {
this.loggedInBundesbruder = loggedInBundesbruder;
}
/**
* @param password
* the password to set
*/
public void setPassword(String password) {
this.password = password;
}
/**
* @param rememberMe
* the rememberMe to set
*/
public void setRememberMe(boolean rememberMe) {
this.rememberMe = rememberMe;
}
/**
* @param userName
* the userName to set
*/
public void setUserName(String userName) {
this.userName = userName;
}
}