| /* |
| * 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.usergrid.security; |
| |
| |
| import java.util.UUID; |
| |
| import org.junit.AfterClass; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.apache.usergrid.management.UserInfo; |
| import org.apache.usergrid.persistence.entities.User; |
| import org.apache.usergrid.security.shiro.CustomPermission; |
| import org.apache.usergrid.security.shiro.principals.ApplicationUserPrincipal; |
| import org.apache.usergrid.utils.UUIDUtils; |
| |
| import org.apache.shiro.SecurityUtils; |
| import org.apache.shiro.UnavailableSecurityManagerException; |
| import org.apache.shiro.mgt.DefaultSecurityManager; |
| import org.apache.shiro.subject.SimplePrincipalCollection; |
| import org.apache.shiro.subject.Subject; |
| import org.apache.shiro.subject.support.SubjectThreadState; |
| import org.apache.shiro.util.LifecycleUtils; |
| import org.apache.shiro.util.ThreadState; |
| |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| |
| |
| public class CustomResolverTest { |
| |
| public static final Logger logger = LoggerFactory.getLogger( CustomResolverTest.class ); |
| |
| private static ThreadState subjectThreadState; |
| |
| |
| @BeforeClass |
| public static void setSecurityManager() { |
| DefaultSecurityManager manager = new DefaultSecurityManager(); |
| SecurityUtils.setSecurityManager( manager ); |
| } |
| |
| |
| @AfterClass |
| public static void tearDownShiro() { |
| doClearSubject(); |
| |
| try { |
| org.apache.shiro.mgt.SecurityManager securityManager = SecurityUtils.getSecurityManager(); |
| LifecycleUtils.destroy( securityManager ); |
| } |
| catch ( UnavailableSecurityManagerException e ) { |
| // we don't care about this when cleaning up the test environment |
| // (for example, maybe the subclass is a unit test and it didn't |
| // need a SecurityManager instance because it was using only |
| // mock Subject instances) |
| } |
| SecurityUtils.setSecurityManager( null ); |
| } |
| |
| |
| private static void doClearSubject() { |
| if ( subjectThreadState != null ) { |
| subjectThreadState.clear(); |
| subjectThreadState = null; |
| } |
| } |
| |
| |
| /** |
| * Allows subclasses to set the currently executing {@link Subject} instance. |
| * |
| * @param subject the Subject instance |
| */ |
| protected void setSubject( Subject subject ) { |
| doClearSubject(); |
| subjectThreadState = new SubjectThreadState( subject ); |
| subjectThreadState.bind(); |
| } |
| |
| |
| @Test |
| public void testResolver() throws Exception { |
| |
| testImplies( true, "applications:get:00000000-0000-0000-0000-000000000001:/foo", |
| "applications:get:00000000-0000-0000-0000-000000000001:/foo" ); |
| |
| testImplies( true, "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/*", |
| "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar" ); |
| |
| testImplies( true, "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/*", |
| "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/baz" ); |
| |
| testImplies( false, "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/*", |
| "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/baz/" ); |
| |
| testImplies( false, "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/*", |
| "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/baz/boz" ); |
| |
| testImplies( true, "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/**", |
| "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/baz/boz" ); |
| |
| testImplies( true, "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/*/boz/*", |
| "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/baz/boz" ); |
| |
| testImplies( true, "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/*/boz/*", |
| "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/baz/boz/biz" ); |
| |
| testImplies( true, "applications:get:00000000-0000-0000-0000-000000000001:/bar/*/boz/*", |
| "applications:get:00000000-0000-0000-0000-000000000001:/bar/3b270ee0-a2d7-11e2-b8ac-f14ec968db08/boz" |
| + "/b53761a-a2d7-11e2-abbb-11f6def11e98" ); |
| |
| testImplies( false, "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/*/boz/*", |
| "applications:get:00000000-0000-0000-0000-000000000001:/foo/bar/baz/boz/biz/box" ); |
| } |
| |
| |
| @Test |
| public void userMeSubstitution() { |
| User fakeUser = new User(); |
| fakeUser.setUuid( UUIDUtils.newTimeUUID() ); |
| fakeUser.setUsername( "testusername" ); |
| |
| UUID appId = UUIDUtils.newTimeUUID(); |
| |
| UserInfo info = new UserInfo( appId, fakeUser.getProperties() ); |
| |
| |
| ApplicationUserPrincipal principal = new ApplicationUserPrincipal( appId, info ); |
| Subject subject = new Subject.Builder( SecurityUtils.getSecurityManager() ) |
| .principals( new SimplePrincipalCollection( principal, "usergrid" ) ).buildSubject(); |
| |
| setSubject( subject ); |
| |
| testImplies( true, "/users/mefake@usergrid.org/**", "/users/mefake@usergrid.org/permissions" ); |
| |
| //test substitution |
| testImplies( true, "/users/me/**", String.format( "/users/%s/permissions", fakeUser.getUsername() ) ); |
| |
| testImplies( true, "/users/me/**", String.format( "/users/%s/permissions", fakeUser.getUuid() ) ); |
| } |
| |
| |
| public void testImplies( boolean expected, String s1, String s2 ) { |
| CustomPermission p1 = new CustomPermission( s1 ); |
| CustomPermission p2 = new CustomPermission( s2 ); |
| if ( expected ) { |
| assertTrue( p1.implies( p2 ) ); |
| } |
| else { |
| assertFalse( p1.implies( p2 ) ); |
| } |
| } |
| } |