Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Access API: Difference between revisions

From MoodleDocs
(48 intermediate revisions by 12 users not shown)
Line 1: Line 1:
{{Moodle_2.2}}The Access API gives you functions so you can determine what the current user is allow to do, and it allows modules to extend Moodle with new capabilities.  
{{Moodle_2.2}}The Access API gives you functions so you can determine what the current user is allowed to do. It also allows modules to extend Moodle with new capabilities.  


==Overview==
==Overview==


Moodle is using a role based access control model. Most entities in Moodle (system, users, course categories, courses, modules and blocks) are represented by contexts that are arranged in a tree like hierarchy called context tree. Role is a set of capability definitions, each capability usually represents an ability of user to do something. Roles are defined at the top most system context level. Roles definitions can be overridden at lower context levels. User access control is calculated from the definitions of roles assigned to users.
Moodle is using a role based access control model. Most entities in Moodle (system, users, course categories, courses, modules and blocks) are represented by contexts that are arranged in a tree like hierarchy called context tree. Role is a set of capability definitions, each capability usually represents an ability of user to do something. Roles are defined at the top most system context level. Role definitions can be overridden at lower context levels. User access control is calculated from the definitions of roles assigned to users.


All users that did not log-in yet automatically get the default role defined in $CFG->notloggedinroleid, it is not possible to assign any other role to this non-existent user id. There is one special guest user account that is user when user logs in using the guest login button or when guest autologin is enabled. Again you can not assign any roles to the guest account directly, this account gets the $CFG->guestroleid automatically. All other authenticated users get the default user role specified in $CFG->defaultuserroleid and in the frontpage context the role specified in $CFG->defaultfrontpageroleid.
All users that did not log-in yet automatically get the default role defined in $CFG->notloggedinroleid, it is not possible to assign any other role to this non-existent user id. There is one special guest user account that is used when user logs in using the guest login button or when guest autologin is enabled. Again you can not assign any roles to the guest account directly, this account gets the $CFG->guestroleid automatically. All other authenticated users get the default user role specified in $CFG->defaultuserroleid and in the frontpage context the role specified in $CFG->defaultfrontpageroleid.


==How to define new capabilities in plugins==
==How to define new capabilities in plugins==
Line 12: Line 12:


For example:
For example:
<code>
<code php>
  $capabilities = array(
  $capabilities = [
     'enrol/manual:manage' => array(
     'mod/folder:managefiles' => [
        'riskbitmask' => RISK_SPAM,
         'captype' => 'write',
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
         'contextlevel' => CONTEXT_MODULE,
         'archetypes' => array(
         'archetypes' => [
            'manager' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
             'editingteacher' => CAP_ALLOW,
         )
         ],
     ),
     ],
  );
  ];
</code>
</code>


Where the meaning of array keys is:
Where the meaning of array keys is:
* riskbitmask - associated risks. These are explained on [[Hardening new Roles system]].
* captype - ''read'' or ''write'' capability type, for security reasons system prevents all write capabilities for guest account and not-logged-in users
* captype - ''read'' or ''write'' capability type, for security reasons system prevents all write capabilities for guest account and not-logged-in users
* contextlevel - specified as context level constant, the lowest level where is this capability usable, plugins may hardcode exceptions if they use capability in more contexts
* contextlevel - specified as context level constant. Declares the typical context level where this capability is checked. This capability can be checked with contexts that are at a lower level (e.g. 'moodle/site:accessallgroups' - could be checked with CONTEXT_MODULE).
* archetypes - specifies defaults for roles with standard archetypes, this is used in installs, upgrades and when resetting roles (it is recommended to use only CAP_ALLOW here)
* archetypes - specifies defaults for roles with standard archetypes, this is used in installs, upgrades and when resetting roles (it is recommended to use only CAP_ALLOW here).  Archetypes are defined in mdl_role table.  See also [[Role archetypes]].
* clonepermissionsfrom - when you are adding a new capability, you can tell Moodle to copy the permissions for each role from the current settings for another capabilty. This may give better defaults than just using archetypes for administrators who have heavily customised their roles configuration. The full syntax is: <tt>'clonepermissionsfrom' => 'moodle/quiz:attempt',</tt>
* ''In releases before May 2012 clonepermissionsfrom works only inside individual plugins or only in core, in later releases plugins may also clone permissions from core, success of other cloning operations depends on upgrade order.''


