/** * 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; } }