dde authorization rules and authorized album.
authorErik Brakkee <erik@brakkee.org>
Sat, 14 Sep 2013 22:45:19 +0000 (00:45 +0200)
committerErik Brakkee <erik@brakkee.org>
Sat, 14 Sep 2013 22:45:19 +0000 (00:45 +0200)
Not working yet because authorized album is not serializable.

src/main/java/META-INF/persistence.xml
src/main/java/org/wamblee/photos/model/authorization/AuthorizedAlbum.java
src/main/java/org/wamblee/photos/model/plumbing/Producer.java
src/main/java/org/wamblee/photos/security/PageAuthorizationRule.java [new file with mode: 0644]
src/main/java/org/wamblee/photos/wicket/HomePage.java

index df1adabf61ba5cf1ccefe14a30b859ac36ad3d25..168625156e3096cf7aef889c3506c6f483245d6b 100644 (file)
@@ -22,6 +22,7 @@
       <class>org.wamblee.security.authorization.AbstractAuthorizationRule</class>
       <class>org.wamblee.security.authorization.UrlAuthorizationRule</class>
       <class>org.wamblee.photos.security.PhotoAuthorizationRule</class>
+      <class>org.wamblee.photos.security.PageAuthorizationRule</class>
       
       
       <class>org.wamblee.security.authorization.AbstractAuthorizationService</class>
index 7406d9985f6e5e3308c8fab514a47c3514ecb82b..96610a6c940a92e05967aed7f98bd40579179530 100644 (file)
@@ -19,8 +19,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.logging.Logger;
 
-import org.apache.log4j.Logger;
 import org.wamblee.cache.Cache;
 import org.wamblee.cache.CachedObject;
 import org.wamblee.photos.model.Album;
@@ -39,8 +39,8 @@ import org.wamblee.security.authorization.WriteOperation;
  */
 public class AuthorizedAlbum extends AuthorizedPhotoEntry implements Album {
 
-    private static final Logger LOGGER = Logger
-            .getLogger(AuthorizedAlbum.class);
+    private static final Logger LOGGER = Logger.getLogger(AuthorizedAlbum.class
+        .getName());
 
     private AuthorizationService _authorizer;
 
@@ -55,16 +55,16 @@ public class AuthorizedAlbum extends AuthorizedPhotoEntry implements Album {
      *            Album to decorate.
      */
     public AuthorizedAlbum(Album aAlbum, AuthorizationService aService,
-            Cache aCache, String aSessionId) {
+        Cache aCache, String aSessionId) {
         super(aAlbum);
         _authorizer = aService;
         _authorizedEntries = new CachedObject<String, ArrayList<PhotoEntry>>(
-                aCache, aSessionId + "/" + aAlbum.getPath(),
-                new CachedObject.Computation<String, ArrayList<PhotoEntry>>() {
-                    public ArrayList<PhotoEntry> getObject(String aObjectKey) {
-                        return AuthorizedAlbum.this.compute();
-                    }
-                });
+            aCache, aSessionId + "/" + aAlbum.getPath(),
+            new CachedObject.Computation<String, ArrayList<PhotoEntry>>() {
+                public ArrayList<PhotoEntry> getObject(String aObjectKey) {
+                    return AuthorizedAlbum.this.compute();
+                }
+            });
         _sessionId = aSessionId;
     }
 
@@ -105,10 +105,10 @@ public class AuthorizedAlbum extends AuthorizedPhotoEntry implements Album {
             return (T) new AuthorizedPhoto((Photo) aEntry);
         } else if (aEntry instanceof Album) {
             return (T) new AuthorizedAlbum((Album) aEntry, _authorizer,
-                    _authorizedEntries.getCache(), _sessionId);
+                _authorizedEntries.getCache(), _sessionId);
         } else {
             throw new IllegalArgumentException(
-                    "Entry is neither a photo nor an album: " + aEntry);
+                "Entry is neither a photo nor an album: " + aEntry);
         }
     }
 
@@ -139,8 +139,8 @@ public class AuthorizedAlbum extends AuthorizedPhotoEntry implements Album {
                     return entry;
                 } else {
                     if (!(entry instanceof Album)) {
-                        throw new IllegalArgumentException(getPath() + " "
-                                + aPath);
+                        throw new IllegalArgumentException(getPath() + " " +
+                            aPath);
                     }
                     return ((Album) entry).getEntry(remainder);
                 }
