blob: e8c308a5935ca435ae9bef6d7e5e9e95cc64c195 [file] [log] [blame]
/*
* 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 ) );
}
}
}