/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.xpn.xwiki.user.impl.xwiki;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.jmock.Mock;
import org.jmock.core.Invocation;
import org.jmock.core.stub.CustomStub;
import org.xwiki.model.EntityType;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.EntityReference;
import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.api.Document;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.test.AbstractBridgedXWikiComponentTestCase;
import com.xpn.xwiki.user.api.XWikiGroupService;
import com.xpn.xwiki.user.api.XWikiRightNotFoundException;
import com.xpn.xwiki.user.api.XWikiRightService;
import com.xpn.xwiki.user.api.XWikiUser;
/**
* Unit tests for {@link com.xpn.xwiki.user.impl.xwiki.XWikiRightServiceImpl}.
*
* @version $Id: 596223088f9281f45511a42d428ab59cb67b4d23 $
*/
public class XWikiRightServiceImplTest extends AbstractBridgedXWikiComponentTestCase
{
private static final EntityReference XWIKIPREFERENCES_REFERENCE = new EntityReference("XWikiPreferences",
EntityType.DOCUMENT, new EntityReference("XWiki", EntityType.SPACE));
private XWikiRightServiceImpl rightService;
private Mock mockGroupService;
private Mock mockXWiki;
private XWikiDocument user;
private XWikiDocument group;
private XWikiDocument group2;
@Override
protected void setUp() throws Exception
{
super.setUp();
this.rightService = new XWikiRightServiceImpl();
this.mockGroupService = mock(XWikiGroupService.class, new Class[] {}, new Object[] {});
this.mockXWiki = mock(XWiki.class);
this.mockXWiki.stubs().method("getGroupService").will(returnValue(this.mockGroupService.proxy()));
this.mockXWiki.stubs().method("isReadOnly").will(returnValue(false));
this.mockXWiki.stubs().method("getWikiOwner").will(returnValue(null));
this.mockXWiki.stubs().method("getMaxRecursiveSpaceChecks").will(returnValue(0));
this.mockXWiki.stubs().method("getDocument").with(ANYTHING, eq("WebPreferences"), ANYTHING).will(
new CustomStub("Implements XWiki.getDocument")
{
@Override
public Object invoke(Invocation invocation) throws Throwable
{
return new XWikiDocument(new DocumentReference(getContext().getWikiId(),
(String) invocation.parameterValues.get(0), "WebPreferences"));
}
});
// Called from MessageToolVelocityContextInitializer.
this.mockXWiki.stubs().method("prepareResources");
getContext().setWiki((XWiki) this.mockXWiki.proxy());
this.user = new XWikiDocument(new DocumentReference("wiki", "XWiki", "user"));
this.user.setNew(false);
getContext().setWikiId(this.user.getWikiName());
BaseObject userObject = new BaseObject();
userObject.setClassName("XWiki.XWikiUser");
this.user.addXObject(userObject);
this.mockXWiki.stubs().method("getDocument").with(eq(this.user.getPrefixedFullName()), ANYTHING).will(
returnValue(this.user));
this.group = new XWikiDocument(new DocumentReference("wiki", "XWiki", "group"));
this.group.setNew(false);
getContext().setWikiId(this.group.getWikiName());
BaseObject groupObject = new BaseObject();
groupObject.setClassName("XWiki.XWikiGroups");
groupObject.setStringValue("member", this.user.getFullName());
this.group.addXObject(groupObject);
this.mockXWiki.stubs().method("getDocument").with(eq(this.group.getPrefixedFullName()), ANYTHING).will(
returnValue(this.group));
this.group2 = new XWikiDocument(new DocumentReference("wiki2", "XWiki", "group2"));
this.group2.setNew(false);
getContext().setWikiId(this.group2.getWikiName());
BaseObject group2Object = new BaseObject();
group2Object.setClassName("XWiki.XWikiGroups");
group2Object.setStringValue("member", this.user.getPrefixedFullName());
this.group2.addXObject(groupObject);
this.mockXWiki.stubs().method("getDocument").with(eq(this.group2.getPrefixedFullName()), ANYTHING).will(
returnValue(this.group2));
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember").with(
eq(this.user.getDocumentReference()), ANYTHING, ANYTHING, ANYTHING).will(
new CustomStub("Implements XWikiGroupService.getAllGroupsReferencesForMember")
{
@Override
public Object invoke(Invocation invocation) throws Throwable
{
XWikiContext context = (XWikiContext) invocation.parameterValues.get(3);
if (context.getWikiId().equals(group.getWikiName())) {
return Collections.singleton(group.getDocumentReference());
} else if (context.getWikiId().equals(group2.getWikiName())) {
return Collections.singleton(group2.getDocumentReference());
} else {
return Collections.emptyList();
}
}
});
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember").with(
eq(this.group.getDocumentReference()), ANYTHING, ANYTHING, ANYTHING).will(
returnValue(Collections.emptyList()));
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember").with(
eq(this.group2.getDocumentReference()), ANYTHING, ANYTHING, ANYTHING).will(
returnValue(Collections.emptyList()));
}
/**
* Test if checkRight() take care of users's groups from other wikis.
*/
public void testCheckRight() throws XWikiRightNotFoundException, XWikiException
{
final XWikiDocument doc = new XWikiDocument(new DocumentReference("wiki2", "Space", "Page"));
Mock mockGlobalRightObj = mock(BaseObject.class, new Class[] {}, new Object[] {});
mockGlobalRightObj.stubs().method("getStringValue").with(eq("levels")).will(returnValue("view"));
mockGlobalRightObj.stubs().method("getStringValue").with(eq("groups")).will(
returnValue(this.group.getPrefixedFullName()));
mockGlobalRightObj.stubs().method("getStringValue").with(eq("users")).will(returnValue(""));
mockGlobalRightObj.stubs().method("getIntValue").with(eq("allow")).will(returnValue(1));
mockGlobalRightObj.stubs().method("setNumber");
mockGlobalRightObj.stubs().method("setDocumentReference");
mockGlobalRightObj.stubs().method("setOwnerDocument");
doc.addObject("XWiki.XWikiGlobalRights", (BaseObject) mockGlobalRightObj.proxy());
getContext().setWikiId("wiki2");
boolean result =
this.rightService.checkRight(this.user.getPrefixedFullName(), doc, "view", true, true, true, getContext());
assertTrue(this.user.getPrefixedFullName() + " does not have global view right on wiki2", result);
}
public void testHasAccessLevelAdminOnDocument() throws Exception
{
final String wikiName = this.user.getWikiName();
final XWikiDocument doc = new XWikiDocument(new DocumentReference(wikiName,
"Space", "Page"));
final XWikiDocument preferences = new XWikiDocument(new DocumentReference(wikiName,
"XWiki", "XWikiPreference"));
BaseObject rightsObject = new BaseObject();
rightsObject.setClassName("XWiki.XWikiRights");
rightsObject.setStringValue("levels", "admin");
rightsObject.setStringValue("users", this.user.getPrefixedFullName());
rightsObject.setIntValue("allow", 1);
doc.addXObject(rightsObject);
BaseObject preferencesObject = new BaseObject();
preferencesObject.setClassName("XWiki.XWikiGlobalRights");
preferencesObject.setStringValue("levels", "admin");
preferencesObject.setIntValue("allow", 0);
preferencesObject.setStringValue("users", this.user.getPrefixedFullName());
preferences.addXObject(preferencesObject);
preferences.setNew(false);
this.mockXWiki.stubs().method("getDocument").with(eq(XWIKIPREFERENCES_REFERENCE), ANYTHING).will(
new CustomStub("Implements XWiki.getDocument")
{
@Override
public Object invoke(Invocation invocation) throws Throwable
{
if (!getContext().getWikiId().equals(wikiName)) {
new XWikiDocument(new DocumentReference(getContext().getWikiId(), "XWiki", "XWikiPreference"));
}
return preferences;
}
});
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getPrefixedFullName()), ANYTHING).will(
returnValue(doc));
getContext().setWikiId(wikiName);
assertFalse("Admin rights must not be considered when set on document level.",
this.rightService.hasAccessLevel("admin", this.user.getPrefixedFullName(),
doc.getPrefixedFullName(), true,
getContext()));
}
public void testHasAccessLevelWhithUserFromAnotherWiki() throws XWikiException
{
final XWikiDocument doc = new XWikiDocument(new DocumentReference(this.group2.getWikiName(), "Space", "Page"));
final XWikiDocument preferences = new XWikiDocument(new DocumentReference("wiki2", "XWiki", "XWikiPreference"));
BaseObject preferencesObject = new BaseObject();
preferencesObject.setClassName("XWiki.XWikiGlobalRights");
preferencesObject.setStringValue("levels", "view");
preferencesObject.setIntValue("allow", 1);
preferences.addXObject(preferencesObject);
preferences.setNew(false);
this.mockXWiki.stubs().method("getDocument").with(eq(XWIKIPREFERENCES_REFERENCE), ANYTHING).will(
new CustomStub("Implements XWiki.getDocument")
{
@Override
public Object invoke(Invocation invocation) throws Throwable
{
if (!getContext().getWikiId().equals("wiki2")) {
new XWikiDocument(new DocumentReference(getContext().getWikiId(), "XWiki", "XWikiPreference"));
}
return preferences;
}
});
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getPrefixedFullName()), ANYTHING).will(
returnValue(doc));
getContext().setWikiId("wiki");
assertFalse("User from another wiki has right on a local wiki", this.rightService.hasAccessLevel("view",
this.user.getPrefixedFullName(), doc.getPrefixedFullName(), true, getContext()));
// direct user rights
preferencesObject.setStringValue("users", this.user.getPrefixedFullName());
getContext().setWikiId(this.user.getWikiName());
assertTrue("User from another wiki does not have right on a local wiki when tested from user wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getPrefixedFullName(), true,
getContext()));
assertTrue("User from another wiki does not have right on a local wiki when tested from user wiki",
this.rightService.hasAccessLevel("view", this.user.getFullName(), doc.getPrefixedFullName(), true,
getContext()));
getContext().setWikiId(doc.getWikiName());
assertTrue("User from another wiki does not have right on a local wiki when tested from local wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getPrefixedFullName(), true,
getContext()));
assertTrue("User from another wiki does not have right on a local wiki when tested from local wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getFullName(), true,
getContext()));
// user group rights
preferencesObject.removeField("users");
// group from user's wiki
preferencesObject.setStringValue("groups", this.group.getPrefixedFullName());
getContext().setWikiId(this.user.getWikiName());
assertTrue("User group from another wiki does not have right on a local wiki when tested from user wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getPrefixedFullName(), true,
getContext()));
assertTrue("User group from another wiki does not have right on a local wiki when tested from user wiki",
this.rightService.hasAccessLevel("view", this.user.getFullName(), doc.getPrefixedFullName(), true,
getContext()));
getContext().setWikiId(doc.getWikiName());
assertTrue("User group from another wiki does not have right on a local wiki when tested from local wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getPrefixedFullName(), true,
getContext()));
assertTrue("User group from another wiki does not have right on a local wiki when tested from local wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getFullName(), true,
getContext()));
// group from document's wiki
preferencesObject.setStringValue("groups", this.group2.getFullName());
getContext().setWikiId(this.user.getWikiName());
assertTrue("User group from another wiki does not have right on a local wiki when tested from user wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getPrefixedFullName(), true,
getContext()));
assertTrue("User group from another wiki does not have right on a local wiki when tested from user wiki",
this.rightService.hasAccessLevel("view", this.user.getFullName(), doc.getPrefixedFullName(), true,
getContext()));
getContext().setWikiId(doc.getWikiName());
assertTrue("User group from another wiki does not have right on a local wiki when tested from local wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getPrefixedFullName(), true,
getContext()));
assertTrue("User group from another wiki does not have right on a local wiki when tested from local wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getFullName(), true,
getContext()));
// user is wiki owner
preferencesObject.removeField("groups");
this.mockXWiki.stubs().method("getWikiOwner").with(eq(doc.getWikiName()), ANYTHING).will(
returnValue(this.user.getPrefixedFullName()));
getContext().setWikiId(this.user.getWikiName());
assertTrue("Wiki owner from another wiki does not have right on a local wiki when tested from user wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getPrefixedFullName(), true,
getContext()));
assertTrue("Wiki owner group from another wiki does not have right on a local wiki when tested from user wiki",
this.rightService.hasAccessLevel("view", this.user.getFullName(), doc.getPrefixedFullName(), true,
getContext()));
getContext().setWikiId(doc.getWikiName());
assertTrue(
"Wiki owner group from another wiki does not have right on a local wiki when tested from local wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getPrefixedFullName(), true,
getContext()));
assertTrue(
"Wiki owner group from another wiki does not have right on a local wiki when tested from local wiki",
this.rightService.hasAccessLevel("view", this.user.getPrefixedFullName(), doc.getFullName(), true,
getContext()));
}
public void testHasAccessLevelWhithOnlyPageAsReference() throws XWikiException
{
final XWikiDocument doc = new XWikiDocument(new DocumentReference("wiki", "Space", "Page"));
final XWikiDocument preferences =
new XWikiDocument(new DocumentReference(doc.getWikiName(), doc.getSpaceName(), "WebPreferences"));
BaseObject preferencesObject = new BaseObject();
preferencesObject.setClassName("XWiki.XWikiGlobalRights");
preferencesObject.setStringValue("levels", "view");
preferencesObject.setIntValue("allow", 1);
preferences.addXObject(preferencesObject);
preferences.setNew(false);
this.mockXWiki.stubs().method("getDocument").with(eq(preferences.getSpaceName()),
eq(preferences.getPageName()), ANYTHING).will(returnValue(preferences));
this.mockXWiki.stubs().method("getDocument").with(eq(XWIKIPREFERENCES_REFERENCE), ANYTHING).will(
returnValue(new XWikiDocument(
new DocumentReference(getContext().getWikiId(), "XWiki", "XWikiPreferences"))));
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getPrefixedFullName()), ANYTHING).will(
returnValue(doc));
getContext().setWikiId("wiki");
getContext().setDoc(doc);
assertFalse("Failed to check right with only page name", this.rightService.hasAccessLevel("view", this.user
.getPageName(), doc.getPageName(), true, getContext()));
}
/**
* Test that programming rights are checked on the context user when no context document is set.
*/
public void testProgrammingRightsWhenNoContextDocumentIsSet()
{
// Setup an XWikiPreferences document granting programming rights to XWiki.Programmer
XWikiDocument prefs = new XWikiDocument(new DocumentReference(getContext().getMainXWiki(), "XWiki", "XWikiPreferences"));
Mock mockGlobalRightObj = mock(BaseObject.class, new Class[] {}, new Object[] {});
mockGlobalRightObj.stubs().method("getStringValue").with(eq("levels")).will(returnValue("programming"));
mockGlobalRightObj.stubs().method("getStringValue").with(eq("users")).will(returnValue("XWiki.Programmer"));
mockGlobalRightObj.stubs().method("getIntValue").with(eq("allow")).will(returnValue(1));
mockGlobalRightObj.stubs().method("setNumber");
mockGlobalRightObj.stubs().method("setDocumentReference");
mockGlobalRightObj.stubs().method("setOwnerDocument");
prefs.addObject("XWiki.XWikiGlobalRights", (BaseObject) mockGlobalRightObj.proxy());
this.mockXWiki.stubs().method("getDocument").with(eq(XWIKIPREFERENCES_REFERENCE), eq(getContext()))
.will(returnValue(prefs));
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember")
.with(eq(new DocumentReference(getContext().getMainXWiki(), "XWiki", "Programmer")), eq(0), eq(0), same(getContext()))
.will(returnValue(Collections.EMPTY_LIST));
// Setup the context (no context document)
this.mockXWiki.stubs().method("getDatabase").will(returnValue("xwiki"));
getContext().remove("doc");
getContext().remove("sdoc");
getContext().setWikiId(getContext().getMainXWiki());
// XWiki.Programmer should have PR, as per the global rights.
getContext().setUser("XWiki.Programmer");
assertTrue(this.rightService.hasProgrammingRights(getContext()));
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember").with(
eq(new DocumentReference("xwiki", "XWiki", XWikiRightService.GUEST_USER)), ANYTHING, ANYTHING, ANYTHING)
.will(returnValue(Collections.emptyList()));
// Guests should not have PR
getContext().setUser(XWikiRightService.GUEST_USER_FULLNAME);
assertFalse(this.rightService.hasProgrammingRights(getContext()));
// superadmin should always have PR
getContext().setUser(XWikiRightService.SUPERADMIN_USER_FULLNAME);
assertTrue(this.rightService.hasProgrammingRights(getContext()));
}
public void testHasAccessLevelWhithGuestUser() throws XWikiException
{
final XWikiDocument doc = new XWikiDocument(new DocumentReference("wiki2", "Space", "Page"));
final XWikiDocument preferences = new XWikiDocument(new DocumentReference("wiki2", "XWiki", "XWikiPreference"));
BaseObject preferencesObject = new BaseObject();
preferencesObject.setClassName("XWiki.XWikiGlobalRights");
preferencesObject.setStringValue("levels", "view");
preferencesObject.setIntValue("allow", 1);
preferences.addXObject(preferencesObject);
this.mockXWiki.stubs().method("getDocument").with(eq(XWIKIPREFERENCES_REFERENCE), ANYTHING).will(
new CustomStub("Implements XWiki.getDocument")
{
@Override
public Object invoke(Invocation invocation) throws Throwable
{
if (!getContext().getWikiId().equals("wiki2")) {
new XWikiDocument(new DocumentReference(getContext().getWikiId(), "XWiki", "XWikiPreference"));
}
return preferences;
}
});
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getPrefixedFullName()), ANYTHING).will(
returnValue(doc));
this.mockXWiki.stubs().method("getXWikiPreference").with(eq("authenticate_view"), ANYTHING, ANYTHING).will(
returnValue("false"));
this.mockXWiki.stubs().method("getXWikiPreferenceAsInt").with(eq("authenticate_view"), ANYTHING, ANYTHING)
.will(returnValue(0));
this.mockXWiki.stubs().method("getSpacePreference").with(eq("authenticate_view"), ANYTHING, ANYTHING).will(
returnValue("false"));
this.mockXWiki.stubs().method("getSpacePreferenceAsInt").with(eq("authenticate_view"), ANYTHING, ANYTHING)
.will(returnValue(0));
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember").with(
eq(new DocumentReference("xwiki", "XWiki", XWikiRightService.GUEST_USER)), ANYTHING, ANYTHING, ANYTHING)
.will(returnValue(Collections.emptyList()));
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember").with(
eq(new DocumentReference("wiki2", "XWiki", XWikiRightService.GUEST_USER)), ANYTHING, ANYTHING, ANYTHING)
.will(returnValue(Collections.emptyList()));
getContext().setWikiId("wiki");
assertFalse("Guest has wiew right on the document", this.rightService.hasAccessLevel("view",
XWikiRightService.GUEST_USER_FULLNAME, doc.getPrefixedFullName(), true, getContext()));
// direct user rights
preferencesObject.setStringValue("users", XWikiRightService.GUEST_USER_FULLNAME);
getContext().setWikiId("wiki");
assertTrue("Guest does not have right on the document when tested from another wiki", this.rightService
.hasAccessLevel("view", XWikiRightService.GUEST_USER_FULLNAME, doc.getPrefixedFullName(), true,
getContext()));
getContext().setWikiId(doc.getDatabase());
assertTrue("Guest does not have right on the document when tested from the document wiki", this.rightService
.hasAccessLevel("view", XWikiRightService.GUEST_USER_FULLNAME, doc.getPrefixedFullName(), true,
getContext()));
}
/**
* This test will fail unless:
* SuperAdmin has programming permission before calling dropPermissions().
* SuperAdmin does not have programming permission after calling dropPermissions().
*/
public void testProgrammingRightsAfterDropPermissions()
{
// Nobody even superadmin gets PR after they have given it up.
this.getContext().setUser(XWikiRightService.SUPERADMIN_USER_FULLNAME);
assertTrue("User does not have programming right prior to calling dropPermissions()",
this.rightService.hasProgrammingRights(this.getContext()));
this.getContext().dropPermissions();
assertFalse("Author retains programming right after calling dropPermissions()",
this.rightService.hasProgrammingRights(this.getContext()));
}
/**
*
* This test will fail unless:
* SuperAdmin has programming permission before calling Document#dropPermissions().
* SuperAdmin does not have programming permission after calling dropPermissions().
*/
public void testProgrammingRightsAfterDropPermissionsForRenderingCycle()
{
final Document doc =
new Document(new XWikiDocument(new DocumentReference("XWiki", "Test", "Permissions")), this.getContext());
// doc.setContentAuthor(XWikiRightService.SUPERADMIN_USER_FULLNAME);
//this.getContext().setDoc(doc);
this.getContext().setUser(XWikiRightService.SUPERADMIN_USER_FULLNAME);
assertTrue("User does not have programming right prior to calling "
+ "doc.dropPermissions()",
this.rightService.hasProgrammingRights(this.getContext()));
final Map<String, Object> backup = new HashMap<String, Object>();
XWikiDocument.backupContext(backup, this.getContext());
doc.dropPermissions();
assertFalse("Author retains programming right after calling doc.dropPermissions()",
this.rightService.hasProgrammingRights(this.getContext()));
final Map<String, Object> backup2 = new HashMap<String, Object>();
XWikiDocument.backupContext(backup2, this.getContext());
assertTrue("User does not have programming right after switching contexts.",
this.rightService.hasProgrammingRights(this.getContext()));
XWikiDocument.restoreContext(backup2, this.getContext());
assertFalse("Author did not lose programming right after switching contexts back.",
this.rightService.hasProgrammingRights(this.getContext()));
XWikiDocument.restoreContext(backup, this.getContext());
assertTrue("Author did not regain programming right after switching contexts back.",
this.rightService.hasProgrammingRights(this.getContext()));
}
public void testHasAccessLevelForDeleteRightWhenUserIsDocumentCreator() throws Exception
{
getContext().setWikiId(this.user.getWikiName());
final XWikiDocument doc = new XWikiDocument(new DocumentReference(this.user.getWikiName(), "Space", "Page"));
// Set the creator to be the user we test against since creator should get delete rights
doc.setCreatorReference(this.user.getDocumentReference());
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getPrefixedFullName()), ANYTHING).will(
returnValue(doc));
final XWikiDocument xwikiPreferences = new XWikiDocument(
new DocumentReference(this.user.getWikiName(), "XWiki", "XWikiPreferences"));
this.mockXWiki.stubs().method("getDocument").with(eq("XWiki.XWikiPreferences"), ANYTHING).will(
returnValue(xwikiPreferences));
assertTrue("Should allow delete rights for page creator",
this.rightService.hasAccessLevel("delete", this.user.getFullName(), doc.getFullName(), true, getContext()));
}
private void assertAccessLevelForGuestUser(String level, XWikiDocument doc, boolean shouldAllow) throws Exception
{
if (shouldAllow) {
assertTrue("Empty wiki should allow " + level + " for guest.",
this.rightService.hasAccessLevel(level, XWikiRightService.GUEST_USER_FULLNAME,
doc.getFullName(), getContext()));
} else {
assertFalse("Empty wiki should deny " + level + " for guest.",
this.rightService.hasAccessLevel(level, XWikiRightService.GUEST_USER_FULLNAME,
doc.getFullName(), getContext()));
}
}
public void testHasAccessLevelOnEmptyWiki() throws Exception
{
getContext().setWikiId("xwiki");
final XWikiDocument doc
= new XWikiDocument(new DocumentReference(getContext().getWikiId(), "Space", "Page"));
final XWikiDocument xwikiPreferences
= new XWikiDocument(new DocumentReference(getContext().getWikiId(), "XWiki", "XWikiPreference"));
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember")
.with(ANYTHING, ANYTHING, ANYTHING, ANYTHING).will(
returnValue(Collections.emptyList()));
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getFullName()), ANYTHING)
.will(returnValue(doc));
this.mockXWiki.stubs().method("getDocument").with(eq(XWIKIPREFERENCES_REFERENCE), ANYTHING).will(
returnValue(xwikiPreferences));
this.mockXWiki.stubs().method("getXWikiPreference").with(ANYTHING, ANYTHING, ANYTHING).will(
returnValue("false"));
this.mockXWiki.stubs().method("getXWikiPreferenceAsInt").with(ANYTHING, ANYTHING, ANYTHING)
.will(returnValue(0));
this.mockXWiki.stubs().method("getSpacePreference").with(ANYTHING, ANYTHING, ANYTHING).will(
returnValue("false"));
this.mockXWiki.stubs().method("getSpacePreferenceAsInt").with(ANYTHING, ANYTHING, ANYTHING)
.will(returnValue(0));
assertAccessLevelForGuestUser("login" , doc, true);
assertAccessLevelForGuestUser("register" , doc, true);
assertAccessLevelForGuestUser("view" , doc, true);
assertAccessLevelForGuestUser("edit" , doc, true);
assertAccessLevelForGuestUser("delete" , doc, true);
assertAccessLevelForGuestUser("admin" , doc, true);
assertAccessLevelForGuestUser("programming", doc, false);
}
private void assertAccessLevelForAdminUser(String level, XWikiDocument doc, boolean shouldAllow) throws Exception
{
if (shouldAllow) {
assertTrue(level + " for admin should be allowed.",
this.rightService.hasAccessLevel(level, getContext().getWikiId() + ":XWiki.Admin",
doc.getFullName(), getContext()));
} else {
assertFalse(level + " for admin should be denied.",
this.rightService.hasAccessLevel(level, getContext().getWikiId() + ":XWiki.Admin",
doc.getFullName(), getContext()));
}
}
public void testAdminAccessLevels() throws Exception
{
getContext().setWikiId("xwiki");
final XWikiDocument doc
= new XWikiDocument(new DocumentReference(getContext().getWikiId(), "Space", "Page"));
final XWikiDocument xwikiPreferences
= new XWikiDocument(new DocumentReference(getContext().getWikiId(), "XWiki", "XWikiPreference"));
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember")
.with(ANYTHING, ANYTHING, ANYTHING, ANYTHING).will(
returnValue(Collections.emptyList()));
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getFullName()), ANYTHING)
.will(returnValue(doc));
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getPrefixedFullName()), ANYTHING)
.will(returnValue(doc));
this.mockXWiki.stubs().method("getDocument").with(eq(XWIKIPREFERENCES_REFERENCE), ANYTHING).will(
returnValue(xwikiPreferences));
this.mockXWiki.stubs().method("getXWikiPreference").with(ANYTHING, ANYTHING, ANYTHING).will(
returnValue("false"));
this.mockXWiki.stubs().method("getXWikiPreferenceAsInt").with(ANYTHING, ANYTHING, ANYTHING)
.will(returnValue(0));
this.mockXWiki.stubs().method("getSpacePreference").with(ANYTHING, ANYTHING, ANYTHING).will(
returnValue("false"));
this.mockXWiki.stubs().method("getSpacePreferenceAsInt").with(ANYTHING, ANYTHING, ANYTHING)
.will(returnValue(0));
BaseObject preferencesObject = new BaseObject();
preferencesObject.setClassName("XWiki.XWikiGlobalRights");
preferencesObject.setStringValue("levels", "admin");
preferencesObject.setIntValue("allow", 1);
preferencesObject.setStringValue("users", getContext().getWikiId() + ":XWiki.Admin");
xwikiPreferences.addXObject(preferencesObject);
assertAccessLevelForAdminUser("login" , doc, true);
assertAccessLevelForAdminUser("register" , doc, true);
assertAccessLevelForAdminUser("view" , doc, true);
assertAccessLevelForAdminUser("edit" , doc, true);
assertAccessLevelForAdminUser("delete" , doc, true);
assertAccessLevelForAdminUser("admin" , doc, true);
assertAccessLevelForAdminUser("programming", doc, true);
}
/**
* Verify that edit rights is not sufficient for editing
* *.WebPreferences and XWiki.XWikiPreferences, since that can be
* used to elevate the privileges to admin.
*/
public void testEditRightsOnWebPreferencesDocuments() throws Exception
{
this.mockGroupService.stubs().method("getAllGroupsReferencesForMember")
.with(ANYTHING, ANYTHING, ANYTHING, ANYTHING).will(
returnValue(Collections.emptyList()));
this.user = new XWikiDocument(new DocumentReference("wiki", "XWiki", "user"));
this.user.setNew(false);
getContext().setWikiId(this.user.getWikiName());
BaseObject userObject = new BaseObject();
userObject.setClassName("XWiki.XWikiUser");
this.user.addXObject(userObject);
this.mockXWiki.stubs().method("getDocument").with(eq(this.user.getPrefixedFullName()), ANYTHING).will(
returnValue(this.user));
getContext().setWikiId(this.user.getWikiName());
final XWikiDocument doc = new XWikiDocument(new DocumentReference("wiki", "Space", "Document"));
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getPrefixedFullName()), ANYTHING).will(
returnValue(doc));
final XWikiDocument preferences = new XWikiDocument(new DocumentReference("wiki", "XWiki", "XWikiPreference"));
BaseObject preferencesObject = new BaseObject();
preferencesObject.setClassName("XWiki.XWikiGlobalRights");
preferencesObject.setStringValue("levels", "admin");
preferencesObject.setIntValue("allow", 0);
preferencesObject.setStringValue("users", "xwiki:XWiki.UserA");
preferences.addXObject(preferencesObject);
this.mockXWiki.stubs().method("getDocument").with(eq("wiki:Space.WebPreferences"), ANYTHING)
.will(returnValue(
new XWikiDocument(new DocumentReference("wiki",
"Space", "WebPreferences"))));
this.mockXWiki.stubs().method("getDocument").with(eq("wiki:XWiki.XWikiPreferences"), ANYTHING)
.will(returnValue(
new XWikiDocument(new DocumentReference("wiki",
"XWiki", "XWikiPreferences"))));
this.mockXWiki.stubs().method("getDocument").with(eq("wiki:Space.XWikiPreferences"), ANYTHING)
.will(returnValue(
new XWikiDocument(new DocumentReference("wiki",
"Space", "XWikiPreferences"))));
this.mockXWiki.stubs().method("getDocument").with(eq(XWIKIPREFERENCES_REFERENCE), ANYTHING).will(
new CustomStub("Implements XWiki.getDocument")
{
@Override
public Object invoke(Invocation invocation) throws Throwable
{
if (!getContext().getWikiId().equals("wiki")) {
new XWikiDocument(new DocumentReference(getContext().getWikiId(), "XWiki", "XWikiPreference"));
}
return preferences;
}
});
assertFalse( "Programming rights have not been configured.",
rightService.hasAccessLevel("programming", "xwiki:XWiki.UserA", "wiki:Space.WebPreferences", getContext()));
assertFalse( "Admin rights have not been configured.",
rightService.hasAccessLevel("admin", "xwiki:XWiki.UserA", "wiki:Space.WebPreferences", getContext()));
assertFalse( "Shouldn't allow edit rights by default on WebPreferences documents.",
rightService.hasAccessLevel("edit", "xwiki:XWiki.UserA", "wiki:Space.WebPreferences", getContext()));
assertFalse( "Edit rights should be denied by default on XWiki.XWikiPreferences",
rightService.hasAccessLevel("edit", "xwiki:XWiki.UserA", "wiki:XWiki.XWikiPreferences", getContext()));
assertTrue( "Other documents named XWikiPreferences should be unaffected.",
rightService.hasAccessLevel("edit", "xwiki:XWiki.UserA", "wiki:Space.XWikiPreferences", getContext()));
preferencesObject = new BaseObject();
preferencesObject.setClassName("XWiki.XWikiGlobalRights");
preferencesObject.setStringValue("levels", "edit");
preferencesObject.setIntValue("allow", 1);
preferencesObject.setStringValue("users", "xwiki:XWiki.UserA");
preferences.addXObject(preferencesObject);
assertTrue( "Edit rights have been configured.",
rightService.hasAccessLevel("edit", "xwiki:XWiki.UserA", "wiki:Space.Document", getContext()));
assertFalse( "No admin rights have been configured.",
rightService.hasAccessLevel("admin", "xwiki:XWiki.UserA", "wiki:Space.Document", getContext()));
assertFalse( "Edit rights should be denied WebPreferences document for non-admin users.",
rightService.hasAccessLevel("edit", "xwiki:XWiki.UserA", "wiki:Space.WebPreferences", getContext()));
assertFalse( "Edit rights should be denied XWiki.XWikiPreferences document for non-admin users.",
rightService.hasAccessLevel("edit", "xwiki:XWiki.UserA", "wiki:XWiki.XWikiPreferences", getContext()));
preferencesObject = new BaseObject();
preferencesObject.setClassName("XWiki.XWikiGlobalRights");
preferencesObject.setStringValue("levels", "admin");
preferencesObject.setIntValue("allow", 1);
preferencesObject.setStringValue("users", "xwiki:XWiki.UserA");
preferences.addXObject(preferencesObject);
assertTrue( "Admin rights have been configured.",
rightService.hasAccessLevel("admin", "xwiki:XWiki.UserA", "wiki:Space.Document", getContext()));
assertTrue( "Edit rights should be granted on WebPreferences document for admin users.",
rightService.hasAccessLevel("edit", "xwiki:XWiki.UserA", "wiki:Space.WebPreferences", getContext()));
assertTrue( "Edit rights should be granted on XWiki.XWikiPreferences document for non-admin users.",
rightService.hasAccessLevel("edit", "xwiki:XWiki.UserA", "wiki:XWiki.XWikiPreferences", getContext()));
}
// This is currently a proof-of-behavior test to show that if a document prevents you from editing
// it, calling hasAccessLevel('create') on that document will also fail.
// Changing this behavior is proposed here: http://lists.xwiki.org/pipermail/devs/2013-March/053802.html
// See also: https://jira.xwiki.org/browse/XWIKI-8892
public void testDeniesAccessLevelForCreateIfDocumentDeniesEdit() throws Exception
{
getContext().setWikiId(this.user.getWikiName());
final XWikiDocument doc = new XWikiDocument(new DocumentReference(this.user.getWikiName(), "Space", "Page"));
// Set the creator to be the user we test against since creator should get delete rights
BaseObject xo = new BaseObject();
xo.setClassName("XWiki.XWikiRights");
xo.setStringValue("levels", "edit");
xo.setStringValue("users", user.getFullName());
xo.setIntValue("allow", 0);
doc.addXObject(xo);
DocumentReference dr = new DocumentReference(this.user.getWikiName(), "XWiki", "XWikiPreferences");
this.mockXWiki.stubs().method("getDocument").with(isA(EntityReference.class), ANYTHING)
.will(returnValue(new XWikiDocument(new DocumentReference(dr))));
this.mockXWiki.stubs().method("getDocument").with(eq(doc.getPrefixedFullName()), ANYTHING).will(
returnValue(doc));
this.mockXWiki.stubs().method("getXWikiPreference").with(eq("authenticate_edit"), ANYTHING, ANYTHING).will(
returnValue(""));
this.mockXWiki.stubs().method("getXWikiPreferenceAsInt").with(eq("authenticate_edit"), ANYTHING, ANYTHING).will(
returnValue(0));
this.mockXWiki.stubs().method("getSpacePreference").with(eq("authenticate_edit"), ANYTHING, ANYTHING).will(
returnValue(""));
this.mockXWiki.stubs().method("getSpacePreferenceAsInt").with(eq("authenticate_edit"), ANYTHING, ANYTHING).will(
returnValue(0));
this.mockXWiki.stubs().method("checkAuth").with(ANYTHING).will(
returnValue(new XWikiUser(this.user.getFullName())));
this.mockXWiki.stubs().method("getRightService").will(returnValue(this.rightService));
assertFalse("Should not have edit permission on document if it is denied at a document level",
this.rightService.checkAccess("edit", doc, getContext()));
assertFalse("Should not have create permission on document if it is denied at a document level",
this.rightService.checkAccess("create", doc, getContext()));
}
}