Skip to content
This repository
  • 3 commits
  • 18 files changed
  • 0 comments
  • 1 contributor
23 app/Global.java
@@ -15,8 +15,14 @@
15 15 */
16 16
17 17 import models.PlayVersion;
  18 +import models.User;
  19 +import models.UserRole;
18 20 import play.Application;
19 21 import play.GlobalSettings;
  22 +import security.RoleDefinitions;
  23 +import services.UserServices;
  24 +
  25 +import java.util.Arrays;
20 26
21 27 /**
22 28 *
@@ -35,5 +41,22 @@ public void onStart(Application application)
35 41 // featured modules can be made sticky to have them stick around for more than 24 hours via admin console - featured modules can also be created from there
36 42 // I'll add this to the wiki later
37 43 // this space for rent
  44 +
  45 + // TODO remove this! It's a development convenience
  46 + if (UserRole.findByRoleName(RoleDefinitions.ADMIN) == null)
  47 + {
  48 + UserRole role = new UserRole();
  49 + role.roleName = RoleDefinitions.ADMIN;
  50 + role.description = "MPO administrator";
  51 + role.save();
  52 + }
  53 +
  54 + if (User.findByUserName("admin") == null)
  55 + {
  56 + new UserServices().createUser("admin",
  57 + "MPO Admin",
  58 + "password",
  59 + Arrays.asList(UserRole.findByRoleName(RoleDefinitions.ADMIN)));
  60 + }
38 61 }
39 62 }
114 app/actions/CurrentUser.java
... ... @@ -1,49 +1,65 @@
1   -/*
2   - * Copyright 2012 The Play! Framework
3   - *
4   - * Licensed under the Apache License, Version 2.0 (the "License");
5   - * you may not use this file except in compliance with the License.
6   - * You may obtain a copy of the License at
7   - *
8   - * http://www.apache.org/licenses/LICENSE-2.0
9   - *
10   - * Unless required by applicable law or agreed to in writing, software
11   - * distributed under the License is distributed on an "AS IS" BASIS,
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   - * See the License for the specific language governing permissions and
14   - * limitations under the License.
15   - */
16   -package actions;
17   -
18   -import models.User;
19   -import play.mvc.Action;
20   -import play.mvc.Http;
21   -import play.mvc.Result;
22   -import utils.StringUtils;
23   -
24   -/**
25   - * @author Steve Chaloner (steve@objectify.be)
26   - */
27   -public class CurrentUser extends Action.Simple
28   -{
29   - @Override
30   - public Result call(Http.Context ctx) throws Throwable
31   - {
32   - String userName = ctx.session().get("userName");
33   - if (!StringUtils.isEmpty(userName))
34   - {
35   - User user = User.findByUserName(userName);
36   - if (user != null)
37   - {
38   - ctx.args.put("user",
39   - user);
40   - }
41   - }
42   - return delegate.call(ctx);
43   - }
44   -
45   - public static User currentUser() {
46   - return (User)Http.Context.current().args.get("user");
47   - }
48   -
49   -}
  1 +/*
  2 + * Copyright 2012 The Play! Framework
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package actions;
  17 +
  18 +import models.User;
  19 +import play.mvc.Action;
  20 +import play.mvc.Http;
  21 +import play.mvc.Result;
  22 +import utils.StringUtils;
  23 +
  24 +/**
  25 + * @author Steve Chaloner (steve@objectify.be)
  26 + */
  27 +public class CurrentUser extends Action.Simple
  28 +{
  29 + @Override
  30 + public Result call(Http.Context ctx) throws Throwable
  31 + {
  32 + accessUser(ctx);
  33 + return delegate.call(ctx);
  34 + }
  35 +
  36 + private static User accessUser(Http.Context ctx)
  37 + {
  38 + User user = (User)ctx.args.get("user");
  39 + if (user == null)
  40 + {
  41 + String userName = ctx.session().get("userName");
  42 + if (!StringUtils.isEmpty(userName))
  43 + {
  44 + user = User.findByUserName(userName);
  45 + if (user != null)
  46 + {
  47 + ctx.args.put("user",
  48 + user);
  49 + }
  50 + }
  51 + }
  52 +
  53 + return user;
  54 + }
  55 +
  56 + public static User currentUser()
  57 + {
  58 + return currentUser(Http.Context.current());
  59 + }
  60 +
  61 + public static User currentUser(Http.Context context)
  62 + {
  63 + return accessUser(context);
  64 + }
  65 +}
