You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by ca...@apache.org on 2011/10/26 17:22:04 UTC

svn commit: r1189266 - in /incubator/rave/trunk/rave-components/rave-core/src: main/java/org/apache/rave/portal/security/impl/ main/java/org/apache/rave/portal/service/ main/java/org/apache/rave/portal/service/impl/ test/java/org/apache/rave/portal/sec...

Author: carlucci
Date: Wed Oct 26 15:22:03 2011
New Revision: 1189266

URL: http://svn.apache.org/viewvc?rev=1189266&view=rev
Log:
RAVE-307: RegionWidget ModelPermissionEvaluator and Service Annotations

Applied patch supplied by Venkat Mahadevan

Added:
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluator.java
    incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluatorTest.java
Modified:
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/RegionWidgetService.java
    incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultRegionWidgetService.java

Added: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluator.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluator.java?rev=1189266&view=auto
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluator.java (added)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluator.java Wed Oct 26 15:22:03 2011
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.rave.portal.security.impl;
+
+import org.apache.rave.portal.model.RegionWidget;
+import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.repository.RegionWidgetRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class DefaultRegionWidgetPermissionEvaluator extends AbstractModelPermissionEvaluator<RegionWidget> {
+    private Logger log = LoggerFactory.getLogger(getClass());
+    private RegionWidgetRepository regionWidgetRepository;
+
+    @Autowired
+    public DefaultRegionWidgetPermissionEvaluator(RegionWidgetRepository regionWidgetRepository) {
+        this.regionWidgetRepository = regionWidgetRepository;
+    }
+
+    @Override
+    public Class<RegionWidget> getType() {
+        return RegionWidget.class;
+    }
+
+    /**
+     * Checks to see if the Authentication object has the supplied Permission
+     * on the supplied RegionWidget object.  This method invokes the private hasPermission
+     * function with the trustedDomainObject parameter set to false since we don't
+     * know if the model being passed in was modified in any way from the
+     * actual entity in the database.
+     *
+     * @param authentication the current Authentication object
+     * @param regionWidget   the RegionWidget model object
+     * @param permission     the Permission to check
+     * @return true if the Authentication has the proper permission, false otherwise
+     */
+    @Override
+    public boolean hasPermission(Authentication authentication, RegionWidget regionWidget, Permission permission) {
+        return hasPermission(authentication, regionWidget, permission, false);
+    }
+
+    /**
+     * Checks to see if the Authentication object has the supplied Permission
+     * for the Entity represented by the targetId(entityId) and targetType(model class name).
+     * This method invokes the private hasPermission function with the
+     * trustedDomainObject parameter set to true since we must pull the entity
+     * from the database and are guaranteed a trusted domain object,
+     * before performing our permission checks.
+     *
+     * @param authentication the current Authentication object
+     * @param targetId       the entityId of the model to check, or a RaveSecurityContext object
+     * @param targetType     the class of the model to check
+     * @param permission     the Permission to check
+     * @return true if the Authentication has the proper permission, false otherwise
+     */
+    @Override
+    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Permission permission) {
+        boolean hasPermission = false;
+        if (targetId instanceof RaveSecurityContext) {
+            hasPermission = verifyRaveSecurityContext(authentication, (RaveSecurityContext) targetId);
+        } else {
+            hasPermission = hasPermission(authentication, regionWidgetRepository.get((Long) targetId), permission, true);
+        }
+        return hasPermission;
+    }
+
+    private boolean hasPermission(Authentication authentication, RegionWidget regionWidget, Permission permission, boolean trustedDomainObject) {
+        // this is our container of trusted regionWidget objects that can be re-used
+        // in this method so that the same trusted regionWidget object doesn't have to
+        // be looked up in the repository multiple times
+        List<RegionWidget> trustedRegionWidgetContainer = new ArrayList<RegionWidget>();
+
+        // first execute the AbstractModelPermissionEvaluator's hasPermission function
+        // to see if it allows permission via it's "higher authority" logic
+        if (super.hasPermission(authentication, regionWidget, permission)) {
+            return true;
+        }
+
+        // perform the security logic depending on the Permission type
+        boolean hasPermission = false;
+
+        switch (permission) {
+            case ADMINISTER:
+                // if you are here, you are not an administrator, so you can't administer RegionWidgets
+                break;
+            case CREATE:
+            case DELETE:
+            case READ:
+            case UPDATE:
+                // anyone can create, delete, read, or update a regionWidget that they own
+                hasPermission = isRegionWidgetOwner(authentication, regionWidget, trustedRegionWidgetContainer, trustedDomainObject);
+                break;
+            default:
+                log.warn("unknown permission: " + permission);
+                break;
+        }
+
+        return hasPermission;
+    }
+
+    // returns a trusted RegionWidget object, either from the RegionWidgetRepository, or the
+    // cached container list
+    private RegionWidget getTrustedRegionWidget(long regionWidgetId, List<RegionWidget> trustedRegionWidgetContainer) {
+        RegionWidget regionWidget = null;
+        if (trustedRegionWidgetContainer.isEmpty()) {
+            regionWidget = regionWidgetRepository.get(regionWidgetId);
+            trustedRegionWidgetContainer.add(regionWidget);
+        } else {
+            regionWidget = trustedRegionWidgetContainer.get(0);
+        }
+        return regionWidget;
+    }
+
+    // checks to see if the Authentication object principal is the owner of the supplied regionWidget object
+    // if trustedDomainObject is false, pull the entity from the database first to ensure
+    // the model object is trusted and hasn't been modified
+    private boolean isRegionWidgetOwner(Authentication authentication, RegionWidget regionWidget, List<RegionWidget> trustedRegionWidgetContainer, boolean trustedDomainObject) {
+        RegionWidget trustedRegionWidget = null;
+        if (trustedDomainObject) {
+            trustedRegionWidget = regionWidget;
+        } else {
+            trustedRegionWidget = getTrustedRegionWidget(regionWidget.getEntityId(), trustedRegionWidgetContainer);
+        }
+        return isRegionWidgetOwnerByUsername(authentication, getUsernameFromRegionWidget(trustedRegionWidget));
+    }
+
+    private boolean isRegionWidgetOwnerByUsername(Authentication authentication, String username) {
+        return ((User)authentication.getPrincipal()).getUsername().equals(username);
+    }
+
+    private boolean isRegionWidgetOwnerById(Authentication authentication, Long userId) {
+        return ((User)authentication.getPrincipal()).getEntityId().equals(userId);
+    }
+
+    private boolean verifyRaveSecurityContext(Authentication authentication, RaveSecurityContext raveSecurityContext) {
+        Class<?> clazz = null;
+        try {
+           clazz = Class.forName(raveSecurityContext.getType());
+        } catch (ClassNotFoundException ex) {
+            throw new IllegalArgumentException("unknown class specified in RaveSecurityContext: ", ex);
+        }
+
+        // perform the permissions check based on the class supplied to the RaveSecurityContext object
+        if (User.class == clazz) {
+            return isRegionWidgetOwnerById(authentication, (Long) raveSecurityContext.getId());
+        } else {
+            throw new IllegalArgumentException("unknown RaveSecurityContext type: " + raveSecurityContext.getType());
+        }
+    }
+    
+    private String getUsernameFromRegionWidget(RegionWidget regionWidget) {
+        return regionWidget.getRegion().getPage().getOwner().getUsername();
+    }
+}

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java?rev=1189266&r1=1189265&r2=1189266&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PageService.java Wed Oct 26 15:22:03 2011
@@ -118,7 +118,10 @@ public interface PageService {
      * @param toRegion the id of the Region to move the RegionWidget to
      * @param fromRegion the id of the Region where the RegionWidget currently resides
      * @return the updated RegionWidget
+     * 
+     * TODO: add a second hasPermission clause for toRegion once the RegionPermissionEvaluator has been created
      */
+    @PreAuthorize("hasPermission(#regionWidgetId, 'org.apache.rave.portal.model.RegionWidget', 'update')")
     RegionWidget moveRegionWidget(long regionWidgetId, int newPosition, long toRegion, long fromRegion);
 
     /**
@@ -128,15 +131,20 @@ public interface PageService {
      * @param toPageId the new page to move the regionWidgetTo
      * @return the updated RegionWidget object
      */
+    @PreAuthorize("hasPermission(#regionWidgetId, 'org.apache.rave.portal.model.RegionWidget', 'update') and " +
+                  "hasPermission(#toPageId, 'org.apache.rave.portal.model.Page', 'update')")
     RegionWidget moveRegionWidgetToPage(long regionWidgetId, long toPageId);    
     
     /**
      * Creates a new instance of a widget and adds it to the first position of the first region on the page
-     * @param page_id the id of the page to add the widget to
-     * @param widget_id the {@link org.apache.rave.portal.model.Widget} id to add
+     * @param pageId the id of the page to add the widget to
+     * @param widgetId the {@link org.apache.rave.portal.model.Widget} id to add
      * @return a valid widget instance
+     * 
+     * TODO: add a second hasPermission clause for Widget once the WidgetPermissionEvaluator has been created     
      */
-    RegionWidget addWidgetToPage(long page_id, long widget_id);
+    @PreAuthorize("hasPermission(#pageId, 'org.apache.rave.portal.model.Page', 'update')") 
+    RegionWidget addWidgetToPage(long pageId, long widgetId);
 
     /**
      * Deletes the specified widget from the page.
@@ -144,6 +152,7 @@ public interface PageService {
      * @param regionWidgetId the id of the region widget to delete.\
      * @return the region from which the widget was deleted
      */
+    @PreAuthorize("hasPermission(#regionWidgetId, 'org.apache.rave.portal.model.RegionWidget', 'delete')")
     Region removeWidgetFromPage(long regionWidgetId);
 
     /**

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/RegionWidgetService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/RegionWidgetService.java?rev=1189266&r1=1189265&r2=1189266&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/RegionWidgetService.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/RegionWidgetService.java Wed Oct 26 15:22:03 2011
@@ -21,6 +21,8 @@ package org.apache.rave.portal.service;
 
 import org.apache.rave.portal.model.RegionWidget;
 import org.apache.rave.portal.model.RegionWidgetPreference;
+import org.springframework.security.access.prepost.PostAuthorize;
+import org.springframework.security.access.prepost.PreAuthorize;
 
 import java.util.List;
 
@@ -31,6 +33,7 @@ public interface RegionWidgetService {
      * @param regionWidgetId The ID of the RegionWidget to fetch.
      * @return The RegionWidget or null if not found.
      */
+    @PostAuthorize("hasPermission(returnObject, 'read')")
     RegionWidget getRegionWidget(long regionWidgetId);
 
     /**
@@ -39,6 +42,7 @@ public interface RegionWidgetService {
      * @param regionWidget The RegionWidget to save.
      * @return The updated RegionWidget with all ID numbers populated.
      */
+    @PreAuthorize("hasPermission(#regionWidget.regionWidgetId, 'org.apache.rave.portal.model.RegionWidget', 'update')")
     RegionWidget saveRegionWidget(RegionWidget regionWidget);
 
     /**
@@ -48,6 +52,7 @@ public interface RegionWidgetService {
      * @param preferences    The collection of new RegionWidgetPreferences.
      * @return The updated RegionWidgetPreferences with all ID numbers populated.
      */
+    @PreAuthorize("hasPermission(#regionWidgetId, 'org.apache.rave.portal.model.RegionWidget', 'update')")
     List<RegionWidgetPreference> saveRegionWidgetPreferences(long regionWidgetId,
                                                              List<RegionWidgetPreference> preferences);
 
@@ -59,6 +64,7 @@ public interface RegionWidgetService {
      * @param preference     The RegionWidgetPreference to save.
      * @return The updated RegionWidgetPreference with all ID numbers populated.
      */
+    @PreAuthorize("hasPermission(#regionWidgetId, 'org.apache.rave.portal.model.RegionWidget', 'update')")
     RegionWidgetPreference saveRegionWidgetPreference(long regionWidgetId, RegionWidgetPreference preference);
     
     /**
@@ -68,5 +74,6 @@ public interface RegionWidgetService {
      * @param collapsed the collapsed state of the RegionWidget
      * @return The updated RegionWidget with the new collapsed value
      */
+    @PreAuthorize("hasPermission(#regionWidgetId, 'org.apache.rave.portal.model.RegionWidget', 'update')")
     RegionWidget saveRegionWidgetCollapsedState(long regionWidgetId, boolean collapsed);
 }
\ No newline at end of file

Modified: incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultRegionWidgetService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultRegionWidgetService.java?rev=1189266&r1=1189265&r2=1189266&view=diff
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultRegionWidgetService.java (original)
+++ incubator/rave/trunk/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultRegionWidgetService.java Wed Oct 26 15:22:03 2011
@@ -49,12 +49,14 @@ public class DefaultRegionWidgetService 
     }
 
     @Override
