3

I'm writing a java component which build all the pages in a wiki. What would be the best way to assign the user rights or groups which may view the page or spaces from within the java service component? Really struggling to find details on this in the API.

Gerrie van Wyk
  • 679
  • 8
  • 27

1 Answers1

5

You are finding no details in the API, because the Rights API is only about reading rights information, not setting rights

If you want to set permissions on pages programatically, and you can assume that the default permission handler is in place (which both the UI and the code to create new users in XWiki does, so it seems not too unreasonbale), you can create them as objects in the pages.

  1. Permissions are set by adding objects of type "XWiki.XWikiRights" to the pages
  2. these objects have the following attributes:

    • groups : a string containing a comma separated list of group references (e.g. XWiki.XWikiAdminGroup,XWiki.XWikiAllGroup for the default admin and "all members" group)
    • users : a string containing a comma separated list of user references (e.g. xwiki:XWiki.Admin,XWiki.Admin would describe the main wiki admin and the "Admin" account in the local wiki
    • levels : a string containing a comma separated list of permissions who ate affected by this entry, e.g. view,comment,edit
    • allow : an integer which should have two values: 1 means the entry is an "allow this right", 0 means it is a "deny these rights"

The groups and users fields can be empty, though usually one of them is filled with data. The levels and allow must be set with some values.

One example how a permission is set on a page is the (internal) method XWiki.protectUserPage which sets the permissions on a newly create user in the way this user can edit ones one profile page:

public void protectUserPage(String userName, String userRights, XWikiDocument doc, XWikiContext context)
    throws XWikiException
{
    DocumentReference rightClassReference = getRightsClass(context).getDocumentReference();

    EntityReference relativeRightClassReference =
        rightClassReference.removeParent(rightClassReference.getWikiReference());

    // Allow users to edit their own profiles
    BaseObject newuserrightsobject = doc.newXObject(relativeRightClassReference, context);
    newuserrightsobject.setLargeStringValue("users", userName);
    newuserrightsobject.setStringValue("levels", userRights);
    newuserrightsobject.setIntValue("allow", 1);
}

Here the first few lines are slightly more complicated to make sure the XWiki.XWikiRights class page is present and properly initialized; without harm you should be able to do something simpler like:

    BaseObject newrightsobject = doc.newObject("XWiki.XWikiRights", context);

The userRights is usually edit here (it was only that while looking for the code that I found out this is actually configurable ...); userName is the full name of the users profile page here (e.g XWiki.NewUser)

The actual full code can be viewed at github e.g. for the 7.2 release:

https://github.com/xwiki/xwiki-platform/blob/xwiki-platform-7.2/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java#L3366

Finally to distinguish between rights only given to a specific page, and rights given to a page and all its subpages: if you want a rights object to be valid for subpages, too, do not add it to the page itself, but create a special subpage with name WebPreferences and add an object of type XWiki.XWikiGlobalRights (with the same fields) to that page.

Some further pointers:

for more details how the access rights work, see http://platform.xwiki.org/xwiki/bin/view/AdminGuide/Access+Rights especially the reference section: "An overview of permissions"

If you have installed the "Admin Tools" extension, you can view the "ShowRights" page to see all right objects in you wiki.

Clemens Klein-Robbenhaar
  • 3,457
  • 1
  • 18
  • 27
  • Thanks for the great answer! – Gerrie van Wyk Jan 25 '16 at 08:53
  • How do I create a new group like `MyCompany.HRGroup`, `MyCompany.AdminGroup`, `MCompany.EngineersGroup`, with different rights, and then add users to them, depending on their role? – Nawaz Mar 20 '20 at 19:32
  • @Nawaz if you do not want to add these groups in the `XWiki` space, you can create an empty page for each of them and then in the object editor add an object of type `XWiki.XWikiGroups` to it. Do not forget to set the checkbox for "terminal page" when creating it. If you want to do this programmatically instead of via the UI, the answer would be to long for a comment; please ask a new question. – Clemens Klein-Robbenhaar Mar 21 '20 at 23:45
  • @ClemensKlein-Robbenhaar: ah, I see. I didn't know `XWiki` is a _space_. I think I can use it. I'm fine with `XWiki.HRGroup` as well. Yes, I want to do it programatically. I'll ask a new question. – Nawaz Mar 22 '20 at 00:03
  • there you go: https://stackoverflow.com/questions/60794694/how-do-i-programmatically-create-new-groups-with-specific-set-of-rights-on-xwiki – Nawaz Mar 22 '20 at 00:20
  • Read your answer multiple times, and I think I understand things better (though still not enough to do the work I need). Wish I could vote it multiple times, because it deserves so. The wiki doc is not great for programming help. I wish they add documentations for API, methods and some common examples. After reading the codebase, I realized everything is a page in the XWiki: be it, users, rights, groups, in addition to the normal (content) pages. – Nawaz Mar 22 '20 at 01:22
  • Why did you do this: `rightClassReference.removeParent(rightClassReference.getWikiReference());`. Is it to avoid having the implicit rights inherited from the parents (as explained in [your examples here](https://stackoverflow.com/questions/60794694/how-do-i-programmatically-create-new-groups-with-specific-set-of-rights-on-xwiki/60806636?noredirect=1#comment107673241_60806636))? – Nawaz Mar 30 '20 at 10:08
  • This is just a snippet from the actual XWiki core code. The issue there is that the full document contains the wiki name (like `xwiki:XWiki.XWikiGlobalRights`) but to look up the class one must have a reference without the wiki prefix (i.e. `XWiki.XWikiGlobalRights`). That is what the code does. I personally prefer to just use strings instead of references in these cases, even though the corresponding methods are deprecated, as I have not finished my PhD in XWiki references yet. – Clemens Klein-Robbenhaar Mar 31 '20 at 09:34