ISIS-290: shiro security + integration into example app

Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/f81b824e
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/f81b824e
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/f81b824e

Branch: refs/heads/master
Commit: f81b824e3d4838d249000d3e1812176b329ecf7d
Parents: 4ceaab8
Author: Dan Haywood <danhayw...@apache.org>
Authored: Thu Jan 3 16:51:18 2013 +0000
Committer: Dan Haywood <danhayw...@apache.org>
Committed: Fri Jan 4 09:23:19 2013 +0000

----------------------------------------------------------------------
 .../shiro/ShiroAuthenticatorOrAuthorizor.java      |   79 ++++++---------
 ...hiroSecurityManagerThreadLocalBinderFilter.java |    2 +-
 .../wicket/ui/pages/login/WicketSignInPage.html    |    2 +-
 .../src/main/resources/images/Default.png          |  Bin 3016 -> 0 bytes
 .../main/java/fixture/todo/ToDoItemsFixture.java   |   26 +++++
 .../fixture/todo/ToDoItemsFixturesService.java     |   22 ++++-
 .../src/main/resources/images/Default.png          |  Bin 3016 -> 0 bytes
 .../src/main/webapp/WEB-INF/isis.properties        |    5 +-
 .../src/main/webapp/WEB-INF/shiro.ini              |   21 +++-
 9 files changed, 100 insertions(+), 57 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/f81b824e/component/security/shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
----------------------------------------------------------------------
diff --git 
a/component/security/shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
 
b/component/security/shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
index 3507870..5c79e11 100644
--- 
a/component/security/shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
+++ 
b/component/security/shiro/src/main/java/org/apache/isis/security/shiro/ShiroAuthenticatorOrAuthorizor.java
@@ -74,11 +74,6 @@ public class ShiroAuthenticatorOrAuthorizor implements 
Authenticator, Authorizor
 
     private final IsisConfiguration configuration;
 
-    private SecurityManager shiroSecurityManager;
-    /**
-     * Downcast of {@link #shiroSecurityManager} (if of this type).
-     */
-    private RealmSecurityManager realmSecurityManager;
 
     // //////////////////////////////////////////////////////
     // constructor
@@ -94,50 +89,28 @@ public class ShiroAuthenticatorOrAuthorizor implements 
Authenticator, Authorizor
 
     @Override
     public void init() {
-        this.shiroSecurityManager = getSecurityManager(configuration);
-        if(shiroSecurityManager instanceof RealmSecurityManager) {
-            this.realmSecurityManager = (RealmSecurityManager) 
shiroSecurityManager;
-        }
     }
 
     /**
      * The {@link SecurityManager} is shared between both the {@link 
Authenticator} and the {@link Authorizor}
      * (if shiro is configured for both components).
      */
