package controllers; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import org.apache.commons.lang3.StringUtils; import com.avaje.ebean.Ebean; import play.*; import play.mvc.*; import play.data.*; import static play.data.Form.*; import models.*; import uk.bl.api.PasswordHash; import uk.bl.api.Utils; import views.html.*; public class ApplicationController extends Controller { // -- Authentication public static class Login { public String email; public String password; /** * We only store lowercase emails and transform user input to lowercase for this field. * @return null if authentication ok. */ public String validate() { boolean res = false; try { if (StringUtils.isBlank(email)) { return "Please enter an email"; } if (StringUtils.isBlank(password)) { return "Please enter a password"; } // Logger.debug("validate() inserted password: " + password); String inputPassword = password; // Logger.debug("validate() db hash for email: " + email.toLowerCase()); User user = User.findByEmail(email.toLowerCase()); if (user == null) { return "Invalid email"; } if (user.roles != null && !user.roles.isEmpty() && user.hasRole("closed")) { return "This user account has been closed. Please contact the British Library web archiving team"; } String userPassword = User.findByEmail(email.toLowerCase()).password; Logger.debug("userPassword: " + userPassword + " - " + inputPassword); res = PasswordHash.validatePassword(inputPassword, userPassword); } catch (NoSuchAlgorithmException e) { Logger.debug("validate() no algorithm error: " + e); } catch (InvalidKeySpecException e) { Logger.debug("validate() key specification error: " + e); } if(!res || User.authenticate(email.toLowerCase(), User.findByEmail(email.toLowerCase()).password) == null) { return "Password not recognised"; } Logger.debug("res: " + res); return null; } } /** * Login page. */ public static Result login() { // If user is already logged in, redirect to the homepage: String email = session().get("email"); User user = User.findByEmail(email); if (user != null) { return redirect( routes.ApplicationController.index() ); } // Redirect to login page (embedding the flash scope url to redirect to afterwards): return ok( login.render(form(Login.class)) ); } /** * Handle login form submission. * We only store lowercase emails and transform user input to lowercase for this field. */ public static Result authenticate() { // Grab the url to redirect to after login: DynamicForm requestData = Form.form().bindFromRequest(); String url = ""; if( requestData.data().containsKey("redirectToUrl")) { url = requestData.get("redirectToUrl"); } // Parse the login: Form<Login> loginForm = form(Login.class).bindFromRequest(); if(loginForm.hasErrors()) { flash().put("url", url); return badRequest(login.render(loginForm)); } else { session("email", loginForm.get().email.toLowerCase()); Logger.debug("The redirectToUrl is: " + url); User user = User.findByEmail(session().get("email")); if (user != null) { user.lastLogin = Utils.INSTANCE.getCurrentTimeStamp(); Ebean.update(user); } if( StringUtils.isBlank(url) ) url = routes.ApplicationController.home().url(); return redirect( url ); } } /** * Logout and clean the session. */ public static Result logout() { session().clear(); flash("success", "You've been logged out"); return redirect( routes.ApplicationController.login() ); } /** * Display the About tab. */ @Security.Authenticated(SecuredController.class) public static Result index() { String email = session().get("email"); User user = User.findByEmail(email); return ok(about.render("About", user)); } public static String getVersion() { if( Play.isProd() ) { return ApplicationController.class.getPackage().getImplementationVersion(); } else { return Play.application().configuration().getString("application.version"); } } public static Result addContent() { return ok( addcontent.render("AddContent", User.findByEmail(request().username())) ); } public static Result findContent() { return ok( findcontent.render("FindContent", User.findByEmail(request().username())) ); } // -- Javascript routing public static Result javascriptRoutes() { response().setContentType("text/javascript"); return ok( Routes.javascriptRouter("jsRoutes", controllers.routes.javascript.ApplicationController.index(), controllers.routes.javascript.CollectionController.index(), controllers.routes.javascript.InstanceController.index(), controllers.routes.javascript.TargetController.index(), controllers.routes.javascript.OrganisationController.index(), controllers.routes.javascript.UserController.index(), controllers.routes.javascript.ContactController.index() ) ); } @Security.Authenticated(SecuredController.class) public static Result home() { String email = session().get("email"); User user = User.findByEmail(email); if (user.ddhaptUser && getDDHAPTStatus()) return redirect(routes.WatchedTargets.overview(0, "target.title", "asc")); else return redirect(routes.ApplicationController.index()); } public static boolean getDDHAPTStatus(){ Boolean ddhaptStatus = Play.application().configuration().getBoolean("enableDDHAPT"); return ddhaptStatus; } //Redirect urls with trailing "/" to the url they intended public static Result untrail(String path) { // We've already removed the trailing "/", so if there's still one (or more) there, // there's a danger of too many redirects, so let's just 404 in case somebody's playing silly browsers if (path.charAt(path.length() -1 ) == '/') return notFound("Sorry, that page does not exist."); else { return movedPermanently(Play.application().configuration().getString("application.context") + "/" + path); //HTTP 301 } } }