Prototype "View Permissions" interface

Prototype "View Permissions" interface

by John Isner -
Number of replies: 15
In a previous discussion, Tim Hunt and others discussed the possibility of a "View permissions" interface for improving the transparency of roles. That discussion led to three things:
  1. MDL-13228 ("Improve the transparency of roles by adding a View Permissions tab")
  2. An article in the documentation wiki explaining How permissions are calculated
  3. A suggestion (by Tim) that it would be useful to have a UI screen that displays the table described in the documentation.
I just attached two files to MDL-13228 that display the table. It's my first php programming exercise, so please don't complain about the code smile. The two files are:
  • get_permission_table

    This file contains two functions that you add to accesslib.php

  • roletab.php

    Put this file in your Moodle root directory (or wherever you like) and point your browser at it. Enter three parameters:
    • the capability name (e.g., mod/quiz:attempt)
    • the context level (SYSTEM, COURSE, COURSECAT, MODULE, etc.)
    • instance id (the id the context. E.g., for a course, it's the course id, for a quiz, it's the module id, etc. You can easily get the context id from the URL when you're pointing at the context.)
This is not he same thing as the "View permissions" tab suggested in MDL-13228. Roletab views only a single permission and shows you exactly how it was calculated. Try it, it'll blow your mind!

Feedback and questions here.
Average of ratings: -
In reply to John Isner

Re: Prototype "View Permissions" interface

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Good effort! I have not actually tried running it, but I had a look at the code and it is not bad, apart from the stunningly deep nesting in get_permissions_table - 9 levels of nesting. Wow!

(That probably suggests you need to define some other functions to do part of the work.)

Actually, if you define the array

$perm_letters = array{
CAP_ALLOW => 'A',
CAP_PREVENT => 'P',
CAP_PROHIBIT => 'X',
CAP_INHERIT => 'N',
};

Then you can replace the inner bit with:

if( isset($rdef[$capability]) ){
$string_perm = $perm_letters[$rdef[$capability];
}else{
$string_perm = $perm_letters[CAP_INHERIT];
}

Also, I never use one-letter variable names any more, except for very short loops over arrays, but I see you picked that habit up from Martin Langhoff, so who am I to criticise.


Hopefully we can get this cleaned up and integrated with the rest of the roles UI soon.
In reply to Tim Hunt

Re: Prototype "View Permissions" interface

by John Isner -
Tim,
I probably picked up the habit of using one-letter variable names a long time before Martin Langhoff was born smile

Below is a screenshot of the output for the complex example in the wiki article. There are some minor differences between the format of the table in the screenshot and the one in the article:
  • Since the actual role names may be long, I decided to encode them as R<id> using the internal role id's. The example is confusing because the actual rolenames are those from the wiki article (r1, r2, r3, and r4) and these became encoded as R16, R17, R18, and R19.
  • Rather than using the (encoded) role names as column headings, I use the short names of the context instances, and repeated the role names in the table body.
  • The table shows all of my roles, not just r1...r4
As I said earlier, it's just a prototype, and any improvements to the format that make the table more readable are welcome. I think it's important to do whatever is necessary so that the user can take in the whole table at a glance.

Back to the issue of N's in the table. I think they're very important. When I look at the table, I want all my roles and overrides accounted for, even if they don't affect the calculation. The table below shows two additional roles that are not in the wiki article: user (the shortname of "Authenticated user") and unipar ("Universal participant"), a role that I gave my test user so that he would have access to all courses. Obviously, those roles do not affect the calculation, but I'm really glad to see them smile

Possible enhancements: allow users to enter multiple capabilities (possibly comma-separated list, or using multiple text boxes), giving multiple tables on the results page. IMO users will typically be interested in seeing what's going on with a group of capabilities. We could possibly even accept a shorthand like "mod/quiz" to mean "all the quiz capabilities."

Anoter UI idea for the input: a screen just like the role definition page (listing all 200 capabilities), but just a single radio button to the right of each, allowing the user to select one or more capabilities to examine. May be overkill.
Attachment rolesdebug2_output_for_wiki_article_scenario.png
In reply to John Isner

Re: Prototype "View Permissions" interface

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
I finally found time to make a non-prototype version of this.

In the attached zip you will find a file called explain.php which you need to copy into into admin/roles. Also in there is tabs_patch.txt, which contains a patch that adds 4 lines of code to admin/roles/tabs.php. You need to apply that patch, either using tools, or by hand.

Then you will get a new 'explain' tab in the roles interface. This tab lets you do what-if scenarios. You can get it to draw a table like the one in John's documentation for any combination of roles in this context, or any of the parent contexts.

You can only draw the table for one capability at a time.

It prints an explanation of the algorithm underneath the table.

Because it lets you experiment with different roles-assignment scenarios, and because these are not stored as real role assignments in the database, you can only really draw the table for one capability at a time, you can't actually call has_capability.

I'll attach a screen-shot in a minute. As you can see, the one thing missing is the language strings.
In reply to Tim Hunt

Re: Prototype "View Permissions" interface

by John Isner -
Hi Tim,
Thanks for your work on this! After you posted your screenshot, I messaged you with some feedback, and you suggested that we have the conversation in public. Good idea.

I don't have time to install explain.zip today, but will definitely do it tomorrow. I don't want to make any premature judgements based on a screenshot!

I hope that our conversation will focus on use cases. Do we want (1) a tool for debugging actual roles-related problems or (2) a tool for running academic what-if scenarios. Both are valid use cases, but for me, (1) is much more important (it is the one I had in mind while developing the prototype).

I am very happy to read that "the explain interface defaults to your current roles assignments when you first go there," because that means I can still use it for (1). And if I can also use it for (2), it's a nice bonus.

Let's resume the discussion tomorrow.
In reply to John Isner

Re: Prototype "View Permissions" interface

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Well, I originally designed it for 2), but since reading your messages, I realised that I could make use of the code I had already written that initialises the what-if scenario to the role assignments of the current user. Exactly the same code could initialise the scenario to the roles for any given user. The only issue there is what sort of interface we provide for choosing that user, and it probably has to respect the viewparticipants capability, and should only let you select users you are allowed to see. We can probably steal and enhance the interface I made for the users roles report (http://moodle.org/mod/data/view.php?d=13&rid=1005).

With a bit more work, it could also be made to initialise the scenario to someone using guest access to the site, or someone logged in with their own account, but accessing a course open to guests, etc.

You also said that you would be reassured if my code actually called has_capability, and proved that it returned the same result as my implementation of the same algorithm. I agree it would be reassuring, and if we know that we are in the scenario for a real user, we can of course do that.

I am now really tempted to spend tomorrow at work playing with this, rather than doing the work I am supposed to be doing wink
In reply to Tim Hunt

Re: Prototype "View Permissions" interface

by John Isner -
Tim,
I installed explain.zip this morning. There's an undefined function role_fix_names() called at line 121 of explain.php.
In reply to John Isner

Re: Prototype "View Permissions" interface

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
I am working in Moodle 1.9/head. Perhaps it is new. I think you can safely comment that line out, it just does the bit about letting your rename roles in courses.
In reply to Tim Hunt

Re: Prototype "View Permissions" interface

by John Isner -
Thanks, it's working now. Here's feedback:

The interface seems a bit complicated, but I got used to it pretty quickly. My main issue is that if I'm using it for debugging, rather than for what-if scenarios, I care about only one of the inputs (the capability) and I'm going to ignore everything else. Maybe there should be two interfaces, one for each use case. Or a "show advanced" for the scenario use case.

For the debugging use case, the default role assignments are those of the current user (that's good), but the current user must be someone who can access the explain roles tab, i.e., someone who can manage permissions. If a student is having problems, the teacher or admin must first research the student's role assignments in order to set up a scenario. This is tedious and error-prone. Possible solutions: (1) as you suggested, allow a user to be specified in the user in the interface (2) make this a user-level interface (i.e., one that anyone can use) (3) make a "debugging" version of explain.php a standalone script like texdebug.php. I see no risks in allowing any user to use such a script to get info about their own permissions.

Even though explain.php can simulate role assignments without storing them, it can not simulate overrides. The actual overrides are used. So these simulations are only partial simulations, making them somewhat harder to interpret and explain.

I don't like the capabilities menu. IMO a 200-item menu is actually less convenient than a text box. On the other hand, if you know the name of the capability, you can start typing and get the menu to complete for you, which is nice. Can you get text boxes to do that? I'm not an html programmer.

I don't like having the menu tell me what capabilities are and are not relevant! That's not the way the roles model works. In the model, you have permissions in a context whether they're relvant or not, and I may want to see them. For example, suppose I'm doing some "explaining" in a quiz context, I suddenly get the urge to investigate a permission that's relevant in a course context (e.g., moodle/course:view). Explain.php makes me go to the course context (click, click, click) to get the answer.

Most likely a bug: In a module context (e.g., quiz), I always get a pink box with an error message "The capability to explain is not relevant to this context" regardless of what capability I choose (e.g., mod/quiz:preview). This happens even after I attempted the Preview, in order to force loading of access data.
In reply to John Isner

Re: Prototype "View Permissions" interface

by John Isner -
This is a follow-up to my feedback post.

As I continue to think about the debugging use case, I am increasingly struck by the parallels with texdebug.php.

Texdebug is a stand-alone script--you don't even need to be logged in to use it. When a user is having problems getting LaTeX markup to render, we tell them to point their browsers as texdebug.php and report back with the results. We ask them to paste the text output into a forum post. Either the user himself or an "expert" in the forums can usually spot the problem.

With roles, we have a similar situation. A user reports a problem like this one from earlier today. I would love to be able to tell this user to point his browser at rolesdebug.php and report back with the results. But instead, we engage in a tedious game of "Twenty Questions."

So for the debugging case I a lean toward a texdebug-sytle solution (with a require_login, of course, since a current user is required). Same three inputs as in my prototype (capability, context level, instance id). Same output table, but also a textbox with a text version of the output that the user could copy and paste into a forum post that would display in a reasonably presentable way.

Incidentally, in my version of rolesdebug.php, you do not have to specify a capability, but you must specify a context level and instance id. Doing this will show you all the role assignments and overrides in effect for the target context, and often this is enough to diagnose a problem -- or at least a good first step.
In reply to John Isner

Re: Prototype "View Permissions" interface

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Sorry, I am way too busy to do more about this at the moment. I will get back to it some time, but not this week.

I'm off now to a 2-hour choir rehearsal. Oh joy.
In reply to Tim Hunt

Re: Prototype "View Permissions" interface

by John Isner -
Tim,
I have been thinking more about how to integrate the debugging version of this functionality into Moodle. The texdebug model is not ideal because the user must specify the context redundantly (when you're in Moodle and you need to debug a roles-related problem, you're presumably already in the context). The ideal solution would be to have the function called directly from the context.

At the bottom of many pages there is a call to print_footer(). I see that it creates a link to the page documentation, among other things. What if print_footer() took an optional argument $context; if $context is set, print_footer() would add a second link for role debugging. This link would open a popup showing the roles table (all N's) and a form with just one input field in case the user wanted to enter an optional capability.

By the way, I put a version of rolesdebug.php (standalone script along the same lines as texdebug) in Modules and Plugins and wrote an article in the docs wiki. This week I helped several users (offline) use the script and in each case, the script got us to the source of the problem very quickly. IMO this definitely needs to be a user-level function, as readily available as documentation.
In reply to John Isner

Re: Prototype "View Permissions" interface

by John Isner -
Thinking a bit more about "calling the function directly from the context." I realized that sometimes the context you're interested in may be different from the one you're currently in, and may be inaccessible to you.

Example: You're trying to enter a course, but Moodle won't let you, and you want to know why. If the role debug button is on the course page, it's useless to you.

Example 2: Blocks don't normally have their own page. You can turn editing on and click the roles icon, but then you get a generic roles managment page (the block context id is at the end of the URL).

As long as you can see a link to a context instance, you can let your mouse hover over it and read the context id out of the URI at the bottom of your browser.
In reply to John Isner

Re: Prototype "View Permissions" interface

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
I have come around to your way of thinking, that this should be an interface aimed at diagnosing roles problems for existing users. Rather than my what-if tool. I may try rewriting my prototype over the coming Easter weekend.

I think that a roles debug tool that is accessible to everyone is dangerous, it might be too useful for people trying to get unauthorised access. I would rather leave it as a tool for people trying to set up roles, but let them select any user to look at. If you can assign roles, you can already see the name and email address of everyone in the system, so it is not a problem to provide them with some interface for selecting which user to look at the permissions of.
In reply to Tim Hunt

Re: Prototype "View Permissions" interface

by John Isner -
I think that a roles debug tool that is accessible to everyone is dangerous

Even if it requires login? Even if it only works for the current user? If so, dangerous in what way?

My little script works only for the current user. To use it requires no special knowledge of roles and capabilities, just the ability to follow simple instructions.

I don't see any advantage in having "the ability to select any user to look at." If there is an advantage, what's the use case?

Here's the use case I have in mind: Someone posts to Moodle.org with a possibly roles-related problem. It doesn't matter if this person can assign roles or necessarily even understands roles! We ask them to (1) recreate the problem (2) use the tool (3) post the output back to the forum. I have already used it this way several times with good results, so it's a real use case, not a hypothetical one. No one had to give me a login to their system, and no one had to find "the the person who set up their roles" to help them. If only someone else could use the tool, they would have to duplicate the user's problem, and that would require the user to explain what context they were in and what operation they had tried. It's an inefficient process with lots of chances for miscommunication. As an admin I would consider it a waste of my time.

This is similar to the use case for texdebug.php. If people are having problems with the TeX filter, we tell them to run the script and paste the output into a forum post. And texdebug.php doesn't even require a login!