package controllers; import managers.AccountManager; import models.Account; import models.Login; import models.enums.AccountRole; import models.services.LdapService; import play.Logger; import play.api.i18n.Lang; import play.data.Form; import play.data.FormFactory; import play.db.jpa.Transactional; import play.i18n.MessagesApi; import play.mvc.Result; import views.html.landingpage; import javax.inject.Inject; import java.util.Random; /** * Controller for authenticate purposes. */ @Transactional public class AccountController extends BaseController { final Logger.ALogger LOG = Logger.of(AccountController.class); private final AccountManager accountManager; private final FormFactory formFactory; private final LdapService ldapService; private final MessagesApi messagesApi; @Inject public AccountController(AccountManager accountManager, FormFactory formFactory, LdapService ldapService, MessagesApi messagesApi) { this.accountManager = accountManager; this.formFactory = formFactory; this.ldapService = ldapService; this.messagesApi = messagesApi; } /** * Default authentication action. * * @return Result */ public Result authenticate() { Form<Login> form = formFactory.form(Login.class).bindFromRequest(); String username = form.field("email").value(); // save originURL before clearing the session (it gets cleared in defaultAuthenticate() and LdapAuthenticate()) String redirect = session().get("originURL"); LOG.info("Login attempt from: " + username); LOG.info("Redirecting to " + redirect); if (username.contains("@")) { return emailAuthenticate(redirect); } else if (username.length() == 0) { LOG.info("... no name given"); flash("error", "Also deine Matrikelnummer brauchen wir schon!"); return badRequest(landingpage.render(form)); } else { return ldapAuthenticate(redirect); } } /** * LDAP authentication. * * @return Result */ private Result ldapAuthenticate(final String redirect) { Form<Login> form = formFactory.form(Login.class).bindFromRequest(); String matriculationNumber = form.field("email").value(); String password = form.field("password").value(); String rememberMe = form.field("rememberMe").value(); // Clean the username matriculationNumber = matriculationNumber.trim().toLowerCase(); try { ldapService.connect(matriculationNumber, password); } catch (LdapService.LdapConnectorException e) { flash("error", e.getMessage()); Component.addToContext(Component.ContextIdent.loginForm, form); return badRequest(landingpage.render(form)); } // try to find user in DB, set role if found (default STUDENT role) Account account = accountManager.findByLoginName(matriculationNumber); AccountRole role = AccountRole.STUDENT; if (ldapService.getRole() != null) { role = ldapService.getRole(); } // if user is not found in DB, create new user from LDAP data, otherwise update user data if (account == null) { LOG.info("... not found. Creating new Account for: " + matriculationNumber); account = new Account(); account.firstname = ldapService.getFirstName(); account.lastname = ldapService.getLastName(); account.loginname = matriculationNumber; account.password = "LDAP - not needed"; Random generator = new Random(); account.avatar = String.valueOf(generator.nextInt(9)); account.role = role; accountManager.create(account); } else { account.firstname = ldapService.getFirstName(); account.lastname = ldapService.getLastName(); account.role = role; accountManager.update(account); } // re-create session, set user session().clear(); session("id", account.id.toString()); if (rememberMe != null) { session("rememberMe", "1"); } LOG.info("Welcome, " + account.name); return redirect(redirect); } /** * Mail authentication. * * @return Result */ private Result emailAuthenticate(final String redirect) { Form<Login> loginForm = formFactory.form(Login.class).bindFromRequest(); Login login = loginForm.get(); if (!accountManager.isAccountValid(login.email, login.password)) { LOG.info("User/Password not valid"); flash("error", "Bitte melde dich mit deiner Matrikelnummer an."); Component.addToContext(Component.ContextIdent.loginForm, loginForm); return badRequest(landingpage.render(loginForm)); } else { Account account = accountManager.findByEmail(login.email); session().clear(); session("email", loginForm.get().email); session("id", account.id.toString()); session("firstname", account.firstname); if (loginForm.get().rememberMe != null) { session("rememberMe", "1"); } LOG.info("Welcome, " + account.name); return redirect(redirect); } } /** * Checks if the specified password is correct for the current used * * @param accountId the account which password should be checked * @param password the password to check * @return true, if the password is correct */ public boolean checkPassword(Long accountId, String password) { Account account = accountManager.findById(accountId); if (password == null || password.length() == 0) { flash("error", messagesApi.get(Lang.defaultLang(), "Kein Passwort angegeben!")); return false; } if (account.loginname == null || account.loginname.length() == 0) { // not an LDAP Account if (accountManager.isAccountValid(account.email, password)) { flash("error", messagesApi.get(Lang.defaultLang(), "profile.delete.wrongpassword")); return false; } else { return true; } } else { // LDAP Account try { ldapService.connect(account.loginname, password); // try logging in with the specified password return true; // login successful } catch (LdapService.LdapConnectorException e) { flash("error", e.getMessage()); return false; } } } /** * Logout and clean the session. */ public Result logout() { LOG.info("Bye, " + session().get("email")); session().clear(); flash("success", messagesApi.get(Lang.defaultLang(), "authenticate.logout")); return redirect(controllers.routes.Application.index()); } }