/*
* 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.jackrabbit.core;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.principal.ItemBasedPrincipal;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.core.security.JackrabbitSecurityManager;
import org.apache.jackrabbit.core.security.SecurityConstants;
import org.apache.jackrabbit.test.AbstractJCRTest;
import org.apache.jackrabbit.test.NotExecutableException;
import org.apache.jackrabbit.util.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Item;
import javax.jcr.LoginException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Node;
import javax.jcr.Value;
import java.security.Principal;
/**
* <code>SecurityManagerTest</code>...
*/
public class UserPerWorkspaceSecurityManagerTest extends AbstractJCRTest {
/**
* logger instance
*/
private static final Logger log = LoggerFactory.getLogger(UserPerWorkspaceSecurityManagerTest.class);
private JackrabbitSecurityManager secMgr;
@Override
protected void setUp() throws Exception {
super.setUp();
RepositoryImpl repo = (RepositoryImpl) superuser.getRepository();
secMgr = repo.getSecurityManager();
if (!(secMgr instanceof UserPerWorkspaceSecurityManager)) {
throw new NotExecutableException();
}
}
private String getAlternativeWorkspaceName() throws RepositoryException {
String altWsp = null;
String[] wsps = superuser.getWorkspace().getAccessibleWorkspaceNames();
if (wsps.length == 1) {
superuser.getWorkspace().createWorkspace("tmp");
altWsp = "tmp";
} else {
for (String name : wsps) {
if (!name.equals(superuser.getWorkspace().getName())) {
altWsp = name;
break;
}
}
}
return altWsp;
}
public void testSystemUserCreation() throws Exception {
String altWsp = getAlternativeWorkspaceName();
if (altWsp == null) {
throw new NotExecutableException();
}
// system users must be automatically be created -> login with admin
// must therefore succeed.
Session s = getHelper().getSuperuserSession(altWsp);
try {
// admin/anonymous/administrators must be present
String adminId = ((UserPerWorkspaceSecurityManager) secMgr).adminId;
assertEquals(adminId, s.getUserID());
UserManager umgr = ((JackrabbitSession) s).getUserManager();
assertNotNull(umgr.getAuthorizable(adminId));
assertNotNull(umgr.getAuthorizable(((UserPerWorkspaceSecurityManager) secMgr).anonymousId));
assertNotNull(umgr.getAuthorizable(SecurityConstants.ADMINISTRATORS_NAME));
} finally {
s.logout();
}
}
public void testSystemUsersAreSaved() throws Exception {
String adminId = ((UserPerWorkspaceSecurityManager) secMgr).adminId;
UserManager umgr = ((JackrabbitSession) superuser).getUserManager();
Principal p = umgr.getAuthorizable(adminId).getPrincipal();
if (p instanceof ItemBasedPrincipal) {
Item item = superuser.getItem(((ItemBasedPrincipal) p).getPath());
assertFalse(item.isNew());
assertFalse(item.isModified());
}
}
public void testUsersArePerWorkspace() throws Exception {
String altWsp = getAlternativeWorkspaceName();
if (altWsp == null) {
throw new NotExecutableException();
}
Session s = getHelper().getSuperuserSession(altWsp);
User u = null;
try {
// other users created in the default workspace...
u = ((JackrabbitSession) superuser).getUserManager().createUser("testUser", "testUser");
superuser.save();
// ... must not be present in the alternate-workspace
UserManager umgr = ((JackrabbitSession) s).getUserManager();
assertNull(umgr.getAuthorizable("testUser"));
try {
Session us = getHelper().getRepository().login(new SimpleCredentials("testUser", "testUser".toCharArray()), altWsp);
us.logout();
fail("testUser must not be able to login to a workspace without this user.");
} catch (LoginException e) {
// success
}
} finally {
s.logout();
if (u != null) {
u.remove();
superuser.save();
}
}
}
public void testCloneUser() throws Exception {
String altWsp = getAlternativeWorkspaceName();
if (altWsp == null) {
throw new NotExecutableException();
}
UserManager uMgr = ((JackrabbitSession) superuser).getUserManager();
Session s = getHelper().getSuperuserSession(altWsp);
User u = null;
try {
// other users created in the default workspace...
u = uMgr.createUser("testUser", "testUser");
superuser.save();
String userPath = null;
if (u.getPrincipal() instanceof ItemBasedPrincipal) {
userPath = ((ItemBasedPrincipal) u.getPrincipal()).getPath();
assertTrue(superuser.nodeExists(userPath));
} else {
throw new NotExecutableException();
}
// ... must not be present in the alternate-workspace
UserManager umgr = ((JackrabbitSession) s).getUserManager();
assertNull(umgr.getAuthorizable("testUser"));
assertFalse(s.nodeExists(userPath));
String clonePath = userPath;
String parentPath = Text.getRelativeParent(clonePath, 1);
while (!s.nodeExists(parentPath)) {
clonePath = parentPath;
parentPath = Text.getRelativeParent(parentPath, 1);
}
// clone the user into the second workspace
s.getWorkspace().clone(superuser.getWorkspace().getName(), clonePath, clonePath, true);
// ... now the user must be visible
assertNotNull(umgr.getAuthorizable("testUser"));
if (userPath != null) {
assertTrue(s.nodeExists(userPath));
}
// ... and able to login to that workspace
Session us = getHelper().getRepository().login(new SimpleCredentials("testUser", "testUser".toCharArray()), altWsp);
us.logout();
} finally {
// remove the test user in the second workspace
Authorizable dest = ((JackrabbitSession) s).getUserManager().getAuthorizable("testUser");
if (dest != null) {
dest.remove();
s.save();
}
// logout the session
s.logout();
if (u != null) {
// remove as well in the first workspace
u.remove();
superuser.save();
}
}
}
public void testUpdateUser() throws NotExecutableException, RepositoryException {
// create the same use in 2 different workspace must make the 'corresponding'
// and updating must succeed
String altWsp = getAlternativeWorkspaceName();
if (altWsp == null) {
throw new NotExecutableException();
}
UserManager uMgr = ((JackrabbitSession) superuser).getUserManager();
Session s = getHelper().getSuperuserSession(altWsp);
User u = null;
try {
// other users created in the default workspace...
u = uMgr.createUser("testUser", "testUser");
superuser.save();
String userPath = null;
if (u.getPrincipal() instanceof ItemBasedPrincipal) {
userPath = ((ItemBasedPrincipal) u.getPrincipal()).getPath();
assertTrue(superuser.nodeExists(userPath));
} else {
throw new NotExecutableException();
}
// ... must not be present in the alternate-workspace
UserManager umgr = ((JackrabbitSession) s).getUserManager();
assertNull(umgr.getAuthorizable("testUser"));
assertFalse(s.nodeExists(userPath));
User u2 = umgr.createUser("testUser", "testUser");
s.save();
assertTrue(s.nodeExists(userPath));
Value value = superuser.getValueFactory().createValue("anyValue");
u.setProperty(propertyName1, value);
superuser.save();
// no automatic sync.
assertFalse(u2.hasProperty(propertyName1));
// update nodes
Node n2 = s.getNode(userPath);
n2.update(superuser.getWorkspace().getName());
// now the value must be visible
assertTrue(u2.hasProperty(propertyName1));
assertEquals(value.getString(), u2.getProperty(propertyName1)[0].getString());
} finally {
// remove the test user in the destination workspace
Authorizable dest = ((JackrabbitSession) s).getUserManager().getAuthorizable("testUser");
if (dest != null) {
dest.remove();
s.save();
}
// logout the session to the destination workspace
s.logout();
if (u != null) {
// and remove it in the default workspace as well
u.remove();
superuser.save();
}
}
}
public void testNewUsersCanLogin() throws Exception {
Session s = null;
User u = null;
try {
// other users created in the default workspace...
u = ((JackrabbitSession) superuser).getUserManager().createUser("testUser", "testUser");
superuser.save();
// the new user must be able to login to the repo
s = getHelper().getRepository().login(new SimpleCredentials("testUser", "testUser".toCharArray()));
} finally {
if (s != null) {
s.logout();
}
if (u != null) {
u.remove();
superuser.save();
}
}
}
public void testTransientUserCannotLogin() throws RepositoryException, UnsupportedRepositoryOperationException {
Session s = null;
String uid = "testUser";
UserManager umgr = ((JackrabbitSession) superuser).getUserManager();
umgr.autoSave(false);
try {
// other users created in the default workspace...
umgr.createUser(uid, uid);
// the new user must be able to login to the repo
s = getHelper().getRepository().login(new SimpleCredentials(uid, uid.toCharArray()));
fail("Non-saved user node -> must not be able to login.");
} catch (LoginException e) {
// success
} finally {
if (s != null) {
s.logout();
}
superuser.refresh(false);
Authorizable a = ((JackrabbitSession) superuser).getUserManager().getAuthorizable(uid);
if (a != null) {
a.remove();
superuser.save();
}
umgr.autoSave(true);
}
}
}