It is necessary to bump up plugin version number after any change in db/access.php.
It is necessary to bump up plugin version number after any change in db/access.php, so that the upgrade scripts can make the necessary changes to the database. To run the upgrade scripts, log in to Moodle as administrator, navigate to the site home page, and follow the instructions.  (If you need to test the upgrade script without changing the plugin version, it is also possible to set back the version number in the mdl_block or mdl_modules table in the database.)


The capability names are defined in plugin language files, the name of the string consists of "pluginname:capabilityname", in the example above it would be:
The capability names are defined in plugin language files, the name of the string consists of "pluginname:capabilityname", in the example above it would be:
<code>
<code php>
$string['manual:manage'] = 'Manage user enrolments';
$string['folder:managefiles'] = 'Manage files in folder module';
</code>
</code>


Line 44: Line 47:


Fetching by object id:
Fetching by object id:
<code>
<code php>
$systemcontext = context_user::instance();
$systemcontext = context_system::instance();
$usercontext = context_user::instance($user->id);
$usercontext = context_user::instance($user->id);
$categorycontext = context_coursecat::instance($category->id);
$categorycontext = context_coursecat::instance($category->id);
$coursecontext = context_course::instance($course->id);
$coursecontext = context_course::instance($course->id);
$contextmodule = context_module::instance($cm->id);
$contextmodule = context_module::instance($cm->id);
$contextblock = context_block::instance($this->instance->id);
</code>
</code>


Fetching by context id:
Fetching by context id:
<code>
<code php>
$context = context::instance_by_id($contextid);
$context = context::instance_by_id($contextid);
</code>
</code>


Line 63: Line 67:


There are multiple deprecated context related functions since 2.2, it is not necessary to replace them immediately. The following two functions are equivalent to the context fetching examples above:
There are multiple deprecated context related functions since 2.2, it is not necessary to replace them immediately. The following two functions are equivalent to the context fetching examples above:
<code>
<code php>
function get_context_instance($contextlevel, $instance = 0, $strictness = IGNORE_MISSING)
function get_context_instance($contextlevel, $instance = 0, $strictness = IGNORE_MISSING)
function get_context_instance_by_id($id, $strictness = IGNORE_MISSING)
function get_context_instance_by_id($id, $strictness = IGNORE_MISSING)
</code>
</code>


===Determining that a user has a given capability===
===Determining that a user has a given capability===


When implementing access control always ask "Does the user have capability to do somethings?". It is incorrect to ask "Does the user have a role somewhere?".
When implementing access control always ask "Does the user have capability to do something?". It is incorrect to ask "Does the user have a role somewhere?".


The most important function is has_capability():
====has_capability()====
<code>
has_capability() is the most important function:
<code php>
  function has_capability($capability, context $context, $user = null, $doanything = true)
  function has_capability($capability, context $context, $user = null, $doanything = true)
</code>
</code>


Check whether a user has a particular capability in a given context. For example:
Check whether a user has a particular capability in a given context. For example:
<code>
<code php>
$context = context_module::instance($cm->id);
$context = context_module::instance($cm->id);
has_capability('mod/forum:replypost', $context)
if (has_capability('mod/folder:managefiles', $context)) {
    // Do or display something.
}
</code>
</code>


By default checks the capabilities of the current user, but you can pass a different userid. By default will return true for admin users, but you can override that with the fourth argument.
By default checks the capabilities of the current user, but you can pass a different userid. By default will return true for admin users, it is not recommended to use false here.


===Enrolment related functions===
====require_capability()====
Function require_capability() is very similar, it is throwing access control exception if user does not have the capability.


Since Moodle  2.2 there is a new concept of user enrolments, they are fully independent from the roles and capabilities, see [[Enrol API]] for more information.
<code php>
function require_capability($capability, context $context, $userid = null, $doanything = true, $errormessage = 'nopermissions', $stringfile = '') {
</code>


The capabilities are often used in combination with enrolment status - for example only enrolled students with a submit capability are allowed to submit assignments.
===Enrolment functions===


<code>
See [[Enrolment API]].
function is_enrolled(context $context, $user = null, $withcapability = '', $onlyactive = false)
function get_enrolled_sql(context $context, $withcapability = '', $groupid = 0, $onlyactive = false)
function get_enrolled_users(context $context, $withcapability = '', $groupid = 0, $userfields = 'u.*', $orderby = '', $limitfrom = 0, $limitnum = 0)
</code>


===Other related functions===
===Other related functions===


<code>
<code php>
  function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)
  function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)
  function require_course_login($courseorid, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)
  function require_course_login($courseorid, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)
