moodle笔记之-权限api
<?php
//权限定义
$capabilities = array(
'mod/mytest:managefiles' => array(//具体的权限:插件类型/插件名/权限 这里是增加一个实例
'riskbitmask' => RISK_SPAM,//该项权限对应的安全风险
'captype' => 'write',//权限类型:允许的读写能力
'contextlevel' => CONTEXT_MODULE,//上下文级别这里表示在模块场景生效
'archetypes' => array(
//给角色类型默认权限;指定角色的默认值默认值和标准原型。这被用于插件的安装、更新、和重置角色的时候。
//定义在mdl_role数据表中
'editingteacher' => CAP_ALLOW
)
//当你想添加一个新的权限时,你可以让moodle复制在其中定义的所有角色的当前权限的集合。在定义一些较为庞大的权限时(例如管理员权限),这可能比使用archetypes要更方便。他的语法形如:'clonepermissionsfrom' => 'moodle/quiz:attempt'。
),
);
权限的名称被定义在插件的语言包中,其命名规则为”插件名:权限名”。例如:
$string['mytest:managefiles'] = 'Manage files in folder module';
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ +
//+ +
//+ 角色类型默认权限 +
//+ +
//+ +
//+ +
//+ +
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
默认角色的caps
默认角色分配DB,所以我们手动添加到accessdata。
这意味着函数工作直接从DB需要确保默认角色caps会妥善处理
(角色)原型:
CAP_INHERITL:不知道父级能干我就能干???
CAP_ALLOW:能做事
CAP_PREVENT:不能做事
CAP_PROHIBIT:不能做事还不能让孩子级做事
define('CAP_INHERIT', 0);//没有改变的权利
define('CAP_ALLOW', 1);/*允许权限,覆盖定义在父级上下文 的CAP_PREVENT*/
define('CAP_PREVENT', -1);/*防止权限,覆盖定义在父级上下文的CAP_ALLOW */
define('CAP_PROHIBIT', -1000); /*禁止权限,覆盖当前和孩子上下文的一切 */
上下文级别目前是6个
CONTEXT_SYSTEM:整个网站
CONTEXT_USER: 另一个用户
CONTEXT_COURSECAT:课程类别
CONTEXT_COURSE:课程类别
CONTEXT_MODULE:活动模块
CONTEXT_BLOCK:版块
define('CONTEXT_SYSTEM',10);
define('CONTEXT_USER',30);
define('CONTEXT_COURSECAT',40);
define('CONTEXT_COURSE',50);
define('CONTEXT_MODULE',70);
define('CONTEXT_BLOCK',80);
'riskbitmask' => RISK_SPAM ,: 该项权限对应的安全风险
// 硬化的作用,是指限制一个角色的分配或将获得权限的能力。
RISK_SPAM -用户可以看到添加到网站的内容(其他人可能会看到允许用户添加内容),发送消息给其他用户; 最初由!isguest保护()
RISK_PERSONAL -进入私人的个人信息-例如:备份与用户的详细信息,在个人资料(隐藏电子邮件)非公开信息等; 最初由isteacher保护()允许访问的个人用户信息
RISK_XSS -用户可以提交没有清理(包括HTML与活动内容和未受保护的文件)的内容; 最初由isteacher保护()
RISK_CONFIG -用户可以改变全局配置,行动缺少理性检查(允许系统配置的变化)
RISK_MANAGETRUST -其他用户的信任管理的位屏蔽(位掩码);允许管理的信托
RISK_DATALOSS -可以破坏大量的信息,可以不容易被回收。允许集中的大规模的删除属于其他用户的数据
moodle_context表
id contextlevel instanceid path depth
1 10 0 /1 1
2 50 1 /1/2 2
3 40 1 /1/3 2
4 30 1 /1/4 2
5 30 2 /1/5 2
6 80 1 /1/2/6 3
8 80 3 /1/2/8 3
9 80 4 /1/9 2
10 80 5 /1/10 2
11 80 6 /1/11 2
12 80 7 /1/12 2
24 40 2 /1/24 2
25 40 3 /1/25 2
26 50 2 /1/25/26 3
27 80 19 /1/25/26/27 4
46 50 6 /1/25/46 3
51 70 1 /1/25/46/51 4
115 30 54 /1/115 2
116 30 55 /1/116 2
117 30 56 /1/117 2
120 70 2 /1/25/46/120 4
121 70 3 /1/25/46/121 4
122 70 4 /1/25/46/122 4
contextlevel:资源类型
CONTEXT_SYSTEM=10
CONTEXT_USER=30
CONTEXT_COURSECAT=40
CONTEXT_COURSE=50 代表课程
CONTEXT_MODULE=70 代表module
CONTEXT_BLOCK=80 代表板块
instanceid 资源id号 代表contextlevel对应的数据表中的id
如:id为 120-122 的 contextlevel 为 70 代表的是它们分别对应板块的block_instance表中的id为 2-3 于是在block_instance表中的blockanme字段可以知道他们属于哪个模块
当我创建了一个课程(manualy)plataform变化至少3表:mdl_block_instance,mdl_course mdl_context。
mdl_course包含关于课程的信息(属性)。mdl_context所得新记录表明什么类型的上下文是新的即instance_id,也就是说,当我创建了一个课程,是表将创造了新的纪录contextlevel 50(这意味着th)和instanceid courseid等于新课程
注:contextlevel就是一个类型,instance就是一个资源id号,取这个种字段名实在难以理解,直接改为resourcetype,resourceid,就不用再费这三个小时去查找它的意思了。
官方直接把这几种资源类型称之为六个level,这样也就不难理解它的名字了。
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ +
//+ +
//+ 上下文获取 +
//+ +
//+ +
//+ +
//+ +
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
在lib\accesslib.php中context_system 类继承 context类
context的子类:
1、context_system:系统环境
方法:
1)protected function __construct(stdClass $record) {
parent::__construct($record);
if ($record->contextlevel != CONTEXT_SYSTEM) {
throw new coding_exception('Invalid $record->contextlevel in context_system constructor.');
}
}
2)get_level_name()静态方法:返回人类可读的环境级别名称(返回System字符串)
3)get_context_name()返回人类可读的上下文标识符(环境名称)
4) public function get_url() {
return new moodle_url('/');
}
5)get_capabilities()返回相关上下文权限的记录的数组相当于select * from mdl_capabilities ORDER BY contextlevel,component,name;
6)create_level_instances()在系统上下文创建缺失的上下文实例即该方法里调用instance静态方法、
7)instance($instanceid = 0, $strictness = MUST_EXIST, $cache = true):返回系统上下文实例
8)get_child_contexts():返回所有网站的上下文除了系统上下文(环境),不调用在生产服务器上、
SELECT * FROM mdl_context WHERE contextlevel > CONTEXT_SYSTEM (值为10);(id数组??)
9) get_cleanup_sql():返回sql必要的清除陈旧的上下文实例清除sql返回SELECT c.*FROM mdl_context c WHERE 1=2
10)build_paths($force):在系统上下文级别重建上下文路径和深度
2、
在插件中,上下文的实体往往是唯一的。因为他们会被系统自动实例化和删除。
通过对象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);加载模块
请注意,CONTEXT_PERSONAL(目前在1.7-1.8)从未付诸实施,并在1.9已被删除。CONTEXT_GROUP还没有实现,并且不能使用。
通过上下文id获取:
$context = context::instance_by_id($contextid);
如果上下文不能正常创建会抛出异常
被删除的用户不会再有上下文
判断(检查)某个用户是否具有指定的权限:has_capability():
$context = context_module::instance($cm->id);
has_capability($capability, context $context, $user = null, $doanything = true)
如果为false就会忽略管理角色分配的影响
has_capability('mod/folder:managefiles', $context)
默认情况下上述代码是在检查当前用户的权限,当然你也可以传入用户id用以检查指定用户的权限如has_capability($capability,$context,$otheruser->id);
一般来说,在检查管理员的所有权限时,都应该返回true,在写代码时应注意这一点。
require_capability()函数也是很常见的,它会在用户没有该项权限时抛出访问控制异常(access control exception)。
其他相关的函数
每个插件脚本在设置了$PAGE->url之后,都应该执行require_login或require_course_login。
function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true,$preventredirect = false)
这个函数做了以下几件事:
它确保用户在访问任何一门课程或活动时都是已经登录的(未登录的用户不能进入任何课程)
用户是否以访客身份登录
验证用户是否具有访问隐藏的课程和活动的权限
验证访问具有experimental groupmembersonly 权限的内容
验证用户是否已选课或者具有'moodle/course:view'权限或者是在访问一些允许访客浏览的内容
添加用户访问该课程的log记录
function require_course_login($courseorid, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false)
这个函数应该只用于活动(activities)中,它会允许用户读取首页的内容而不会在log日志中记录。例如浏览资源文件、阅读词条列表等等。
function get_users_by_capability(context $context, $capability, $fields = '', $sort = '', $limitfrom = '', $limitnum = '',
$groups = '', $exceptions = '', $doanything_ignored = null, $view_ignored = null, $useviewallgroups = false)
它会返回具有某种权限的所有用户的列表。它会忽略选课信息,因此只应在课程上下文之上被使用。
isguestuser(), isloggedin() and is_siteadmin()
这些函数在过去需要首先限制特殊账户的访问。现在已经不需要了。因为任何具有写权限或者有风险的权限都已经在has_capability()中自动了规避了这些用户。
强烈建议在活动(activity)模块中使用 is_siteadmin(),否则请务必准确地使用权限和选课信息。
function isguestuser($user = null)
function isloggedin()
function is_siteadmin($user_or_id = null)
is_guest(), is_viewing() and is_enrolled()
为了访问课程的数据,这些函数中至少要有一个返回true
is_enrolled(): 用户在user_enrolments表中有活动记录
is_viewing(): 用户具有’moodle/course:view’权限(可以访问,但不是参与者)
is_guest(): 访客用户被一些课程模块允许暂时访问
function is_guest(context $context, $user = null)
function is_viewing(context $context, $user = null, $withcapability = '')
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ +
//+ +
//+ 上下文(环境)处理 +
//+ +
//+ +
//+ +
//+ +
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* - context_course::instance($courseid), context_module::instance($cm->id), context_coursecat::instance($catid)
* - context::instance_by_id($contextid)
* - $context->get_parent_contexts();
* - $context->get_child_contexts();
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ +
//+ +
//+ 用户是否可以做一些… +
//+ +
//+ +
//+ +
//+ +
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* - has_capability()
* - has_any_capability()
* - has_all_capabilities()
* - require_capability()
* - require_login() (from moodlelib)
* - is_enrolled()
* - is_viewing()
* - is_guest()
* - is_siteadmin()
* - isguestuser()
* - isloggedin()
这个用户访问什么课程?
* - get_enrolled_users()
在这里用户可以做什么?
* - get_enrolled_users() - at and bellow course context
* - get_users_by_capability() - above course context
修改角色
* - role_assign()
* - role_unassign()
* - role_unassign_all()
高级——仅供内部使用
* - load_all_capabilities()
* - reload_all_capabilities()
* - has_capability_in_accessdata()
* - get_user_access_sitewide()
* - load_course_context()
* - load_role_access_by_context()
* - etc.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ +
//+ +
//+ 命名约定 +
//+ +
//+ +
//+ +
//+ +
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
“ctx”指上下文
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ +
//+ +
//+ 建立数据库角色 +
//+ +
//+ +
//+ +
//+ +
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
访问控制数据保存在“accessdata”数组中——登录的用户,将会在$USER->access
其他用户可以生成和传递(但也可能是缓存针对在$ACCESSLIB_PRIVATE->accessdatabyuser里的userid )。
$accessdata是一个多维数组,角色分配(RAs),role-capabilities-perm集(角色defs)和一个课程列表加载数据。
键入的“ contextpaths ” (上下文表的路径字段)为了快速走升(向上)/降(向下)树
代码:
* $accessdata['ra'][$contextpath] = array($roleid=>$roleid)
* [$contextpath] = array($roleid=>$roleid)
* [$contextpath] = array($roleid=>$roleid)
角色就像这样定义存储:
* $accessdata['rdef']["$contextpath:$roleid"]['mod/forum:viewpost'] = 1
* ['mod/forum:editallpost'] = -1
* ['mod/forum:startdiscussion'] = -1000
看has_capability_in_accessdata()怎样走到那棵树。
首先我们只加载rdef和ra级别,但不低于。
这使得accessdata小而紧凑。Below-the-course ra/ rdef根据需要加载。我们跟踪的加载ra / rdef的课程
* $accessdata['loaded'] = array($courseid1=>1, $courseid2=>1)
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+ +
//+ +
//+ 过期accessdata +
//+ +
//+ +
//+ +
//+ +
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
登录用户,accessdata长寿
我们在每个页面加载负载$ACCESSLIB_PRIVATE -> dirtycontexts列表上下文路径被影响通过变化。任何检查达到或者低于一个肮脏的环境将触发一个透明accessdata重载。
在系统级别的变化将迫使每个人的重载。
/*
??字段的缩写??
protected static $coursecatfields = array(
'id' => array('id', 0),
'name' => array('na', ''),
'idnumber' => array('in', null),
'description' => null, // Not cached.
'descriptionformat' => null, // Not cached.
'parent' => array('pa', 0),
'sortorder' => array('so', 0),
'coursecount' => array('cc', 0),
'visible' => array('vi', 1),
'visibleold' => null, // Not cached.
'timemodified' => null, // Not cached.
'depth' => array('dh', 1),
'path' => array('ph', null),
'theme' => null, // Not cached.
);
*/
//定义$capabilities = array()的文件:
//1\moodle\admin\roles\classes\capability_table_base.php:
//admin\settings\appearance.php:
//admin\settings\courses.php:
//admin\tool\capability\index.php:
//admin\tool\customlang\db\access.php:
//\admin\tool\monitor\db\access.php:
//admin\tool\uploaduser\db\access.php
//blocks下的\db\access.php:
//course\management.php:
//course\search.php:
//\enrol下的\db\access.php:
//grade\下的db\access.php:
//
//
//
//moodle\lib\accesslib.php:这个文件包含用于管理用户访问的功能
//moodle\lib\coursecatlib.php:包含类coursecat为课程类别负责操作
//lib\db\access.php:Moodle核心能力定义。
//
//
//
//local\下的\db\access.php:
//moodle\message\output\airnotifier\db\access.php:
//moodle\mod\下的\db\access.php:
//moodle\report\下的\db\access.php:
//moodle\repository\下的\db\access.php:
//webservice\下的\db\access.php: