Skip to content
This repository was archived by the owner on Feb 10, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ github-buttons
test-env.sh
repo
.idea
/.project
1 change: 1 addition & 0 deletions samples/java/hibernate/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: target/start -Dhttp.port=${PORT} -Dplay.version=2.3.6 -DapplyEvolutions.default=true -DapplyDownEvolutions.default=true -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url=$DATABASE_URL ${JAVA_OPTS}
28 changes: 28 additions & 0 deletions samples/java/hibernate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Play Authenticate sample Java application for JPA/Hibernate

Authentication providers that require further configuration parameters
are commented out in `conf/play.plugins`. Please review the configuration
in `conf/play-authenticate/mine.conf` and reenable them if you want to
use them.

Example of play authentication using Hibernate and MySql

Play version: 2.4.2
play authenticate: 0.7.0-SNAPSHOT
MySQL

This implementation does not use a managed entity manager, the developer is responsable
for closing db connections unless using @Transactional in controllers. There are some compatibility issues using this
implementation with @Transactional, deadbolt and the hibernate dao objects. So its best advised to avoid using @Transactional.

So every time you use

EntityManager em = JPA.em(JPAConstants.DB);

You need to call

em.close(); in the same function before all return statements/exceptions or you could have a connection leak.

Hibernate has been setup to use MySql, you'll need to adjust the application.conf to match your database. Hibernate will create all
the tables automatically for you when you first run the app, but you need to create the schema/database using phphMyAdmin etc.
There is a MySql workbench project file that has the cascading setup if needed (schema.mwb).
94 changes: 94 additions & 0 deletions samples/java/hibernate/app/Global.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import java.util.Arrays;

import javax.persistence.EntityManager;

import models.SecurityRole;

import com.feth.play.module.pa.PlayAuthenticate;
import com.feth.play.module.pa.PlayAuthenticate.Resolver;
import com.feth.play.module.pa.exceptions.AccessDeniedException;
import com.feth.play.module.pa.exceptions.AuthException;

import constants.JpaConstants;
import controllers.routes;
import dao.SecurityRoleHome;
import play.Application;
import play.GlobalSettings;
import play.db.jpa.JPA;
import play.mvc.Call;

public class Global extends GlobalSettings {

@Override
public void onStart(Application app) {
PlayAuthenticate.setResolver(new Resolver() {

@Override
public Call login() {
// Your login page
return routes.Application.login();
}

@Override
public Call afterAuth() {
// The user will be redirected to this page after authentication
// if no original URL was saved
return routes.Application.index();
}

@Override
public Call afterLogout() {
return routes.Application.index();
}

@Override
public Call auth(String provider) {
// You can provide your own authentication implementation,
// however the default should be sufficient for most cases
return com.feth.play.module.pa.controllers.routes.AuthenticateDI.authenticate(provider);
}

@Override
public Call askMerge() {
return routes.Account.askMerge();
}

@Override
public Call askLink() {
return routes.Account.askLink();
}

@Override
public Call onException(AuthException e) {
if (e instanceof AccessDeniedException) {
return routes.Signup
.oAuthDenied(((AccessDeniedException) e)
.getProviderKey());
}

// more custom problem handling here...
return super.onException(e);
}
});

initialData();
}

private void initialData() {

EntityManager em = JPA.em(JpaConstants.DB);

SecurityRoleHome dao = new SecurityRoleHome();

if (!dao.hasInitialData(em)) {
for (String roleName : Arrays
.asList(controllers.Application.USER_ROLE)) {
SecurityRole role = new SecurityRole();
role.setRoleName(roleName);
dao.persist(role, em);
}
}

em.close();
}
}
8 changes: 8 additions & 0 deletions samples/java/hibernate/app/constants/JpaConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package constants;

public final class JpaConstants {
public static final String DB = "default";

private JpaConstants(){
}
}
228 changes: 228 additions & 0 deletions samples/java/hibernate/app/controllers/Account.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
package controllers;

import javax.persistence.EntityManager;

import models.User;
import be.objectify.deadbolt.java.actions.Restrict;
import be.objectify.deadbolt.java.actions.Group;
import be.objectify.deadbolt.java.actions.SubjectPresent;

import com.feth.play.module.pa.PlayAuthenticate;
import com.feth.play.module.pa.user.AuthUser;

import constants.JpaConstants;
import dao.UserHome;
import play.data.Form;
import play.data.format.Formats.NonEmpty;
import play.data.validation.Constraints.MinLength;
import play.data.validation.Constraints.Required;
import play.db.jpa.JPA;
import play.i18n.Messages;
import play.mvc.Controller;
import play.mvc.Result;
import providers.MyUsernamePasswordAuthProvider;
import providers.MyUsernamePasswordAuthUser;
import views.html.account.*;
import static play.data.Form.form;