+    @Transactional
     public RegionWidget saveRegionWidget(RegionWidget regionWidget) {
         return regionWidgetRepository.save(regionWidget);
     }
 
     @Override
     @Synchronized(discriminator = "'RegionWidget'", id = "#regionWidgetId")
+    @Transactional
     public List<RegionWidgetPreference> saveRegionWidgetPreferences(long regionWidgetId,
                                                                     List<RegionWidgetPreference> preferences) {
         RegionWidget regionWidget = this.getValidRegionWidget(regionWidgetId);
@@ -65,6 +67,7 @@ public class DefaultRegionWidgetService 
 
     @Override
     @Synchronized(discriminator = "'RegionWidget'", id = "#regionWidgetId")
+    @Transactional
     public RegionWidgetPreference saveRegionWidgetPreference(long regionWidgetId, RegionWidgetPreference preference) {
         RegionWidget regionWidget = this.getValidRegionWidget(regionWidgetId);
         ModelUtils.normalizeRegionWidgetPreference(regionWidgetId, preference);

Added: incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluatorTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluatorTest.java?rev=1189266&view=auto
==============================================================================
--- incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluatorTest.java (added)
+++ incubator/rave/trunk/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluatorTest.java Wed Oct 26 15:22:03 2011
@@ -0,0 +1,333 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.rave.portal.security.impl;
+
+import org.apache.rave.portal.model.Page;
+import org.apache.rave.portal.model.Region;
+import org.apache.rave.portal.model.RegionWidget;
+import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.repository.RegionWidgetRepository;
+import org.apache.rave.portal.security.ModelPermissionEvaluator.Permission;
+import org.apache.rave.portal.security.util.AuthenticationUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.GrantedAuthorityImpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class DefaultRegionWidgetPermissionEvaluatorTest {
+    private DefaultRegionWidgetPermissionEvaluator defaultRegionWidgetPermissionEvaluator;
+    private RegionWidgetRepository mockRegionWidgetRepository;
+    private Authentication mockAuthentication;
+    private Page page;
+    private RegionWidget regionWidget;
+    private Region region;
+    private User user, user2;
+    private List<GrantedAuthority> grantedAuthoritiesList;
+
+    private final Long VALID_REGION_ID = 1L;
+    private final Long VALID_REGION_WIDGET_ID = 1L;
+    private final Long VALID_PAGE_ID = 3L;
+    private final Long VALID_USER_ID = 99L;
+    private final String VALID_USERNAME = "john.doe";
+    private final String VALID_USERNAME2 = "jane.doe";
+
+    @Before
+    public void setUp() {
+        mockRegionWidgetRepository = createMock(RegionWidgetRepository.class);
+        defaultRegionWidgetPermissionEvaluator = new DefaultRegionWidgetPermissionEvaluator(mockRegionWidgetRepository);
+        mockAuthentication = createMock(Authentication.class);
+
+        user = new User();
+        user.setUsername(VALID_USERNAME);
+        user.setEntityId(VALID_USER_ID);
+        user2 = new User();
+        user2.setUsername(VALID_USERNAME2);
+        page = new Page();
+        page.setEntityId(VALID_PAGE_ID);
+        page.setOwner(user);
+        region = new Region();
+        region.setEntityId(VALID_REGION_ID);
+        region.setPage(page);
+        regionWidget = new RegionWidget();
+        regionWidget.setEntityId(VALID_REGION_WIDGET_ID);
+        regionWidget.setRegion(region);
+        grantedAuthoritiesList = new ArrayList<GrantedAuthority>();
+        grantedAuthoritiesList.add(new GrantedAuthorityImpl("ROLE_USER"));
+    }
+
+    @Test
+    public void testGetType() throws ClassNotFoundException {
+        assertThat(defaultRegionWidgetPermissionEvaluator.getType().getName(), is(RegionWidget.class.getName()));
+    }
+
+    @Test
+    public void testHasPermission_3args_administer() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        replay(mockAuthentication);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.ADMINISTER), is(false));
+        verify(mockAuthentication);
+    }
+
+    @Test
+    public void testHasPermission_3args_administer_hasAdminRole() {
+        grantedAuthoritiesList.add(new GrantedAuthorityImpl(AuthenticationUtils.ROLE_ADMIN));
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        replay(mockAuthentication);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.ADMINISTER), is(true));
+        verify(mockAuthentication);
+    }
+
+    @Test
+    public void testHasPermission_3args_create_isRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.CREATE), is(true));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_3args_create_isNotRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.CREATE), is(false));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_3args_delete_isRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.DELETE), is(true));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_3args_delete_isNotRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.DELETE), is(false));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_3args_update_isRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.UPDATE), is(true));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_3args_update_isNotRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.UPDATE), is(false));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_3args_read_isRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.READ), is(true));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_3args_read_isNotRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, regionWidget, Permission.READ), is(false));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_4args_administer() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        replay(mockAuthentication);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_WIDGET_ID, RegionWidget.class.getName(), Permission.ADMINISTER), is(false));
+        verify(mockAuthentication);
+    }
+
+    @Test
+    public void testHasPermission_4args_create_isRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_WIDGET_ID, RegionWidget.class.getName(), Permission.CREATE), is(true));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_4args_create_isNotRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_WIDGET_ID, RegionWidget.class.getName(), Permission.CREATE), is(false));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_4args_delete_isRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_WIDGET_ID, RegionWidget.class.getName(), Permission.CREATE), is(true));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_4args_delete_isNotRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_WIDGET_ID, RegionWidget.class.getName(), Permission.CREATE), is(false));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_4args_read_isRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_WIDGET_ID, RegionWidget.class.getName(), Permission.CREATE), is(true));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_4args_read_isNotRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_WIDGET_ID, RegionWidget.class.getName(), Permission.CREATE), is(false));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_4args_update_isRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_WIDGET_ID, RegionWidget.class.getName(), Permission.CREATE), is(true));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_4args_update_isNotRegionWidgetOwner() {
+        expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);
+        replay(mockAuthentication);
+        replay(mockRegionWidgetRepository);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_WIDGET_ID, RegionWidget.class.getName(), Permission.CREATE), is(false));
+        verify(mockAuthentication);
+        verify(mockRegionWidgetRepository);
+    }
+
+    @Test
+    public void testHasPermission_4args_update_isRegionWidgetOwner_withRaveSecurityContextObject() {
+        RaveSecurityContext raveSecurityContext = new RaveSecurityContext(VALID_USER_ID, "org.apache.rave.portal.model.User");
+
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        replay(mockAuthentication);
+        assertThat(defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, raveSecurityContext, RegionWidget.class.getName(), Permission.UPDATE), is(true));
+        verify(mockAuthentication);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testHasPermission_4args_update_isRegionWidgetOwner_withInvalidRaveSecurityContextType() {
+        RaveSecurityContext raveSecurityContext = new RaveSecurityContext(VALID_USER_ID, "java.lang.String");
+
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        replay(mockAuthentication);
+        defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, raveSecurityContext, RegionWidget.class.getName(), Permission.UPDATE);
+        verify(mockAuthentication);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testHasPermission_4args_update_isRegionWidgetOwner_withUnknownRaveSecurityContextType() {
+        RaveSecurityContext raveSecurityContext = new RaveSecurityContext(VALID_USER_ID, "foo.bar.DummyClass");
+
+        expect(mockAuthentication.getPrincipal()).andReturn(user);
+        replay(mockAuthentication);
+        defaultRegionWidgetPermissionEvaluator.hasPermission(mockAuthentication, raveSecurityContext, RegionWidget.class.getName(), Permission.UPDATE);
+        verify(mockAuthentication);
+    }
+}