@@ -198,15 +198,15 @@ public class AuthorizedAlbum extends AuthorizedPhotoEntry implements Album {
     public void removeEntry(String aId) throws IOException {
         // Check whether deletion is allowed.
         PhotoEntry entry = _authorizer.check(decorated().getEntry("/" + aId),
-                new DeleteOperation());
+            new DeleteOperation());
         _authorizedEntries.invalidate();
         decorated().removeEntry(aId);
     }
 
     public Photo findPhotoBefore(String aId) {
         Photo entry = decorated().findPhotoBefore(aId);
-        while (entry != null
-                && !_authorizer.isAllowed(entry, new AllOperation())) {
+        while (entry != null &&
+            !_authorizer.isAllowed(entry, new AllOperation())) {
             entry = decorated().findPhotoBefore(entry.getId());
         }
         return decorate(entry);
@@ -214,8 +214,8 @@ public class AuthorizedAlbum extends AuthorizedPhotoEntry implements Album {
 
     public Photo findPhotoAfter(String aId) {
         Photo entry = decorated().findPhotoAfter(aId);
-        while (entry != null
-                && !_authorizer.isAllowed(entry, new AllOperation())) {
+        while (entry != null &&
+            !_authorizer.isAllowed(entry, new AllOperation())) {
             entry = decorated().findPhotoAfter(entry.getId());
         }
         return decorate(entry);
index 9ad3c143fe58d33f58d0cad993271e9e55958e95..4e5b1da7b6a2a1540c3fb9c11bab938993f0dd09 100644 (file)
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.logging.Logger;
 
 import javax.enterprise.context.ApplicationScoped;
 import javax.enterprise.context.SessionScoped;
@@ -28,8 +29,8 @@ import javax.inject.Inject;
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
 
-import org.apache.log4j.Logger;
 import org.wamblee.cache.Cache;
 import org.wamblee.cache.EhCache;
 import org.wamblee.io.ClassPathResource;
@@ -37,19 +38,39 @@ import org.wamblee.io.InputResource;
 import org.wamblee.photos.concurrent.ConcurrentAlbum;
 import org.wamblee.photos.model.Album;
 import org.wamblee.photos.model.PhotoEntry;
+import org.wamblee.photos.model.authorization.AuthorizedAlbum;
 import org.wamblee.photos.model.filesystem.FileSystemAlbum;
+import org.wamblee.photos.security.PageAuthorizationRule;
+import org.wamblee.photos.security.PhotoAuthorizationRule;
+import org.wamblee.photos.wicket.HomePage;
 import org.wamblee.security.authentication.GroupSet;
 import org.wamblee.security.authentication.Md5HexMessageDigester;
 import org.wamblee.security.authentication.MessageDigester;
 import org.wamblee.security.authentication.NameValidator;
 import org.wamblee.security.authentication.RegexpNameValidator;
 import org.wamblee.security.authentication.User;
+import org.wamblee.security.authentication.UserAccessor;
 import org.wamblee.security.authentication.UserAdminInitializer;
 import org.wamblee.security.authentication.UserAdministration;
 import org.wamblee.security.authentication.UserAdministrationImpl;
 import org.wamblee.security.authentication.UserSet;
 import org.wamblee.security.authentication.jpa.JpaGroupSet;
 import org.wamblee.security.authentication.jpa.JpaUserSet;
+import org.wamblee.security.authorization.AbstractAuthorizationRule;
+import org.wamblee.security.authorization.AllOperation;
+import org.wamblee.security.authorization.AnyUserCondition;
+import org.wamblee.security.authorization.AuthorizationInitializer;
+import org.wamblee.security.authorization.AuthorizationResult;
+import org.wamblee.security.authorization.AuthorizationService;
+import org.wamblee.security.authorization.CreateOperation;
+import org.wamblee.security.authorization.DefaultOperationRegistry;
+import org.wamblee.security.authorization.DeleteOperation;
+import org.wamblee.security.authorization.GroupUserCondition;
+import org.wamblee.security.authorization.Operation;
+import org.wamblee.security.authorization.OperationRegistry;
+import org.wamblee.security.authorization.ReadOperation;
+import org.wamblee.security.authorization.WriteOperation;
+import org.wamblee.security.authorization.jpa.JpaAuthorizationService;
 
 /**
  * @author Erik Brakkee
@@ -65,9 +86,24 @@ public class Producer {
     @Inject
     private HttpServletRequest request;
 
+    @Inject
+    private HttpSession session;
+
     @PersistenceContext
     private EntityManager entityManager;
 
+    // Created by this producer.
+
+    @Inject
+    private UserAdministration userAdmin;
+
+    @Inject
+    private AuthorizationService authorizationService;
+
+    @Inject
+    @AllPhotos
+    private Album allPhotos;
+
     private Configuration getCOnfiguration() {
         LOGGER.info("Initializing configuration");
         Configuration config;
@@ -115,6 +151,47 @@ public class Producer {
         }
     }
 
+    @Produces
+    @ApplicationScoped
+    public AuthorizationService getAuthorizationService() {
+        OperationRegistry registry = new DefaultOperationRegistry(
+            new Operation[] { new AllOperation(), new CreateOperation(),
+                new DeleteOperation(), new ReadOperation(),
+                new WriteOperation() });
+        UserAccessor userAccessor = new UserAccessor() {
+
+            @Override
+            public String getCurrentUser() {
+                Principal principal = request.getUserPrincipal();
+                if (principal == null) {
+                    return null;
+                }
+                return principal.getName();
+            }
+        };
+        AuthorizationService service = new JpaAuthorizationService("DEFAULT",
+            entityManager, userAccessor, userAdmin, 10000);
+
+        AnyUserCondition anyUserCondition = new AnyUserCondition();
+        GroupUserCondition adminUserCondition = new GroupUserCondition(
+            "administrators");
+
+        PhotoAuthorizationRule photoEntryRule = new PhotoAuthorizationRule();
+
+        // Pages that allow access by any authenticated user
+        PageAuthorizationRule anyUserPageRule = new PageAuthorizationRule(
+            AuthorizationResult.GRANTED, anyUserCondition, HomePage.class);
+
+        PageAuthorizationRule adminPageRule = new PageAuthorizationRule(
+            AuthorizationResult.GRANTED, adminUserCondition);
+
+        AuthorizationInitializer initializer = new AuthorizationInitializer(
+            service, new AbstractAuthorizationRule[] { photoEntryRule,
+                anyUserPageRule, adminPageRule });
+
+        return service;
+    }
+
     @Produces
     @ApplicationScoped
     @AllPhotos
@@ -139,10 +216,21 @@ public class Producer {
     @Produces
     @SessionScoped
     @AuthorizedPhotos
-    public Album getAuthorizedPhotos() {
+    public Album getAuthorizedAlbum() {
         LOGGER.info("Initializing authorized photos for current session");
+        try {
+            InputResource cacheConfig = new ClassPathResource(
+                "META-INF/ehcache.xml");
+            Cache<String, User> userCache = new EhCache(cacheConfig, "users");
+            Cache authorizedPhotoCache = new EhCache(cacheConfig, "photos");
 
-        return null;
+            AuthorizedAlbum album = new AuthorizedAlbum(allPhotos,
+                authorizationService, authorizedPhotoCache, session.getId());
+            return album;
+        } catch (IOException e) {
+            throw new RuntimeException("Problem initializing authorized album",
+                e);
+        }
     }
 
     @Produces
diff --git a/src/main/java/org/wamblee/photos/security/PageAuthorizationRule.java b/src/main/java/org/wamblee/photos/security/PageAuthorizationRule.java
new file mode 100644 (file)
index 0000000..b32f5df
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2005 the original author or authors.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wamblee.photos.security;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.wamblee.photos.wicket.BasePage;
+import org.wamblee.security.authorization.AllOperation;
+import org.wamblee.security.authorization.AuthorizationResult;
+import org.wamblee.security.authorization.IsaOperationCondition;
+import org.wamblee.security.authorization.RegexpPathCondition;
+import org.wamblee.security.authorization.UrlAuthorizationRule;
+import org.wamblee.security.authorization.UserCondition;
+
+/**
+ * AUthorization rule for pages.
+ */
+@Entity
+@DiscriminatorValue("PAGE")
+public class PageAuthorizationRule extends UrlAuthorizationRule {
+
+    /**
+     * Type-safe construction of page authorization rule.
+     * 
+     * @param aResult
+     *            Result.
+     * @param aUserCondition
+     *            User condition.
+     * @param aPageList
+     *            A list of page names.
+     */
+    public PageAuthorizationRule(AuthorizationResult aResult,
+        UserCondition aUserCondition, Class<? extends BasePage>... aPageList) {
+        super(aResult, aUserCondition, new RegexpPathCondition(
+            getPageRegex(aPageList)), BasePage.class,
+            new IsaOperationCondition(AllOperation.class));
+    }
+
+    /**
+     * Converts a list of page names into a regular expression for the pages.
+     * 
+     * @param aPageList
+     *            List of pages.
+     * @return Regexp matching any of the given pagenames.
+     */
+    private static String getPageRegex(Class<? extends BasePage>[] aPageList) {
+        String result = "";
+        for (int i = 0; i < aPageList.length; i++) {
+            if (result.length() == 0) {
+                result = "/" + aPageList[i].getSimpleName();
+            } else {
+                result = result + "|/" + aPageList[i].getSimpleName();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Constructor for OR mapping.
+     */
+    protected PageAuthorizationRule() {
+        super();
+    }
+
+    /* (non-Javadoc)
+     * @see org.wamblee.security.authorization.UrlAuthorizationRule#getResourcePath(java.lang.Object)
+     */
+    @Override
+    protected String getResourcePath(Object aResource) {
+        BasePage page = (BasePage) aResource;
+        return "/" + page.getClass().getSimpleName();
+    }
+}
index a6126b7c2cdaaf79ea47b687d1bc3d5c47fa3a67..ccb667034e39cf7bd512dfaada84396f83b280c0 100644 (file)
@@ -44,6 +44,10 @@ public class HomePage extends BasePage {
     @AllPhotos
     private Album album;
 
+    // @Inject
+    // @AuthorizedPhotos
+    // private Album authorized;
+
     /**
      * Constructor that is invoked when page is invoked without a session.
      * 
@@ -68,5 +72,14 @@ public class HomePage extends BasePage {
             System.out.println("Entry " + i + " " + entry.getId() + " " +
                 entry.getPath());
         }
+
+        /*
+        System.out.println("Authorized Entries: " + authorized.size());
+        for (int i = 0; i < authorized.size(); i++) {
+            PhotoEntry entry = authorized.getEntry(i);
+            System.out.println("Entry " + i + " " + entry.getId() + " " +
+                entry.getPath());
+        }
+        */
     }
 }