3  app/controllers/Categories.java
@@ -16,12 +16,14 @@
16 16 package controllers;
17 17
18 18 import actions.CurrentUser;
  19 +import be.objectify.deadbolt.actions.Restrict;
19 20 import models.Category;
20 21 import models.Module;
21 22 import play.data.Form;
22 23 import play.mvc.Controller;
23 24 import play.mvc.Result;
24 25 import play.mvc.With;
  26 +import security.RoleDefinitions;
25 27 import views.html.admin.categories;
26 28 import views.html.admin.categoryDetails;
27 29
@@ -33,6 +35,7 @@
33 35 * @author Steve Chaloner (steve@obectify.be)
34 36 */
35 37 @With(CurrentUser.class)
  38 +@Restrict(RoleDefinitions.ADMIN)
36 39 public class Categories extends Controller
37 40 {
38 41 public static Result showCategories()
12 app/controllers/Modules.java
@@ -16,6 +16,7 @@
16 16 package controllers;
17 17
18 18 import actions.CurrentUser;
  19 +import be.objectify.deadbolt.actions.RoleHolderPresent;
19 20 import models.BinaryContent;
20 21 import models.Module;
21 22 import models.ModuleVersion;
@@ -42,18 +43,20 @@
42 43 @With(CurrentUser.class)
43 44 public class Modules extends Controller
44 45 {
45   -
  46 + @RoleHolderPresent
46 47 public static Result myModules()
47 48 {
48 49 User currentUser = currentUser();
49 50 return ok(myModules.render(currentUser, Module.ownedBy(currentUser)));
50 51 }
51 52
  53 + @RoleHolderPresent
52 54 public static Result showModuleRegistrationForm()
53 55 {
54 56 return ok(moduleRegistrationForm.render(currentUser(), form(Module.class)));
55 57 }
56 58
  59 + @RoleHolderPresent
57 60 public static Result submitModuleRegistrationForm()
58 61 {
59 62 Form<Module> form = form(Module.class).bindFromRequest();
@@ -70,7 +73,7 @@ public static Result submitModuleRegistrationForm()
70 73 }
71 74 }
72 75
73   -
  76 + @RoleHolderPresent
74 77 public static Result showVersionManagement(String moduleKey)
75 78 {
76 79 Form<ModuleVersion> form = form(ModuleVersion.class);
@@ -81,6 +84,7 @@ public static Result showVersionManagement(String moduleKey)
81 84 form));
82 85 }
83 86
  87 + @RoleHolderPresent
84 88 public static Result uploadNewVersion(String moduleKey)
85 89 {
86 90 Result result;
@@ -140,13 +144,15 @@ public static Result details(String moduleKey)
140 144 moduleVersions));
141 145 }
142 146
143   - // this will have a deadbolt dynamic restriction to ensure the user hasn't voted twice
  147 + // this will have a deadbolt dynamic restriction to ensure the user hasn't voted twice, when request params are available
  148 + @RoleHolderPresent
144 149 public static Result vote(String moduleKey)
145 150 {
146 151 return TODO;
147 152 }
148 153
149 154 // If a user has already rated, then change the rate, don't add a new one
  155 + @RoleHolderPresent
