diff --git a/account/pom.xml b/account/pom.xml index 87b29f3..586e6ee 100644 --- a/account/pom.xml +++ b/account/pom.xml @@ -22,11 +22,6 @@ - - org.apache.shiro - shiro-core - 1.2.4 - commons-lang commons-lang @@ -37,6 +32,24 @@ freemarker 2.3.23 + + org.apache.shiro + shiro-core + 1.2.4 + provided + + + org.apache.shiro + shiro-web + 1.2.4 + provided + + + de.muehlencord.shared + shared-jeeutil + 1.0-SNAPSHOT + jar + javax javaee-api diff --git a/account/src/main/java/de/muehlencord/shared/account/ui/LoginView.java b/account/src/main/java/de/muehlencord/shared/account/ui/LoginView.java new file mode 100644 index 0000000..de0a939 --- /dev/null +++ b/account/src/main/java/de/muehlencord/shared/account/ui/LoginView.java @@ -0,0 +1,146 @@ +package de.muehlencord.shared.account.ui; + +import de.muehlencord.shared.account.business.account.AccountControl; +import de.muehlencord.shared.account.entity.AccountEntity; +import de.muehlencord.shared.jeeutil.FacesUtil; +import java.io.IOException; +import java.io.Serializable; +import javax.ejb.EJB; +import javax.faces.context.ExternalContext; +import javax.faces.context.FacesContext; +import javax.faces.view.ViewScoped; +import javax.inject.Named; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.web.util.WebUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author joern.muehlencord + */ +@Named(value = "loginView") +@ViewScoped +public class LoginView implements Serializable { + + @EJB + private AccountControl accountService; + + private String username = null; + private String password = null; + private boolean rememberMe = false; + + private String resetPasswordToken = null; + + private static final Logger LOGGER = LoggerFactory.getLogger(LoginView.class.getName()); + + public void authenticate() { + + // Example using most common scenario of username/password pair: + UsernamePasswordToken token = new UsernamePasswordToken(getUsername(), getPassword()); + + // "Remember Me" built-in: + token.setRememberMe(rememberMe); + + Subject currentUser = SecurityUtils.getSubject(); + + LOGGER.info("Submitting login with username of " + username); + + try { + currentUser.login(token); + // user logged in, update account entity + AccountEntity account = accountService.getAccountEntity(username, true); + accountService.updateLogin(account); + + // redirect to home + ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); + String fallbackUrl = "/web/index.xhtml"; + // ec.redirect(url); + WebUtils.redirectToSavedRequest((ServletRequest) ec.getRequest(), (ServletResponse) ec.getResponse(), fallbackUrl); + } catch (IOException | AuthenticationException e) { + // Could catch a subclass of AuthenticationException if you like + String hint = "Error while authenticating user " + username; + LOGGER.error(hint + "Reason: " + e.toString()); + FacesUtil.addErrorMessage("Login failed"); + + AccountEntity account = accountService.getAccountEntity(username, false); + if (account != null) { + accountService.addLoginError(account); + } + } finally { + token.clear(); + } + } + + public void logout() { + Subject currentUser = SecurityUtils.getSubject(); + try { + currentUser.logout(); + + ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); + String url = ec.getRequestContextPath() + "/login.xhtml"; + ec.redirect(url); + + } catch (Exception e) { + LOGGER.warn(e.toString()); + } + } + + public String executePasswordReset() { + boolean passwordResetted = accountService.resetPassword(username, password, resetPasswordToken); + if (passwordResetted) { + // TODO add email notification on updated user account + FacesUtil.addInfoMessage ("Password resetted"); + return login(); + } else { + // TODO add email notificaton on failed password reset + FacesUtil.addErrorMessage("Password reset failed"); + return login(); + } + } + + /* **** naviation rules **** */ + public String login() { + return "/login.xhtml"; // TODO make configurable + } + + /* *** getter / setter */ + public String getUsername() { + return username; + } + + public void setUsername(String un) { + this.username = un; + } + + public String getPassword() { + return password; + } + + public void setPassword(String pw) { + this.password = pw; + } + + public boolean isRememberMe() { + return rememberMe; + } + + public void setRememberMe(boolean rememberMe) { + this.rememberMe = rememberMe; + } + + public String getResetPasswordToken() { + return resetPasswordToken; + } + + public void setResetPasswordToken(String resetPasswordToken) { + this.resetPasswordToken = resetPasswordToken; + } + +} diff --git a/account/src/main/java/de/muehlencord/shared/account/ui/LostPasswordView.java b/account/src/main/java/de/muehlencord/shared/account/ui/LostPasswordView.java new file mode 100644 index 0000000..0388355 --- /dev/null +++ b/account/src/main/java/de/muehlencord/shared/account/ui/LostPasswordView.java @@ -0,0 +1,46 @@ +package de.muehlencord.shared.account.ui; + +import de.muehlencord.shared.account.business.account.AccountControl; +import de.muehlencord.shared.jeeutil.FacesUtil; +import java.io.Serializable; +import javax.ejb.EJB; +import javax.faces.view.ViewScoped; +import javax.inject.Named; + +/** + * + * @author joern@muehlencord.de + */ +@Named (value = "lostPasswordView") +@ViewScoped +public class LostPasswordView implements Serializable { + + @EJB + private AccountControl accountService; + + private String userName; + private boolean passwordResetStarted = false; + + public String initPasswordReset() { + if (accountService.initPasswordReset(userName)) { + passwordResetStarted = true; + FacesUtil.addInfoMessage("Password reset started, please check your email account"); + } else { + FacesUtil.addErrorMessage("Error while resetting password. Please contact your administrator"); + } + return "/login.xhtml"; // TODO make configurable, get from LoginView? + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public boolean getPasswordResetStarted() { + return passwordResetStarted; + } + +}