package org.dataone.service.types.v1.util; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InputStream; import java.util.Set; import java.util.TreeSet; import org.dataone.exceptions.MarshallingException; import org.dataone.service.types.v1.Group; import org.dataone.service.types.v1.Permission; import org.dataone.service.types.v1.Person; import org.dataone.service.types.v1.Session; import org.dataone.service.types.v1.Subject; import org.dataone.service.types.v1.SubjectInfo; import org.dataone.service.types.v1.SystemMetadata; import org.dataone.service.types.v1.TypeFactory; import org.dataone.service.util.Constants; import org.dataone.service.util.TypeMarshaller; import org.junit.Before; import org.junit.Test; public class AuthUtilsTestCase { private Session standardSession = null; private Subject publick = null; private Subject authenticated = null; private Subject verified = null; private Subject buildSubject(String cn) { Subject subject = new Subject(); subject.setValue("CN=" + cn + ",DC=something,DC=org"); return subject; } private Person buildTestPerson(String subjectString) { Person p = new Person(); p.setSubject(buildSubject(subjectString)); return p; } private Group buildTestGroup(String subjectString) { Group g = new Group(); g.setSubject(buildSubject(subjectString)); return g; } @Before public void setupSymbolicSubjects() { publick = new Subject(); publick.setValue(Constants.SUBJECT_PUBLIC); authenticated = new Subject(); authenticated.setValue(Constants.SUBJECT_AUTHENTICATED_USER); verified = new Subject(); verified.setValue(Constants.SUBJECT_VERIFIED_USER); } @Before public void createSession() { if (standardSession == null) { Session ses = new Session(); Subject subjectX = buildSubject("x"); ses.setSubject(subjectX); SubjectInfo si = new SubjectInfo(); Person x = buildTestPerson("x"); Person y = buildTestPerson("y"); Person z = buildTestPerson("z"); z.setVerified(true); x.addEquivalentIdentity(y.getSubject()); x.addEquivalentIdentity(z.getSubject()); si.addPerson(x); si.addPerson(y); si.addPerson(z); ses.setSubjectInfo(si); standardSession = ses; } } @Test public void testAuthorizedClientSubjects_Public() { Set subjectSet = AuthUtils.authorizedClientSubjects(standardSession); assertTrue("public should always appear", subjectSet.contains(publick)); } @Test public void testAuthorizedClientSubjects_Authenticated() { Set subjectSet = AuthUtils.authorizedClientSubjects(standardSession); assertTrue("authenticated should be in the list", subjectSet.contains(authenticated)); } @Test public void testAuthorizedClientSubjects_Verified() { Set subjectSet = AuthUtils.authorizedClientSubjects(standardSession); assertTrue("verified appears because an equiv identity is verified", subjectSet.contains(verified)); } @Test public void testAuthorizedClientSubjects_EquivalentIDs() { Set subjectSet = AuthUtils.authorizedClientSubjects(standardSession); assertTrue("subject list should contain x", subjectSet.contains(buildSubject("x"))); assertTrue("subject list should contain y", subjectSet.contains(buildSubject("y"))); assertTrue("subject list should contain z", subjectSet.contains(buildSubject("z"))); } @Test public void testAuthorizedClientSubjects_DaisyChainEquivalentIDs() { Session ses = new Session(); Subject subjectX = buildSubject("x"); ses.setSubject(subjectX); SubjectInfo si = new SubjectInfo(); Person x = buildTestPerson("x"); Person y = buildTestPerson("y"); Person z = buildTestPerson("z"); z.setVerified(true); x.addEquivalentIdentity(y.getSubject()); y.addEquivalentIdentity(z.getSubject()); si.addPerson(x); si.addPerson(y); si.addPerson(z); ses.setSubjectInfo(si); Set subjectSet = AuthUtils.authorizedClientSubjects(standardSession); assertTrue("subject list contains x", subjectSet.contains(buildSubject("x"))); assertTrue("subject list contains y", subjectSet.contains(buildSubject("y"))); assertTrue("subject list contains z", subjectSet.contains(buildSubject("z"))); } @Test public void testAuthorizedClientSubjects_DaisyChainVerified() { Session ses = new Session(); Subject subjectX = buildSubject("x"); ses.setSubject(subjectX); SubjectInfo si = new SubjectInfo(); Person x = buildTestPerson("x"); Person y = buildTestPerson("y"); Person z = buildTestPerson("z"); z.setVerified(true); x.addEquivalentIdentity(y.getSubject()); y.addEquivalentIdentity(z.getSubject()); si.addPerson(x); si.addPerson(y); si.addPerson(z); ses.setSubjectInfo(si); Set subjectSet = AuthUtils.authorizedClientSubjects(ses); assertTrue("subject list contains x", subjectSet.contains(verified)); } @Test public void testAuthorizedClientSubjects_EmptySession_isPublic() { Session ses = new Session(); Set subjectSet = AuthUtils.authorizedClientSubjects(ses); assertTrue("empty session should revert to public", subjectSet.contains(publick)); assertTrue("empty session should have only 1 subject (public)", subjectSet.size() == 1); } @Test public void testAuthorizedClientSubjects_Null_isPublic() { Set subjectSet = AuthUtils.authorizedClientSubjects(null); assertTrue("null session should revert to public", subjectSet.contains(publick)); assertTrue("null session should have only 1 subject (public)", subjectSet.size() == 1); } @Test public void testAuthorizedClientSubjects_PublicNotAuthenticated() { Session ses = new Session(); ses.setSubject(publick); SubjectInfo si = new SubjectInfo(); // Person x = buildTestPerson("x"); // Person y = buildTestPerson("y"); // Person z = buildTestPerson("z"); ses.setSubjectInfo(si); Set subjectSet = AuthUtils.authorizedClientSubjects(ses); assertFalse("public subject in session, should not have authenticated", subjectSet.contains(authenticated)); } @Test public void testAuthorizedClientSubjects_GroupTransitive() { Session ses = new Session(); ses.setSubject(buildSubject("x")); SubjectInfo si = new SubjectInfo(); Person x = buildTestPerson("x"); x.addIsMemberOf(buildSubject("groupA")); Person y = buildTestPerson("y"); x.addEquivalentIdentity(buildSubject("y")); y.addEquivalentIdentity(buildSubject("x")); y.addIsMemberOf(buildSubject("groupB")); Person z = buildTestPerson("z"); x.addEquivalentIdentity(buildSubject("z")); z.addEquivalentIdentity(buildSubject("x")); z.addIsMemberOf(buildSubject("groupC")); si.addPerson(x); si.addPerson(y); si.addPerson(z); si.addGroup(buildTestGroup("groupA")); si.addGroup(buildTestGroup("groupB")); si.addGroup(buildTestGroup("groupC")); ses.setSubjectInfo(si); Set subjectSet = AuthUtils.authorizedClientSubjects(ses); assertTrue("subject list should contain groupA", subjectSet.contains(buildSubject("groupA"))); assertTrue("subject list should contain groupB", subjectSet.contains(buildSubject("groupB"))); assertTrue("subject list should contain groupC", subjectSet.contains(buildSubject("groupC"))); } @Test public void testAuthorizedClientSubjects_GroupTransitive_DaisyChainEquivID() { Session ses = new Session(); ses.setSubject(buildSubject("x")); SubjectInfo si = new SubjectInfo(); Person x = buildTestPerson("x"); Group a = buildTestGroup("groupA"); a.addHasMember(x.getSubject()); x.addIsMemberOf(a.getSubject()); Person y = buildTestPerson("y"); Group b = buildTestGroup("groupB"); b.addHasMember(y.getSubject()); y.addIsMemberOf(b.getSubject()); x.addEquivalentIdentity(buildSubject("y")); y.addEquivalentIdentity(buildSubject("x")); Person z = buildTestPerson("z"); Group c = buildTestGroup("groupC"); c.addHasMember(z.getSubject()); z.addIsMemberOf(c.getSubject()); y.addEquivalentIdentity(buildSubject("z")); z.addEquivalentIdentity(buildSubject("y")); si.addPerson(x); si.addPerson(y); si.addPerson(z); si.addGroup(a); si.addGroup(b); si.addGroup(c); ses.setSubjectInfo(si); Set subjectSet = AuthUtils.authorizedClientSubjects(ses); assertTrue("subject list should contain groupA", subjectSet.contains(buildSubject("groupA"))); assertTrue("subject list should contain groupB", subjectSet.contains(buildSubject("groupB"))); assertTrue("subject list should contain groupC", subjectSet.contains(buildSubject("groupC"))); } /** * setting up a circular equivalent identity graph, to make sure we don't get stuck */ @Test public void testAuthorizedClientSubjects_RecursionInfiniteLoopTest() { Session ses = new Session(); ses.setSubject(buildSubject("x")); SubjectInfo si = new SubjectInfo(); Person x = buildTestPerson("x"); Group a = buildTestGroup("groupA"); a.addHasMember(x.getSubject()); x.addIsMemberOf(a.getSubject()); Person y = buildTestPerson("y"); Group b = buildTestGroup("groupB"); b.addHasMember(y.getSubject()); y.addIsMemberOf(b.getSubject()); x.addEquivalentIdentity(buildSubject("y")); y.addEquivalentIdentity(buildSubject("x")); Person z = buildTestPerson("z"); Group c = buildTestGroup("groupC"); c.addHasMember(z.getSubject()); z.addIsMemberOf(c.getSubject()); y.addEquivalentIdentity(buildSubject("z")); z.addEquivalentIdentity(buildSubject("y")); Person w = buildTestPerson("w"); Group d = buildTestGroup("groupD"); d.addHasMember(w.getSubject()); w.addIsMemberOf(d.getSubject()); z.addEquivalentIdentity(buildSubject("w")); w.addEquivalentIdentity(buildSubject("z")); x.addEquivalentIdentity(buildSubject("w")); w.addEquivalentIdentity(buildSubject("x")); si.addPerson(w); si.addPerson(x); si.addPerson(y); si.addPerson(z); si.addGroup(a); si.addGroup(b); si.addGroup(c); si.addGroup(d); ses.setSubjectInfo(si); Set subjectSet = AuthUtils.authorizedClientSubjects(ses); assertTrue("subject list should contain groupA", subjectSet.contains(buildSubject("groupA"))); assertTrue("subject list should contain groupB", subjectSet.contains(buildSubject("groupB"))); assertTrue("subject list should contain groupC", subjectSet.contains(buildSubject("groupC"))); assertTrue("subject list should contain groupC", subjectSet.contains(buildSubject("groupD"))); } @Test public void testAuthorizedClientSubjects_RecursionInfiniteLoopTest_Live() throws InstantiationException, IllegalAccessException, IOException, MarshallingException { Session ses = new Session(); InputStream is = this.getClass().getResourceAsStream("/org/dataone/service/samples/v1/loopedSubjectInfo.xml"); SubjectInfo si = TypeMarshaller.unmarshalTypeFromStream(SubjectInfo.class, is); ses.setSubjectInfo(si); ses.setSubject(si.getPerson(0).getSubject()); Set subjectSet = AuthUtils.authorizedClientSubjects(ses); for (Subject s : subjectSet) { System.out.println(s.getValue()); } assertTrue("subject list should contain New Group", subjectSet.contains(TypeFactory.buildSubject("CN=New Group,DC=dataone,DC=org"))); // assertTrue("subject list should contain groupB", subjectSet.contains(buildSubject("groupB"))); // assertTrue("subject list should contain groupC", subjectSet.contains(buildSubject("groupC"))); // assertTrue("subject list should contain groupC", subjectSet.contains(buildSubject("groupD"))); } @Test public void testIsAuthorized_AccessPolicy() { SystemMetadata sysmeta = new SystemMetadata(); sysmeta.setAccessPolicy( AccessUtil.createSingleRuleAccessPolicy( new String[]{buildSubject("x").getValue(), buildSubject("y").getValue()}, new Permission[]{ Permission.WRITE})); sysmeta.setRightsHolder(buildSubject("qq")); Set subjectSet = new TreeSet(); subjectSet.add(buildSubject("z")); subjectSet.add(buildSubject("y")); subjectSet.add(buildSubject("x")); assertTrue("x should be able to read the object", AuthUtils.isAuthorized(subjectSet, Permission.READ, sysmeta)); assertTrue("x should be able to write the object", AuthUtils.isAuthorized(subjectSet, Permission.WRITE, sysmeta)); assertFalse("x should NOT be able to change the object", AuthUtils.isAuthorized(subjectSet, Permission.CHANGE_PERMISSION, sysmeta)); assertFalse("testRightsHolder should be able to change the object", AuthUtils.isAuthorized(subjectSet, Permission.CHANGE_PERMISSION, sysmeta)); } @Test public void testIsAuthorized_RightsHolder() { SystemMetadata sysmeta = new SystemMetadata(); sysmeta.setAccessPolicy( AccessUtil.createSingleRuleAccessPolicy( new String[]{buildSubject("x").getValue(), buildSubject("y").getValue()}, new Permission[]{ Permission.WRITE})); sysmeta.setRightsHolder(buildSubject("testRightsHolder")); Set subjectSet = new TreeSet(); subjectSet.add(buildSubject("testRightsHolder")); assertTrue("testRightsHolder should be able to change the object", AuthUtils.isAuthorized(subjectSet, Permission.CHANGE_PERMISSION, sysmeta)); } }