function get_users_by_capability(context $context, $capability, $fields = '', $sort = '', $limitfrom = '', $limitnum = '',
                                  $groups = '', $exceptions = '', $doanything_ignored = null, $view_ignored = null, $useviewallgroups = false)
  function isguestuser($user = null)
  function isguestuser($user = null)
  function isloggedin()
  function isloggedin()
  function is_siteadmin($user_or_id = null)
  function is_siteadmin($user_or_id = null)
function is_guest(context $context, $user = null)
function is_viewing(context $context, $user = null, $withcapability = '')
</code>
</code>
====require_login()====
Each plugin script should include require_login() or require_course_login() after setting up PAGE->url.
This function does following:
* it verifies that user is logged in before accessing any course or activities (not-logged-in users can not enter any courses).
* user is logged in as gu
* verify access to hidden courses and activities
* if an activity is specified, verify any [[Availability API|availability restrictions]] for the activity
* verify that user is either enrolled or has capability 'moodle/course:view' or some enrol plugin gives them temporary guest access
* logs access to courses
====require_course_login()====
This function is supposed to be used only in activities that want to allow read access to content on the frontpage without logging-in. For example view resource files, reading of glossary  entries, etc.
====isguestuser(), isloggedin() and is_siteadmin()====
These function were previously needed for limiting of access of special accounts. It is usually not necessary any more, because any '''write''' or '''risky''' capabilities are now automatically prevented in has_capability().
It is strongly discouraged to use is_siteadmin() in activity modules, please use standard capabilities and enrolment status instead.
====is_guest(), is_viewing() and is_enrolled()====
In order to access course data one of these functions must return true for user:
* is_enrolled() - user has active record in user_enrolments table
* is_viewing() - user has 'moodle/course:view' capability (may access course, but is not considered to be participant)
* is_guest() - user was given temporary guest access by some enrolment plugin
====get_users_by_capability()====
This method returns list of users with given capability, it ignores enrolment status and should be used only above the course context.


