Hi folks,
I decided to do an analysis of how exactly how permissions are checked so we 
might be able to brainstorm about where there is low hanging fruit in the 
optimization field.


 0. Check that the user is authenticated
 1. If user is attempting write operation on read-only wiki, return false.
 2. If user is a guest, get XWikiPreferences for the wiki and do 4 checks on 
the XWikiPreferences object to see if the action requires authentication.
 3. If action is "delete", get current document and check if current user 
created that document.

 4. Determine if user is superadmin
 5.   Load DocumentReferenceResolver from ComponentManager and normalize 
username then compare to superadmin name.

 6. Check for admin status on main wiki
 7.   Get XWikiPreferences document for main wiki
 8.     scan for rights objects which allow the user "admin" permission, return 
if found
 9.     get list of all groups which user is a member of, repeat check for 
each, returning if found
10.   If checking permission for "programming" then repeat from step 7 with 
"programming" as permission.
11.   If the permission being checked is programming, return the result even if 
false.

12. If in a subwiki, get the XWikiServer<subwiki> document and return if the 
current user is the owner.

13. If checking for register permission then get the XWikiPreferences document 
for the wiki.
14.   scan for rights objects which allow the user, return if found
15.     get list of all groups which user is a member of, repeat check for 
each, returning if found
16.     if no match is found, check for deny rights on the user, return if found
17.       get list of all groups which user is a member of, repeat check for 
each, returning if found

18. Get XWikiPreferences from wiki
19.   scan for rights objects which allow the user "admin" permission, return 
if found.
20.     get list of all groups which user is a member of, repeat check for 
each, returning if found

21. Get WebPreferences for space where document to check permissions resides.
22.   scan for rights objects which allow the user "admin" permission, return 
if found.
23.     get list of all groups which user is a member of, repeat check for 
each, returning if found
24.   if the WebPreferences document specifies another Space as it's "parent" 
then change to that space and return to step 21.

25. Get the document to check permission on
26.   scan for rights objects which deny the user, return if found
27.     get list of all groups which user is a member of, repeat check for 
each, returning if found
28.   scan for rights objects which allow the user, return if found
29.     get list of all groups which user is a member of, repeat check for 
each, returning if found

30. Get the WebPreferences document for the space where document to check 
permission on resides.
31.   scan for rights objects which deny the user, return if found
32.     get list of all groups which user is a member of, repeat check for 
each, returning if found.
33.   scan for rights objects which allow the user, return if found
34.     get list of all groups which user is a member of, repeat check for 
each, returning if found.

35. Check if the WebPreferences document specifies a "parent space" if so, 
change to that space and go to step 30.

36. Get the XWikiPreferences document for the wiki
37.   scan for rights objects which deny the user, return if found
38.     get list of all groups which user is a member of, repeat check for 
each, returning if found
39.   scan for rights objects which allow the user, return if found
40.     get list of all groups which user is a member of, repeat check for 
each, returning if found

Getting the list of groups which a user is a member of is relatively quick 
after the first run since it is cached.
After being loaded it is stored in the context but the implementation doesn't 
trust the version in the context and gets it again. It could be a little bit 
faster by just assuming that anything in the context is still valid.

If a group is a member of another group then the checks will be repeated twice 
each time.

One thought that comes to mind is that we could check permissions on a user and 
all of the groups of which he is a member, simultaneously. This would reduce 
the number of scans over the list of objects in a given document and since this 
is such a hotspot, I think optimizations like this might pay off.

Documents which need to be loaded include:
The XWikiPreferences for the main wiki
XWikiPreferences for the subwiki (if applicable)
WebPreferences for the space (and any space listed as a parent)
The document which we are checking
If in a subwiki, the XWikiServer<subwiki> document

This means that for any level of performance, all documents other than the 
document we are checking need to remain in the cache perpetually.

Since the vast majority of checks are for things like view and edit with users 
who don't have programming or admin permission, it makes sense to rearrange the 
checks so that the most common path executes the fastest. This would be a major 
project though.

Any other thoughts and ideas about it?

Caleb

_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs

Reply via email to