Role overrides revisited

Jump to: navigation, search
Warning: This page is no longer in use. The information contained on the page should NOT be seen as relevant or reliable.


Originally the user capabilities were calculated as a sum of role capabilities/overrides in all parent contexts. In 1.9 it was completely rewritten.

Summary of problems in 1.9.x

  • overrides in one role affect evaluation of capability in all other roles assigned to user
  • very hard to explain to normal people (including most of the developers, sorry)
  • relies heavily on PHP code and is nearly impossible to optimise with SQL especially when fetching users having some capability in specified context
I have just worked out that it is possible to do both has_capability and get_users_by_capability in pure SQL. However, I think in almost all cases it would be slower becuase of $CFG->defaultroleid and $CFG->defaultforntpageroleid, and becuase the query is extremely complex.--Tim Hunt 02:52, 11 March 2009 (UTC)

Proposed solution

Change evaluation algorithm, instead of aggregation caps from all roles in each step, calculate resulting capability for each role and use OR logical operation on the result. The prohibit would work the same way as before.

Example

File:role eval proposal.png

Image above shows an example where one user is both student and teacher in the same course. The override in student role does not affect default capability from default role.


At present this setup returns false in glossary context, in order to get the same results you would need to reassign the teacher role at the glossary context.

Algorithm

Question: am I allowed to do something in specified context?

  1. Look up all roles I have in specified context by looking for all my role assignments in parent contexts.
  2. Is there any CAP_PROHIBIT specified in any role capability or role override? If yes, answer is I can not do that.
  3. For each role separately find the override or cap definition at the lowest level - this is the result for individual role at this context (CAP_ALLOW, CAP_PREVENT or nothing).
  4. If at least one role has CAP_ALLOW result I can do it, yay!

Backwards compatibility

  • No major problems expected unless somebody assigned multiple roles with multiple overrides at the same context. Guessing results is relatively difficult and one new override may change result for different users in different contexts.
This is incorrect. This proposal breaks backwards-compability with just two role assignments and no overrides. For example a capability where Authenticated user says Allow and Student says Prevent.--Tim Hunt 02:50, 11 March 2009 (UTC)
This complex evaluation replaced original 1.7 and 1.8 mostly undefined results. Authenticated role is a special role designed especially for system level capabilities, it should not contain capabilities used at lower contexts at all, sorry. Petr Škoda (škoďák)
AFAIK it was never documented that Authenticated role is sort of special role and should not be used in lower contexts. From a contrib-developer point of view I can't see any reason why this role should be special. Or even, why should I ask "is some of predefined Moodle roles special?" --David Mudrak 06:30, 16 March 2009 (UTC)
So, the only differences are that:
  1. Final results for each role must be weighted by depth (or 2^depth-1). So, inner results will weight more than previous ones.
  2. Instead of applying logical OR, final results must be summed.
  3. To be BC, >0 means permission is granted. <=0 means permission is denied
(note that the 2^depth-1 approach gives us up to 31 possible levels - max 32 bits int, but using floats will give us far more depths)"
Is that all? IMO the key concept here is to avoid resolving ties inter-roles and process each role separately. And then, of course, apply the correct calculations to final results. --Eloy Lafuente (stronk7) 10:08, 18 March 2009 (UTC)

Needed code changes

Performance improvements