public class Account extends Controller {

public static class Accept {

@Required
@NonEmpty
public Boolean accept;

public Boolean getAccept() {
return accept;
}

public void setAccept(Boolean accept) {
this.accept = accept;
}

}

public static class PasswordChange {
@MinLength(5)
@Required
public String password;

@MinLength(5)
@Required
public String repeatPassword;

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getRepeatPassword() {
return repeatPassword;
}

public void setRepeatPassword(String repeatPassword) {
this.repeatPassword = repeatPassword;
}

public String validate() {
if (password == null || !password.equals(repeatPassword)) {
return Messages
.get("playauthenticate.change_password.error.passwords_not_same");
}
return null;
}
}

private static final Form<Accept> ACCEPT_FORM = form(Accept.class);
private static final Form<Account.PasswordChange> PASSWORD_CHANGE_FORM = form(Account.PasswordChange.class);

@SubjectPresent
public Result link() {
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
return ok(link.render());
}

@Restrict(@Group(Application.USER_ROLE))
public Result verifyEmail() {
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
User user = Application.getLocalUser(session());
if (user.getEmailValidated()) {
// E-Mail has been validated already
flash(Application.FLASH_MESSAGE_KEY,
Messages.get("playauthenticate.verify_email.error.already_validated"));
} else if (user.getEmail() != null && !user.getEmail().trim().isEmpty()) {
flash(Application.FLASH_MESSAGE_KEY, Messages.get(
"playauthenticate.verify_email.message.instructions_sent",
user.getEmail()));
MyUsernamePasswordAuthProvider.getProvider()
.sendVerifyEmailMailingAfterSignup(user, ctx());
} else {
flash(Application.FLASH_MESSAGE_KEY, Messages.get(
"playauthenticate.verify_email.error.set_email_first",
user.getEmail()));
}
return redirect(routes.Application.profile());
}

@Restrict(@Group(Application.USER_ROLE))
public Result changePassword() {
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
User u = Application.getLocalUser(session());

if (!u.getEmailValidated()) {
return ok(unverified.render());
} else {
return ok(password_change.render(PASSWORD_CHANGE_FORM));
}
}

@Restrict(@Group(Application.USER_ROLE))
public Result doChangePassword() {
EntityManager em = JPA.em(JpaConstants.DB);
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
Form<Account.PasswordChange> filledForm = PASSWORD_CHANGE_FORM
.bindFromRequest();
if (filledForm.hasErrors()) {
// User did not select whether to link or not link
em.close();
return badRequest(password_change.render(filledForm));
} else {
User user = Application.getLocalUser(session());
String newPassword = filledForm.get().password;

UserHome userDao = new UserHome();

userDao.changePassword(user, new MyUsernamePasswordAuthUser(newPassword), true, em);
em.close();
flash(Application.FLASH_MESSAGE_KEY,
Messages.get("playauthenticate.change_password.success"));
return redirect(routes.Application.profile());
}
}

@SubjectPresent
public Result askLink() {
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
AuthUser u = PlayAuthenticate.getLinkUser(session());
if (u == null) {
// account to link could not be found, silently redirect to login
return redirect(routes.Application.index());
}
return ok(ask_link.render(ACCEPT_FORM, u));
}

@SubjectPresent
public Result doLink() {
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
AuthUser u = PlayAuthenticate.getLinkUser(session());
if (u == null) {
// account to link could not be found, silently redirect to login
return redirect(routes.Application.index());
}

Form<Accept> filledForm = ACCEPT_FORM.bindFromRequest();
if (filledForm.hasErrors()) {
// User did not select whether to link or not link
return badRequest(ask_link.render(filledForm, u));
} else {
// User made a choice :)
boolean link = filledForm.get().accept;
if (link) {
flash(Application.FLASH_MESSAGE_KEY,
Messages.get("playauthenticate.accounts.link.success"));
}
return PlayAuthenticate.link(ctx(), link);
}
}

@SubjectPresent
public Result askMerge() {
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
// this is the currently logged in user
AuthUser aUser = PlayAuthenticate.getUser(session());

// this is the user that was selected for a login
AuthUser bUser = PlayAuthenticate.getMergeUser(session());
if (bUser == null) {
// user to merge with could not be found, silently redirect to login
return redirect(routes.Application.index());
}

// You could also get the local user object here via
// User.findByAuthUserIdentity(newUser)
return ok(ask_merge.render(ACCEPT_FORM, aUser, bUser));
}

@SubjectPresent
public Result doMerge() {
com.feth.play.module.pa.controllers.Authenticate.noCache(response());
// this is the currently logged in user
AuthUser aUser = PlayAuthenticate.getUser(session());

// this is the user that was selected for a login
AuthUser bUser = PlayAuthenticate.getMergeUser(session());
if (bUser == null) {
// user to merge with could not be found, silently redirect to login
return redirect(routes.Application.index());
}

Form<Accept> filledForm = ACCEPT_FORM.bindFromRequest();
if (filledForm.hasErrors()) {
// User did not select whether to merge or not merge
return badRequest(ask_merge.render(filledForm, aUser, bUser));
} else {
// User made a choice :)
boolean merge = filledForm.get().accept;
if (merge) {
flash(Application.FLASH_MESSAGE_KEY,
Messages.get("playauthenticate.accounts.merge.success"));
}
return PlayAuthenticate.merge(ctx(), merge);
}
}

}
Loading