-    private static synchronized SecurityManager getSecurityManager(final 
IsisConfiguration configuration) {
+    private static synchronized RealmSecurityManager getSecurityManager() {
+        SecurityManager securityManager;
         try {
-            return (DefaultSecurityManager) SecurityUtils.getSecurityManager();
+            securityManager = SecurityUtils.getSecurityManager();
         } catch(UnavailableSecurityManagerException ex) {
-            String shiroIniLocation = lookupIniLocationFrom(configuration);
-
-            Factory<SecurityManager> factory = new 
IniSecurityManagerFactory(shiroIniLocation);
-            SecurityManager securityManager = factory.getInstance();
-            SecurityUtils.setSecurityManager(securityManager);
-            return securityManager;
-        }
-    }
-
-    private static String lookupIniLocationFrom(final IsisConfiguration 
configuration) {
-        String configuredValue;
-        
-        configuredValue = 
configuration.getString("isis.security.shiro.iniLocation");
-        if(configuredValue != null) {
-            return configuredValue;
-        }
-        configuredValue = 
configuration.getString("isis.authentication.shiro.iniLocation");
-        if(configuredValue != null) {
-            return configuredValue;
+            return null;
         }
-        configuredValue = 
configuration.getString("isis.authorization.shiro.iniLocation");
-        if(configuredValue != null) {
-            return configuredValue;
+        if(!(securityManager instanceof RealmSecurityManager)) {
+            return null;
         }
-        return "classpath:shiro.ini";
+        return (RealmSecurityManager) securityManager;
     }
 
+
     @Override
     public void shutdown() {
-        //
     }
 
     // //////////////////////////////////////////////////////
@@ -146,11 +119,18 @@ public class ShiroAuthenticatorOrAuthorizor implements 
Authenticator, Authorizor
 
     @Override
     public final boolean canAuthenticate(final Class<? extends 
AuthenticationRequest> authenticationRequestClass) {
+        if(getSecurityManager() == null) {
+            return false;
+        }
         return 
AuthenticationRequestPassword.class.isAssignableFrom(authenticationRequestClass);
     }
 
     @Override
     public AuthenticationSession authenticate(final AuthenticationRequest 
request, final String code) {
+        RealmSecurityManager securityManager = getSecurityManager();
+        if(securityManager == null) {
+            return null;
+        }
         final AuthenticationToken token = asAuthenticationToken(request);
         
         Subject currentUser = SecurityUtils.getSubject();
@@ -183,16 +163,22 @@ public class ShiroAuthenticatorOrAuthorizor implements 
Authenticator, Authorizor
         }
         
         List<String> roles = getRoles(token);
+        // copy over any roles passed in
+        // (this is used by the Wicket viewer, for example).s
+        roles.addAll(request.getRoles());
         
         return new SimpleSession(request.getName(), roles, code);
     }
 
     private List<String> getRoles(final AuthenticationToken token) {
-        if(realmSecurityManager == null) {
-            return Collections.emptyList();
-        }
         final List<String> roles = Lists.newArrayList();
-        final Collection<Realm> realms = realmSecurityManager.getRealms();
+
+        RealmSecurityManager securityManager = getSecurityManager();
+        if(securityManager == null) {
+            return roles;
+        }
+        
+        final Collection<Realm> realms = securityManager.getRealms();
         for (final Realm realm : realms) {
             if(realm.supports(token)) {
                 continue;
@@ -241,22 +227,23 @@ public class ShiroAuthenticatorOrAuthorizor implements 
Authenticator, Authorizor
     }
 
     private boolean isPermitted(Identifier identifier, String qualifier) {
-        if(realmSecurityManager == null) {
-            // cannot do permission checking if the security manager is not a 
RealmSecurityManager
+        RealmSecurityManager securityManager = getSecurityManager();
+        if(securityManager == null) {
+            // cannot do permission checking if no security manager
             return false;
         }
 
         String permission = asPermissionsString(identifier) + ":" + qualifier;
 
-        PrincipalCollection principals = 
SecurityUtils.getSubject().getPrincipals();
-        return realmSecurityManager.isPermitted(principals, permission);
+        Subject subject = SecurityUtils.getSubject();
+        return subject.isPermitted(permission);
     }
 
-    private String asPermissionsString(Identifier identifier) {
-        String packageName;
-        String className;
+    private static String asPermissionsString(Identifier identifier) {
         String fullyQualifiedClassName = identifier.getClassName();
         int lastDot = fullyQualifiedClassName.lastIndexOf('.');
+        String packageName;
+        String className;
         if(lastDot > 0) {
             packageName =fullyQualifiedClassName.substring(0, lastDot);
             className = fullyQualifiedClassName.substring(lastDot+1);

http://git-wip-us.apache.org/repos/asf/isis/blob/f81b824e/component/security/shiro/src/main/java/org/apache/isis/security/shiro/web/IsisShiroSecurityManagerThreadLocalBinderFilter.java
----------------------------------------------------------------------
diff --git 
a/component/security/shiro/src/main/java/org/apache/isis/security/shiro/web/IsisShiroSecurityManagerThreadLocalBinderFilter.java
 
b/component/security/shiro/src/main/java/org/apache/isis/security/shiro/web/IsisShiroSecurityManagerThreadLocalBinderFilter.java
index d08b70f..2e47443 100644
--- 
a/component/security/shiro/src/main/java/org/apache/isis/security/shiro/web/IsisShiroSecurityManagerThreadLocalBinderFilter.java
+++ 
b/component/security/shiro/src/main/java/org/apache/isis/security/shiro/web/IsisShiroSecurityManagerThreadLocalBinderFilter.java
@@ -31,7 +31,7 @@ public class IsisShiroSecurityManagerThreadLocalBinderFilter 
implements Filter {
         SecurityManager securityManager = webEnvironment.getSecurityManager();
         ThreadContext.bind(securityManager);
         try {
-            doFilter(request, response, chain);
+            chain.doFilter(request, response);
         } finally {
             ThreadContext.unbindSecurityManager();
         }

http://git-wip-us.apache.org/repos/asf/isis/blob/f81b824e/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/WicketSignInPage.html
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/WicketSignInPage.html
 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/WicketSignInPage.html
index b85e5cb..a9be742 100644
--- 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/WicketSignInPage.html
+++ 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/login/WicketSignInPage.html
@@ -34,7 +34,7 @@
                <div id="container" class="wicketSignInPanel">
                        <div class="headerContainer">
                                <div id="header">
-                                       <h1><span 
wicket:id="applicationName">[application name]</span></h1>
+                                       <h1><span wicket:id="applicationName" 
class="applicationName">[application name]</span></h1>
                                </div>
                                <div class="clear"/>
                        </div>

http://git-wip-us.apache.org/repos/asf/isis/blob/f81b824e/example/application/claims/viewer-wicket/src/main/resources/images/Default.png
----------------------------------------------------------------------
diff --git 
a/example/application/claims/viewer-wicket/src/main/resources/images/Default.png
 
b/example/application/claims/viewer-wicket/src/main/resources/images/Default.png
deleted file mode 100644
index 8409e46..0000000
Binary files 
a/example/application/claims/viewer-wicket/src/main/resources/images/Default.png
 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/isis/blob/f81b824e/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixture.java
----------------------------------------------------------------------
diff --git 
a/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixture.java
 
b/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixture.java
index cfa0e1d..4c4adf7 100644
--- 
a/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixture.java
+++ 
b/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixture.java
@@ -21,6 +21,7 @@ package fixture.todo;
 
 import java.util.List;
 
+import org.apache.isis.applib.annotation.Named;
 import org.apache.isis.applib.clock.Clock;
 import org.apache.isis.applib.fixtures.AbstractFixture;
 import org.joda.time.LocalDate;
@@ -45,18 +46,43 @@ public class ToDoItemsFixture extends AbstractFixture {
         getContainer().flush();
     }
 
+    public void installFor(String user) {
+
+        removeAllToDosFor(user);
+
+        createToDoItemForUser("Buy milk", Category.Domestic, user, 
daysFromToday(0));
+        createToDoItemForUser("Buy stamps", Category.Domestic, user, 
daysFromToday(0));
+        createToDoItemForUser("Pick up laundry", Category.Other, user, 
daysFromToday(6));
+        createToDoItemForUser("Write blog post", Category.Professional, user, 
null);
+        createToDoItemForUser("Organize brown bag", Category.Professional, 
user, daysFromToday(14));
+
+        getContainer().flush();
+    }
+
     // {{ helpers
     private void removeAllToDosForCurrentUser() {
+        
         final List<ToDoItem> allToDos = toDoItems.allToDos();
         for (final ToDoItem toDoItem : allToDos) {
             getContainer().remove(toDoItem);
         }
     }
 
+    private void removeAllToDosFor(String user) {
+        final List<ToDoItem> items = allMatches(ToDoItem.class, 
ToDoItem.thoseOwnedBy(user));
+        for (final ToDoItem toDoItem : items) {
+            getContainer().remove(toDoItem);
+        }
+    }
+
     private ToDoItem createToDoItemForCurrentUser(final String description, 
final Category category, final LocalDate dueBy) {
         return toDoItems.newToDo(description, category, dueBy);
     }
 
+    private ToDoItem createToDoItemForUser(final String description, final 
Category category, String user, final LocalDate dueBy) {
+        return toDoItems.newToDo(description, category, user, dueBy);
+    }
+
     private static LocalDate daysFromToday(final int i) {
         final LocalDate date = new LocalDate(Clock.getTimeAsDateTime());
         return date.plusDays(i);

http://git-wip-us.apache.org/repos/asf/isis/blob/f81b824e/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
----------------------------------------------------------------------
diff --git 
a/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
 
b/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
index 65cca69..ab61a37 100644
--- 
a/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
+++ 
b/example/application/quickstart_wicket_restful_jdo/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
@@ -19,11 +19,15 @@
 
 package fixture.todo;
 
-import dom.todo.ToDoItems;
+import java.util.List;
 
 import org.apache.isis.applib.AbstractService;
 import org.apache.isis.applib.annotation.Named;
 
+import com.google.common.collect.Lists;
+
+import dom.todo.ToDoItems;
+
 /**
  * Enables fixtures to be installed from the application.
  */
@@ -38,8 +42,22 @@ public class ToDoItemsFixturesService extends 
AbstractService {
         return "Example fixtures installed";
     }
 
-    private ToDoItems toDoItems;
+    public String installFor(@Named("User") String user) {
+        final ToDoItemsFixture fixture = new ToDoItemsFixture();
+        fixture.setContainer(getContainer());
+        fixture.setToDoItems(toDoItems);
+        fixture.installFor(user);
+        return "Example fixtures installed for " + user;
+    }
+    public String default0InstallFor() {
+        return "guest";
+    }
+    public List<String> choices0InstallFor() {
+        return Lists.newArrayList("guest", "dick", "bob", "joe");
+    }
 
+    
+    private ToDoItems toDoItems;
     public void setToDoItems(final ToDoItems toDoItems) {
         this.toDoItems = toDoItems;
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/f81b824e/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/resources/images/Default.png
----------------------------------------------------------------------
diff --git 
a/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/resources/images/Default.png
 
b/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/resources/images/Default.png
deleted file mode 100644
index 8409e46..0000000
Binary files 
a/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/resources/images/Default.png
 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/isis/blob/f81b824e/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties
----------------------------------------------------------------------
diff --git 
a/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties
 
b/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties
index 7c84ae6..4556efd 100644
--- 
a/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties
+++ 
b/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/isis.properties
@@ -80,8 +80,9 @@ isis.persistor=datanucleus
 # 
  
 # default is file in SERVER mode, none in SERVER_EXPLORATION.  Derived from 
wicket mode 
+
+#isis.authentication=bypass
 
isis.authentication=org.apache.isis.security.shiro.authentication.ShiroAuthenticationManagerInstaller
-isis.authentication.shiro.iniLocation=classpath:shiro.ini
 
 
 #
@@ -96,7 +97,7 @@ isis.authentication.shiro.iniLocation=classpath:shiro.ini
  
 # default is file in SERVER mode, none in SERVER_EXPLORATION.  Derived from 
wicket mode 
 #isis.authorization=file
-
+isis.authorization=org.apache.isis.security.shiro.authorization.ShiroAuthorizationManagerInstaller
 
 
 #

http://git-wip-us.apache.org/repos/asf/isis/blob/f81b824e/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/shiro.ini
----------------------------------------------------------------------
diff --git 
a/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/shiro.ini
 
b/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/shiro.ini
index bc605c7..3aac276 100644
--- 
a/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/shiro.ini
+++ 
b/example/application/quickstart_wicket_restful_jdo/viewer-webapp/src/main/webapp/WEB-INF/shiro.ini
@@ -28,11 +28,11 @@
 [users]
 # user = password, role1, role2, role3, ...
 
-sven = pass, org.apache.isis.viewer.wicket.roles.USER, admin
-dick = pass, org.apache.isis.viewer.wicket.roles.USER, admin
-bob  = pass, org.apache.isis.viewer.wicket.roles.USER, admin
-joe  = pass, org.apache.isis.viewer.wicket.roles.USER, admin
-
+sven = pass, admin
+dick = pass, user
+bob  = pass, user
+joe  = pass, user
+guest = guest, guest
 
 
 
@@ -47,3 +47,14 @@ joe  = pass, org.apache.isis.viewer.wicket.roles.USER, admin
 # role = perm1, perm2, perm3, ...
 
 admin = *
+user = *:ToDoItemsJdo:*:*,\
+       *:ToDoItemJdo:*:*,\
+       *:ToDoItemsFixturesService:install:*
+guest = *:ToDoItemsJdo:notYetComplete:*,\
+        *:ToDoItemsJdo:complete:*,\
+        *:ToDoItemsJdo:similarTo:*,\
+        *:ToDoItemsJdo:newToDo:r,\
+        *:ToDoItem:*:r,\
+        *:ToDoItem:completed:*,\
+        *:ToDoItem:notYetCompleted:r
+        
\ No newline at end of file

Reply via email to