==See also==
==See also==
* [[Core APIs]]
* [[Roles]]
* [[Role archetypes]]
* [[Hardening new Roles system]]
* [[Roles and modules]]
* [[NEWMODULE Adding capabilities]]
* [[NEWMODULE Adding capabilities]]
* [[Roles and modules]]
* [[New permissions evaluation in 2.0]]
* [[New permissions evaluation in 2.0]]
* [[Role archetypes]]
* [https://moodle.org/mod/forum/discuss.php?d=257611 (Forums) How to check if current user is student?]
* [[Roles]]
 
[[Category:API]]

Revision as of 07:17, 2 October 2020

Moodle 2.2 The Access API gives you functions so you can determine what the current user is allowed to do. It also allows modules to extend Moodle with new capabilities.

Overview

Moodle is using a role based access control model. Most entities in Moodle (system, users, course categories, courses, modules and blocks) are represented by contexts that are arranged in a tree like hierarchy called context tree. Role is a set of capability definitions, each capability usually represents an ability of user to do something. Roles are defined at the top most system context level. Role definitions can be overridden at lower context levels. User access control is calculated from the definitions of roles assigned to users.

All users that did not log-in yet automatically get the default role defined in $CFG->notloggedinroleid, it is not possible to assign any other role to this non-existent user id. There is one special guest user account that is used when user logs in using the guest login button or when guest autologin is enabled. Again you can not assign any roles to the guest account directly, this account gets the $CFG->guestroleid automatically. All other authenticated users get the default user role specified in $CFG->defaultuserroleid and in the frontpage context the role specified in $CFG->defaultfrontpageroleid.

How to define new capabilities in plugins

Capabilities are defined by $capabilities array defined in db/access.php files. The name of the capability consists of "plugintype/pluginname:capabilityname".

For example:

$capabilities = [
   'mod/folder:managefiles' => [
       'riskbitmask' => RISK_SPAM,
       'captype' => 'write',
       'contextlevel' => CONTEXT_MODULE,
       'archetypes' => [
           'editingteacher' => CAP_ALLOW,
       ],
   ],
];

Where the meaning of array keys is:

  • riskbitmask - associated risks. These are explained on Hardening new Roles system.
  • captype - read or write capability type, for security reasons system prevents all write capabilities for guest account and not-logged-in users
  • contextlevel - specified as context level constant. Declares the typical context level where this capability is checked. This capability can be checked with contexts that are at a lower level (e.g. 'moodle/site:accessallgroups' - could be checked with CONTEXT_MODULE).
  • archetypes - specifies defaults for roles with standard archetypes, this is used in installs, upgrades and when resetting roles (it is recommended to use only CAP_ALLOW here). Archetypes are defined in mdl_role table. See also Role archetypes.
  • clonepermissionsfrom - when you are adding a new capability, you can tell Moodle to copy the permissions for each role from the current settings for another capabilty. This may give better defaults than just using archetypes for administrators who have heavily customised their roles configuration. The full syntax is: 'clonepermissionsfrom' => 'moodle/quiz:attempt',
  • In releases before May 2012 clonepermissionsfrom works only inside individual plugins or only in core, in later releases plugins may also clone permissions from core, success of other cloning operations depends on upgrade order.

It is necessary to bump up plugin version number after any change in db/access.php, so that the upgrade scripts can make the necessary changes to the database. To run the upgrade scripts, log in to Moodle as administrator, navigate to the site home page, and follow the instructions. (If you need to test the upgrade script without changing the plugin version, it is also possible to set back the version number in the mdl_block or mdl_modules table in the database.)

The capability names are defined in plugin language files, the name of the string consists of "pluginname:capabilityname", in the example above it would be: $string['folder:managefiles'] = 'Manage files in folder module';

Useful functions and classes

Context fetching

In plugins context instances are usually only instantiated because they are instantiated and deleted automatically by the system.

Fetching by object id: $systemcontext = context_system::instance(); $usercontext = context_user::instance($user->id); $categorycontext = context_coursecat::instance($category->id); $coursecontext = context_course::instance($course->id); $contextmodule = context_module::instance($cm->id); $contextblock = context_block::instance($this->instance->id);

Fetching by context id: $context = context::instance_by_id($contextid);

Notes:

  • by default exception is thrown if context can not be created
  • deleted users do not have contexts any more


There are multiple deprecated context related functions since 2.2, it is not necessary to replace them immediately. The following two functions are equivalent to the context fetching examples above: function get_context_instance($contextlevel, $instance = 0, $strictness = IGNORE_MISSING) function get_context_instance_by_id($id, $strictness = IGNORE_MISSING)

Determining that a user has a given capability

When implementing access control always ask "Does the user have capability to do something?". It is incorrect to ask "Does the user have a role somewhere?".

has_capability()

has_capability() is the most important function:

function has_capability($capability, context $context, $user = null, $doanything = true)

Check whether a user has a particular capability in a given context. For example: $context = context_module::instance($cm->id); if (has_capability('mod/folder:managefiles', $context)) {

   // Do or display something.

}

By default checks the capabilities of the current user, but you can pass a different userid. By default will return true for admin users, it is not recommended to use false here.

require_capability()

Function require_capability() is very similar, it is throwing access control exception if user does not have the capability.

function require_capability($capability, context $context, $userid = null, $doanything = true, $errormessage = 'nopermissions', $stringfile = ) {

Enrolment functions

See Enrolment API.

Other related functions

function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)
function require_course_login($courseorid, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)
function get_users_by_capability(context $context, $capability, $fields = , $sort = , $limitfrom = , $limitnum = ,
                                 $groups = , $exceptions = , $doanything_ignored = null, $view_ignored = null, $useviewallgroups = false)
function isguestuser($user = null)
function isloggedin()
function is_siteadmin($user_or_id = null)
function is_guest(context $context, $user = null)
function is_viewing(context $context, $user = null, $withcapability = )

require_login()

Each plugin script should include require_login() or require_course_login() after setting up PAGE->url.

This function does following:

  • it verifies that user is logged in before accessing any course or activities (not-logged-in users can not enter any courses).
  • user is logged in as gu
  • verify access to hidden courses and activities
  • if an activity is specified, verify any availability restrictions for the activity
  • verify that user is either enrolled or has capability 'moodle/course:view' or some enrol plugin gives them temporary guest access
  • logs access to courses

require_course_login()

This function is supposed to be used only in activities that want to allow read access to content on the frontpage without logging-in. For example view resource files, reading of glossary entries, etc.

isguestuser(), isloggedin() and is_siteadmin()

These function were previously needed for limiting of access of special accounts. It is usually not necessary any more, because any write or risky capabilities are now automatically prevented in has_capability().

It is strongly discouraged to use is_siteadmin() in activity modules, please use standard capabilities and enrolment status instead.

is_guest(), is_viewing() and is_enrolled()

In order to access course data one of these functions must return true for user:

  • is_enrolled() - user has active record in user_enrolments table
  • is_viewing() - user has 'moodle/course:view' capability (may access course, but is not considered to be participant)
  • is_guest() - user was given temporary guest access by some enrolment plugin

get_users_by_capability()

This method returns list of users with given capability, it ignores enrolment status and should be used only above the course context.

See also