/** * Copyright 2011 meltmedia * * 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.xchain.namespaces.hibernate.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.security.Principal; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.commons.jxpath.JXPathContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.criterion.Projections; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.xchain.Catalog; import org.xchain.framework.hibernate.CriteriaEntityPermission; import org.xchain.framework.hibernate.EntityOperation; import org.xchain.framework.hibernate.EntityPermission; import org.xchain.framework.hibernate.HibernateLifecycle; import org.xchain.framework.hibernate.HqlEntityPermission; import org.xchain.framework.lifecycle.Lifecycle; import org.xchain.framework.lifecycle.LifecycleClass; import org.xchain.framework.lifecycle.StartThreadStep; import org.xchain.framework.lifecycle.StopThreadStep; import org.xchain.framework.lifecycle.ThreadContext; import org.xchain.framework.lifecycle.ThreadLifecycle; import org.xchain.framework.security.DefaultIdentityService; import org.xchain.framework.security.Identity; import org.xchain.framework.security.IdentityImpl; import org.xchain.framework.security.IdentityManager; import org.xchain.framework.security.IdentityService; import org.xchain.framework.security.Permission; import org.xchain.framework.security.SecurityManager; import org.xchain.framework.security.UsernamePrincipal; import org.xchain.namespaces.hibernate.test.om.User; import org.xchain.namespaces.hibernate.test.om.UserNote; /** * @author Jason Rose * @author Josh Kennedy */ public class TestQualifiedEntityPermission extends BaseDatabaseTest { public static final Logger log = LoggerFactory.getLogger(TestQualifiedEntityPermission.class); protected JXPathContext context = null; protected ThreadContext threadContext = null; protected Catalog catalog = null; @BeforeClass public static void setupCommand() throws Exception { Lifecycle.startLifecycle(); populateUserData(); populateUserNoteData(); } @AfterClass public static void teardownCommand() throws Exception { Lifecycle.stopLifecycle(); } @Before public void setupTest() throws Exception { // create the context. context = JXPathContext.newContext(new Object()); threadContext = new TestThreadContext(); ThreadLifecycle.getInstance().startThread(threadContext); } @After public void teardownTest() throws Exception { context = null; catalog = null; ThreadLifecycle.getInstance().stopThread(threadContext); threadContext = null; } @Test public void testGetEntityClass() throws Exception { CriteriaEntityPermission p = new CriteriaEntityPermission(EntityOperation.ALL, UserNote.class, null, null, null, null, null); assertEquals(UserNote.class, p.getEntityClass()); } @Test public void testNotEntityPermission() throws Exception { CriteriaEntityPermission p = new CriteriaEntityPermission(EntityOperation.ALL, UserNote.class, null, null, null, null, null); IdentityManager.instance().loggedIn(new UsernamePrincipal(userList.get(0).getUsername())); Permission notEntityPermission = new Permission() { public boolean implies(Permission permission) {return true;}; }; try { SecurityManager.instance().checkPermission(notEntityPermission); fail(); } catch (SecurityException e) { } try { IdentityManager.instance().getIdentity().getPermissions().add(p); SecurityManager.instance().checkPermission(notEntityPermission); fail(); } catch (Exception e) { } } @Test public void testEntityNotAssignable() throws Exception { Session session = HibernateLifecycle.getCurrentSession(); IdentityManager.instance().loggedIn(new UsernamePrincipal(userList.get(0).getUsername())); UserNote instance = (UserNote) userList.get(0).getUserNoteSet().toArray()[0]; Transaction t = session.beginTransaction(); Criteria notesCriteria = session.createCriteria(UserNote.class); notesCriteria.setProjection(Projections.projectionList().add(Projections.count("text"))); CriteriaEntityPermission p = new CriteriaEntityPermission(EntityOperation.LOAD, UserNote.class, notesCriteria, null, null, null, null); EntityPermission<User> instancePermission = new EntityPermission<User>(EntityOperation.LOAD, instance.getId(), userList.get(0)); try { SecurityManager.instance().checkPermission(instancePermission); fail(); } catch (SecurityException e) { } try { IdentityManager.instance().getIdentity().getPermissions().add(p); SecurityManager.instance().checkPermission(instancePermission); fail(); } catch (Exception e) { } t.rollback(); } @Test public void testPermissionNotImplied() throws Exception { Session session = HibernateLifecycle.getCurrentSession(); IdentityManager.instance().loggedIn(new UsernamePrincipal(userList.get(0).getUsername())); UserNote instance = (UserNote) userList.get(0).getUserNoteSet().toArray()[0]; Transaction t = session.beginTransaction(); Criteria notesCriteria = session.createCriteria(UserNote.class); notesCriteria.setProjection(Projections.projectionList().add(Projections.count("text"))); CriteriaEntityPermission p = new CriteriaEntityPermission(EntityOperation.LOAD, UserNote.class, notesCriteria, null, null, null, null); EntityPermission<UserNote> instancePermission = new EntityPermission<UserNote>(EntityOperation.UPDATE, instance.getId(), instance); try { SecurityManager.instance().checkPermission(instancePermission); fail(); } catch (SecurityException e) { } try { IdentityManager.instance().getIdentity().getPermissions().add(p); SecurityManager.instance().checkPermission(instancePermission); fail(); } catch (Exception e) { } t.rollback(); } @Test public void testProcessResult() throws Exception { HibernateLifecycle.getCurrentSession().beginTransaction(); final String noResultHql = String.format("select count(entity) from %s entity where entity.id = :id and 0=1", UserNote.class.getName()); final String arrayResultHql = String.format("select entity.id, entity.text from %s entity where entity.id = :id", UserNote.class.getName()); final String booleanResultHql = String.format("select new java.lang.Boolean('false') from %s entity where entity.id = :id", UserNote.class.getName()); final String booleanResultHql2 = String.format("select new java.lang.Boolean('true') from %s entity where entity.id = :id", UserNote.class.getName()); final String integerResultHql = String.format("select count(entity) from %s entity where entity.id = :id", UserNote.class.getName()); final String longResultHql = String.format("select entity.id from %s entity where entity.id = :id", UserNote.class.getName()); final String objectResultHql = String.format("select entity from %s entity where entity.id = :id", UserNote.class.getName()); final String[] hqlArray = new String[] { noResultHql, arrayResultHql, booleanResultHql, booleanResultHql2, integerResultHql, longResultHql, objectResultHql }; IdentityManager.instance().loggedIn(new UsernamePrincipal(userList.get(0).getUsername())); UserNote instance = (UserNote) userList.get(0).getUserNoteSet().toArray()[0]; Permission entityPermission = new EntityPermission<UserNote>(EntityOperation.LOAD, instance.getId(), instance); for( String hql : hqlArray ) { try { Set<Permission> permissions = IdentityManager.instance().getIdentity().getPermissions(); permissions.clear(); Permission p = new HqlEntityPermission(EntityOperation.ALL, UserNote.class, hql); permissions.add(p); SecurityManager.instance().checkPermission(entityPermission); } catch (SecurityException e) { } catch (IllegalArgumentException e) { } catch (Exception e) { fail(e.getMessage()); } } HibernateLifecycle.getCurrentSession().getTransaction().rollback(); } @LifecycleClass(uri = "http://www.xchain.org/security/1.0") public static class TestIdentityService implements IdentityService { private static final long serialVersionUID = 1L; private static boolean started = false; private static boolean cleanup = false; private Map<Principal, Identity> identities; private Identity currentIdentity; public TestIdentityService() { identities = new HashMap<Principal, Identity>(); for(User user : userList) { IdentityImpl identity = new IdentityImpl(); identity.setPrincipal(new UsernamePrincipal(user.getUsername())); identities.put(identity.getPrincipal(), identity); } } public Identity getIdentity() { return currentIdentity; } public void loggedIn(Principal principal) throws SecurityException { currentIdentity = identities.get(principal); } public void loggedOut() { currentIdentity = null; } @StartThreadStep(localName = "criteria-test-identity-service", before = DefaultIdentityService.IDENTITY_LIFECYCLE_STEP_NAME) public static void startStep(ThreadContext foo) { log.debug("Starting lifecycle step: test-identity-service"); if( foo.getClass().equals(TestThreadContext.class) ) { synchronized( TestIdentityService.class ) { if( !started ) { log.debug("Starting TestIdentityService."); if( IdentityManager.instance().getIdentityService() == null ) { log.debug("Installing TestIdentityService."); IdentityManager.instance().setIdentityService(new TestIdentityService()); cleanup = true; } started = true; } } } } @StopThreadStep(localName = "criteria-test-identity-service") public static void stopStep(ThreadContext foo) { log.debug("Stopping lifecycle step: test identity service."); if( foo.getClass().equals(TestThreadContext.class) ) { synchronized( TestIdentityService.class ) { if( started ) { log.debug("Stopping TestIdentityService."); if( cleanup ) { IdentityManager.instance().setIdentityService(null); cleanup = false; } started = false; } } } } @Override public boolean equals(Object o) { return o.getClass().equals(getClass()); } } public static class TestThreadContext extends ThreadContext { } }