150 156 public static Result rate(String moduleKey,
151 157 int rate)
152 158 {
3  app/controllers/PlayVersions.java
@@ -16,11 +16,13 @@
16 16 package controllers;
17 17
18 18 import actions.CurrentUser;
  19 +import be.objectify.deadbolt.actions.Restrict;
19 20 import models.PlayVersion;
20 21 import play.data.Form;
21 22 import play.mvc.Controller;
22 23 import play.mvc.Result;
23 24 import play.mvc.With;
  25 +import security.RoleDefinitions;
24 26 import views.html.admin.playVersions;
25 27
26 28 import static actions.CurrentUser.currentUser;
@@ -29,6 +31,7 @@
29 31 * @author Steve Chaloner (steve@obectify.be)
30 32 */
31 33 @With(CurrentUser.class)
  34 +@Restrict(RoleDefinitions.ADMIN)
32 35 public class PlayVersions extends Controller
33 36 {
34 37 public static Result showPlayVersions()
8 app/models/AbstractModel.java
@@ -4,13 +4,13 @@
4 4 import javax.persistence.MappedSuperclass;
5 5
6 6 @MappedSuperclass
7   -public abstract class AbstractModel extends play.db.ebean.Model {
8   -
  7 +public abstract class AbstractModel extends play.db.ebean.Model
  8 +{
9 9 @Id
10 10 public Long id;
11 11
12   - public Long getId() {
  12 + public Long getId()
  13 + {
13 14 return id;
14 15 }
15   -
16 16 }
21 app/models/User.java
@@ -15,9 +15,12 @@
15 15 */
16 16 package models;
17 17
18   -import models.security.UserRole;
  18 +import be.objectify.deadbolt.models.Permission;
  19 +import be.objectify.deadbolt.models.Role;
  20 +import be.objectify.deadbolt.models.RoleHolder;
19 21
20 22 import javax.persistence.*;
  23 +import java.util.Collections;
21 24 import java.util.List;
22 25
23 26 /**
@@ -25,7 +28,8 @@
25 28 */
26 29 @Entity
27 30 @Table(name = "MPO_USER")
28   -public class User extends AbstractModel {
  31 +public class User extends AbstractModel implements RoleHolder
  32 +{
29 33
30 34 @Column(nullable = false, length = 40, unique = true)
31 35 public String userName;
@@ -70,4 +74,17 @@ public static User authenticate(String userName,
70 74 .eq("password", password)
71 75 .findUnique();
72 76 }
  77 +
  78 + @Override
  79 + public List<? extends Role> getRoles()
  80 + {
  81 + return roles;
  82 + }
  83 +
  84 + @Override
  85 + public List<? extends Permission> getPermissions()
  86 + {
  87 + // for now, let's go with role-based security. I don't think we need any fine-grained control.
  88 + return Collections.emptyList();
  89 + }
73 90 }
20 app/models/security/UserRole.java → app/models/UserRole.java
@@ -13,9 +13,10 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package models.security;
  16 +package models;
17 17
18 18 import play.db.ebean.Model;
  19 +import be.objectify.deadbolt.models.Role;
19 20
20 21 import javax.persistence.Column;
21 22 import javax.persistence.Entity;
@@ -25,7 +26,7 @@
25 26 * @author Steve Chaloner (steve@objectify.be)
26 27 */
27 28 @Entity
28   -public class UserRole extends Model
  29 +public class UserRole extends Model implements Role
29 30 {
30 31 @Id
31 32 public Long id;
@@ -38,4 +39,19 @@
38 39
39 40 public static final Finder<Long, UserRole> FIND = new Finder<Long, UserRole>(Long.class,
40 41 UserRole.class);
  42 +
  43 + @Override
  44 + public String getRoleName()
  45 + {
  46 + return roleName;
  47 + }
  48 +
  49 + public static UserRole findByRoleName(String roleName)
  50 + {
  51 + return FIND.where()
  52 + .eq("roleName",
  53 + roleName)
  54 + .findUnique();
  55 +
  56 + }
41 57 }
59 app/security/RepoDeadboltHandler.java
... ... @@ -0,0 +1,59 @@
  1 +/*
  2 + * Copyright 2012 The Play! Framework
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package security;
  17 +
  18 +import actions.CurrentUser;
  19 +import be.objectify.deadbolt.DeadboltHandler;
  20 +import be.objectify.deadbolt.DynamicResourceHandler;
  21 +import be.objectify.deadbolt.models.RoleHolder;
  22 +import controllers.Application;
  23 +import controllers.routes;
  24 +import play.core.Router;
  25 +import play.mvc.Http;
  26 +import play.mvc.Result;
  27 +import play.mvc.Results;
  28 +
  29 +/**
  30 + * @author Steve Chaloner
  31 + */
  32 +public class RepoDeadboltHandler extends Results implements DeadboltHandler
  33 +{
  34 + @Override
  35 + public Result beforeRoleCheck(Http.Context context)
  36 + {
  37 + return null;
  38 + }
  39 +
  40 + @Override
  41 + public RoleHolder getRoleHolder(Http.Context context)
  42 + {
  43 + return CurrentUser.currentUser(context);
  44 + }
  45 +
  46 + @Override
  47 + public Result onAccessFailure(Http.Context context,
  48 + String s)
  49 + {
  50 + Http.Context.current.set(context);
  51 + return redirect(routes.Application.index());
  52 + }
  53 +
  54 + @Override
  55 + public DynamicResourceHandler getDynamicResourceHandler(Http.Context context)
  56 + {
  57 + return new RepoDynamicResourceHandler();
  58 + }
  59 +}
52 app/security/RepoDynamicResourceHandler.java
... ... @@ -0,0 +1,52 @@
  1 +/*
  2 + * Copyright 2012 The Play! Framework
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package security;
  17 +
  18 +import be.objectify.deadbolt.AbstractDynamicResourceHandler;
  19 +import be.objectify.deadbolt.DeadboltHandler;
  20 +import be.objectify.deadbolt.DynamicResourceHandler;
  21 +import play.mvc.Http;
  22 +import security.dynamic.AllowToVote;
  23 +
  24 +/**
  25 + * @author Steve Chaloner
  26 + */
  27 +public class RepoDynamicResourceHandler extends AbstractDynamicResourceHandler
  28 +{
  29 + @Override
  30 + public boolean isAllowed(String name,
  31 + String meta,
  32 + DeadboltHandler deadboltHandler,
  33 + Http.Context context)
  34 + {
  35 + boolean allowed = false;
  36 + DynamicResourceHandler handler = null;
  37 + if (AllowToVote.KEY.equals(name))
  38 + {
  39 + handler = new AllowToVote();
  40 + }
  41 +
  42 + if (handler != null)
  43 + {
  44 + allowed = handler.isAllowed(name,
  45 + meta,
  46 + deadboltHandler,
  47 + context);
  48 + }
  49 +
  50 + return allowed;
  51 + }
  52 +}
29 app/security/RoleDefinitions.java
... ... @@ -0,0 +1,29 @@
  1 +/*
  2 + * Copyright 2012 The Play! Framework
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package security;
  17 +
  18 +/**
  19 + * @author Steve Chaloner
  20 + */
  21 +public class RoleDefinitions
  22 +{
  23 + public static final String ADMIN = "admin";
  24 +
  25 + private RoleDefinitions()
  26 + {
  27 + // no-op
  28 + }
  29 +}
57 app/security/dynamic/AllowToVote.java
... ... @@ -0,0 +1,57 @@
  1 +/*
  2 + * Copyright 2012 The Play! Framework
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package security.dynamic;
  17 +
  18 +import be.objectify.deadbolt.AbstractDynamicResourceHandler;
  19 +import be.objectify.deadbolt.DeadboltHandler;
  20 +import models.User;
  21 +import models.Vote;
  22 +import play.Logger;
  23 +import play.mvc.Http;
  24 +import utils.StringUtils;
  25 +
  26 +import java.util.Iterator;
  27 +
  28 +/**
  29 + * @author Steve Chaloner
  30 + */
  31 +public class AllowToVote extends AbstractDynamicResourceHandler
  32 +{
  33 + public static final String KEY = "allowToVote";
  34 +
  35 + @Override
  36 + public boolean isAllowed(String name,
  37 + String meta,
  38 + DeadboltHandler deadboltHandler,
  39 + Http.Context ctx)
  40 + {
  41 + boolean allowed = true;
  42 + if (StringUtils.isEmpty(meta))
  43 + {
  44 + Logger.error("HasVoted required a moduleKey in the meta data");
  45 + }
  46 + else
  47 + {
  48 + User user = (User)deadboltHandler.getRoleHolder(ctx);
  49 + for (Iterator<Vote> iterator = user.votes.iterator(); allowed && iterator.hasNext(); )
  50 + {
  51 + Vote vote = iterator.next();
  52 + allowed = !meta.equals(vote.playModule.key);
  53 + }
  54 + }
  55 + return allowed;
  56 + }
  57 +}
42 app/services/UserServices.java
@@ -16,19 +16,41 @@
16 16 package services;
17 17
18 18 import models.User;
  19 +import models.UserRole;
  20 +
  21 +import java.util.ArrayList;
  22 +import java.util.Collections;
  23 +import java.util.List;
19 24
20 25 /**
21 26 * @author Steve Chaloner (steve@objectify.be)
22 27 */
23   -public class UserServices {
  28 +public class UserServices
  29 +{
  30 +
  31 + public User createUser(String userName,
  32 + String displayName,
  33 + String password)
  34 + {
  35 + return createUser(userName,
  36 + displayName,
  37 + password,
  38 + Collections.<UserRole>emptyList());
  39 + }
24 40
25   - public User createUser(String userName, String displayName, String password) {
26   - User user = new User();
27   - user.userName = userName;
28   - user.displayName = displayName;
29   - user.password = password;
30   - user.accountActive = true;
31   - user.save();
32   - return user;
33   - }
  41 + public User createUser(String userName,
  42 + String displayName,
  43 + String password,
  44 + List<UserRole> roles)
  45 + {
  46 + User user = new User();
  47 + user.userName = userName;
  48 + user.displayName = displayName;
  49 + user.password = password;
  50 + user.accountActive = true;
  51 + user.roles = new ArrayList<UserRole>(roles);
  52 + user.save();
  53 + user.saveManyToManyAssociations("roles");
  54 + return user;
  55 + }
34 56 }
9 app/views/modules/moduleDetails.scala.html
... ... @@ -1,6 +1,7 @@
1 1 @(currentUser: User, module: Module, versions: List[ModuleVersion])
2 2 @import tags.moduleList
3 3 @import utils.StringUtils.isEmpty
  4 +@import be.objectify.deadbolt.views.html._
4 5
5 6 @main(module.name, currentUser) {
6 7
@@ -36,10 +37,14 @@
36 37 <td>Description :</td>
37 38 <td>@module.description</td>
38 39 </tr>
  40 + @dynamic(security.dynamic.AllowToVote.KEY, module.key) {
39 41 <tr>
40   - <td></td>
41   - <td></td>
  42 + <td>Vote: </td>
  43 + <td>
  44 + <a href="@routes.Modules.vote(module.key)">Vote</a>
  45 + </td>
42 46 </tr>
  47 + }
43 48 </table>
44 49 </div>
45 50 <div id="controlArea">
7 app/views/tags/userMenu.scala.html
... ... @@ -1,12 +1,17 @@
1 1 @(currentUser: User)
2 2
  3 +@import be.objectify.deadbolt.views.html._
  4 +@import be.objectify.deadbolt.utils.TemplateUtils._
  5 +
3 6 <div id="news">
4 7 <ul class="wrapper">
5 8 @if(currentUser != null) {
6 9 Hello @currentUser.displayName |
7 10 <a href="@routes.Modules.myModules">My modules</a> |
8 11 <a href="@routes.Modules.showModuleRegistrationForm">Submit a new module</a> |
9   - <a href="@routes.PlayVersions.showPlayVersions">Admin</a> |
  12 + @restrict(la(as("admin"))) {
  13 + <a href="@routes.PlayVersions.showPlayVersions">Admin</a> |
  14 + }
10 15 <a href="@routes.Application.logout">Log out</a>
11 16 } else {
12 17 <li>
4 conf/application.conf
@@ -56,3 +56,7 @@ logger.play=INFO
56 56 # Logger provided to your application:
57 57 logger.application=DEBUG
58 58
  59 +# Security
  60 +deadbolt.handler=security.RepoDeadboltHandler
  61 +deadbolt.cache-user=true
  62 +
1  conf/play.plugins
... ... @@ -0,0 +1 @@
  1 +10000:be.objectify.deadbolt.DeadboltPlugin
4 project/Build.scala
@@ -8,11 +8,11 @@ object ApplicationBuild extends Build {
8 8 val appVersion = "1.0-SNAPSHOT"
9 9
10 10 val appDependencies = Seq(
11   - // Add your project dependencies here,
  11 + "deadbolt-2" %% "deadbolt-2" % "1.1.2"
12 12 )
13 13
14 14 val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
15   - // Add your own project settings here
  15 + resolvers += "Objectify Play Repository" at "http://schaloner.github.com/releases/"
16 16 )
17 17
18 18 }

No commit comments for this range

Something went wrong with that request. Please try again.