]> git.mjollnir.org Git - moodle.git/commitdiff
adding functions and interface for access control - role assignment and role overrides
authortoyomoyo <toyomoyo>
Fri, 18 Aug 2006 08:01:16 +0000 (08:01 +0000)
committertoyomoyo <toyomoyo>
Fri, 18 Aug 2006 08:01:16 +0000 (08:01 +0000)
admin/roles/allowassign.php [new file with mode: 0755]
admin/roles/allowoverride.php [new file with mode: 0755]
admin/roles/assign.php
admin/roles/manage.php
admin/roles/managetabs.php [new file with mode: 0755]
admin/roles/override.php
lib/accesslib.php
lib/db/access.php

diff --git a/admin/roles/allowassign.php b/admin/roles/allowassign.php
new file mode 100755 (executable)
index 0000000..1c55b20
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+/**
+ * this page defines what roles can access (grant user that role and override that roles' 
+ * capabilities in different context. For example, we can say that Teachers can only grant 
+ * student role or modify student role's capabilities. Note that you need both the right
+ * capability moodle/roles:assign or moodle/roles:manage and this database table roles_deny_grant
+ * to be able to grant roles. If a user has moodle/roles:manage at site level assignment
+ * then he can modify the roles_allow_assign table via this interface.
+ */
+    require_once('../../config.php');
+/// check capabilities here
+
+    $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
+    require_capability('moodle/roles:manage', $sitecontext);
+
+    $site = get_site();
+    $stradministration = get_string('administration');
+    $strmanageroles = get_string('manageroles');
+    
+/// form processiong here
+
+/// get all roles
+    $roles = get_records('role');
+
+    if ($grant = data_submitted()) {
+      
+        foreach ($grant as $grole => $val) {
+            if ($grole == 'dummy') {
+                continue;  
+            }
+          
+            $string = explode('_', $grole);
+            $temp[$string[1]][$string[2]] = 1; // if set, means can access
+        }
+
+// if current assignment is in data_submitted, ignore, else, write deny into db
+        foreach ($roles as $srole) {
+            foreach ($roles as $trole) {
+                if (isset($temp[$srole->id][$trole->id])) { // if set, need to write to db
+                    if (!$record = get_record('role_allow_assign', 'roleid', $srole->id, 'allowassign', $trole->id)) {
+                        $record->roleid = $srole->id;
+                        $record->allowassign = $trole->id;
+                        insert_record('role_allow_assign', $record);
+                    }
+                } else { //if set, means can access, attempt to remove it from db
+                    delete_records('role_allow_assign', 'roleid', $srole->id, 'allowassign', $trole->id);
+                }  
+            }
+        }
+    }
+/// displaying form here
+
+    print_header("$site->shortname: $strmanageroles", 
+                 "$site->fullname", 
+                 "<a href=\"../index.php\">$stradministration</a> -> <a href=\"manage.php\">$strmanageroles</a>
+                 ");
+                 
+    $currenttab='allowassign';
+    require_once('managetabs.php');
+
+    $table->tablealign = "center";
+    $table->align = array ("middle", "left");
+    $table->wrap = array ("nowrap", "nowrap");
+    $table->cellpadding = 5;
+    $table->cellspacing = 0;
+    $table->width = '40%';
+    
+/// get all the roles identifier
+    foreach ($roles as $role) {
+        $rolesname[] = $role->name;  
+        $roleids[] = $role->id;
+    }    
+    
+    $table->data[] = array_merge(array(''), $rolesname);
+    
+    foreach ($roles as $role) {
+        
+        $beta = get_box_list($role->id, $roleids);
+    
+        $table->data[] = array_merge(array($role->name), $beta);
+    }
+    
+    echo '<form action="allowassign.php" method="post">';
+    print_table($table);
+    echo '<div align="center"><input type="submit" value="submit"/></div>';
+    echo '<input type="hidden" name="dummy" value="1" />'; // this is needed otherwise we do not know a form has been submitted
+    echo '</form>';
+
+    print_footer();
+
+// returns array
+function get_box_list($roleid, $arraylist){
+    
+    foreach ($arraylist as $targetid) {
+        if (get_record('role_allow_assign', 'roleid', $roleid, 'allowassign', $targetid)) {
+            $array[] = '<input type="checkbox" name="s_'.$roleid.'_'.$targetid.'" value="1" checked="checked"/>';
+        } else {
+            $array[] = '<input type="checkbox" name="s_'.$roleid.'_'.$targetid.'" value="1" />';              
+        }
+    }
+    return $array;
+}
+?>
\ No newline at end of file
diff --git a/admin/roles/allowoverride.php b/admin/roles/allowoverride.php
new file mode 100755 (executable)
index 0000000..d35e52e
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+/**
+ * this page defines what roles can override (override roles in different context. For example, 
+ * we can say that Admin can override teacher roles in a course
+ * To be able to override roles. If a user has moodle/roles:overrde at context level
+ * and be in the roles_allow_override table.
+ */
+    require_once('../../config.php');
+/// check capabilities here
+
+    $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
+    require_capability('moodle/roles:manage', $sitecontext);
+
+    $site = get_site();
+    $stradministration = get_string('administration');
+    $strmanageroles = get_string('manageroles');
+    
+/// form processiong here
+
+/// get all roles
+    $roles = get_records('role');
+
+    if ($grant = data_submitted()) {
+      
+        foreach ($grant as $grole => $val) {
+            if ($grole == 'dummy') {
+                continue;  
+            }
+          
+            $string = explode('_', $grole);
+            $temp[$string[1]][$string[2]] = 1; // if set, means can access
+        }
+
+// if current assignment is in data_submitted, ignore, else, write deny into db
+        foreach ($roles as $srole) {
+            foreach ($roles as $trole) {
+                if (isset($temp[$srole->id][$trole->id])) { // if set, need to write to db
+                    if (!$record = get_record('role_allow_override', 'roleid', $srole->id, 'allowoverride', $trole->id)) {
+                        $record->roleid = $srole->id;
+                        $record->allowoverride = $trole->id;
+                        insert_record('role_allow_override', $record);
+                    }
+                } else { //if set, means can access, attempt to remove it from db
+                    delete_records('role_allow_override', 'roleid', $srole->id, 'allowoverride', $trole->id);
+                }  
+            }
+        }
+    }
+/// displaying form here
+
+    print_header("$site->shortname: $strmanageroles", 
+                 "$site->fullname", 
+                 "<a href=\"../index.php\">$stradministration</a> -> <a href=\"manage.php\">$strmanageroles</a>
+                 ");
+                 
+    $currenttab='allowoverride';
+    require_once('managetabs.php');
+
+    $table->tablealign = "center";
+    $table->align = array ("middle", "left");
+    $table->wrap = array ("nowrap", "nowrap");
+    $table->cellpadding = 5;
+    $table->cellspacing = 0;
+    $table->width = '40%';
+    
+/// get all the roles identifier
+    foreach ($roles as $role) {
+        $rolesname[] = $role->name;  
+        $roleids[] = $role->id;
+    }    
+    
+    $table->data[] = array_merge(array(''), $rolesname);
+    
+    foreach ($roles as $role) {
+        
+        $beta = get_box_list($role->id, $roleids);
+    
+        $table->data[] = array_merge(array($role->name), $beta);
+    }
+    
+    echo '<form action="allowoverride.php" method="post">';
+    print_table($table);
+    echo '<div align="center"><input type="submit" value="submit"/></div>';
+    echo '<input type="hidden" name="dummy" value="1" />'; // this is needed otherwise we do not know a form has been submitted
+    echo '</form>';
+
+    print_footer();
+
+// returns array
+function get_box_list($roleid, $arraylist){
+    
+    foreach ($arraylist as $targetid) {
+        if (get_record('role_allow_override', 'roleid', $roleid, 'allowoverride', $targetid)) {
+            $array[] = '<input type="checkbox" name="s_'.$roleid.'_'.$targetid.'" value="1" checked="checked"/>';
+        } else {
+            $array[] = '<input type="checkbox" name="s_'.$roleid.'_'.$targetid.'" value="1" />';              
+        }
+    }
+    return $array;
+}
+?>
\ No newline at end of file
index a648d455dfcc0d70881fbcf4acbdbff6b962eaa1..663685d37402e9fcc4a18e9879140163db62242b 100755 (executable)
 
     $context = get_record('context', 'id', $contextid);
     
+    // role assigning permission checking
+    if ($roleid) {
+        if (!user_can_assign($context, $roleid)) {
+            error ('you can not override this role in this context');
+        }  
+    }
+    
     $participants = get_string("participants");
     $user = get_record('user', 'id', $userid);
     $fullname = fullname($user, isteacher($course->id));
     // this needs to check capability too
     $role = get_records('role');
     foreach ($role as $rolex) {
-        $options[$rolex->id] = $rolex->name;
+        if (user_can_assign($context, $rolex->id)) {
+            $options[$rolex->id] = $rolex->name;
+        }
     }
     
     // prints a form to swap roles
index c184cb1221886f54a1ef3e0322d5193a6a6b692e..044aa62bc909c48fa41425ab336b1b2fe4f7948c 100755 (executable)
@@ -41,6 +41,9 @@
 //                 $editingstr
 //                 ");
 
+    $currenttab = 'manage';
+    include_once('managetabs.php');
+
     // form processing, editing a role, adding a role or deleting a role
     if ($action && confirm_sesskey()) {
         
diff --git a/admin/roles/managetabs.php b/admin/roles/managetabs.php
new file mode 100755 (executable)
index 0000000..5cb61ee
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+// this page deals with the 2 tabs for manage.php and grant.php
+
+    $toprow[] = new tabobject('manage', $CFG->wwwroot.'/admin/roles/manage.php', get_string('manage'));
+    
+    $toprow[] = new tabobject('allowassign', $CFG->wwwroot.'/admin/roles/allowassign.php', get_string('allowassign'));
+
+    $toprow[] = new tabobject('allowoverride', $CFG->wwwroot.'/admin/roles/allowoverride.php', get_string('allowoverride'));
+    
+    $tabs = array($toprow);
+    
+    print_tabs($tabs, $currenttab);
+
+?>
index e7fd3829a0eaa39b7bd22b09a9203edfaf4c220a..4bb1ff63f7f6aedd781f5d5ebd9ea788732f06f6 100755 (executable)
 
     $context = get_record('context', 'id', $contextid);
     
+    // role overriding permission checking
+    if ($roleid) {
+        if (!user_can_override($context, $roleid)) {
+            error ('you can not override this role in this context');
+        }  
+    }
+    
     $participants = get_string("participants");
     $user = get_record('user', 'id', $userid);
     $fullname = fullname($user, isteacher($course->id));
      // this needs to check capability too
     $role = get_records('role');
     foreach ($role as $rolex) {
-        $options[$rolex->id] = $rolex->name;
+        if (user_can_override($context, $rolex->id)) {
+            $options[$rolex->id] = $rolex->name;
+        }
     }
 
     print ('<form name="rolesform" action="override.php" method="post">');
index a69641872631773a13f0d7ac915218041d298337..064e8e61b8e7b222113a07de95205b688c687b22 100755 (executable)
@@ -1599,4 +1599,58 @@ function get_user_roles_in_context($userid, $contextid){
     }
     return rtrim($rolestring, ', ');
 }
+
+
+// returns bool
+function user_can_override($context, $targetroleid) {
+    // first check if user has override capability
+    // if not return false;
+    if (!has_capability('moodle/role:override', $context)) {
+        return false;  
+    }
+    // pull out all active roles of this user from this context(or above)
+    $userroles = get_user_roles($context);
+    foreach ($userroles as $userrole) {
+        // if any in the role_allow_override table, then it's ok
+        if (get_record('role_allow_override', 'roleid', $userrole->roleid, 'allowoverride', $targetroleid)) {
+            return true;
+        }
+    }
+    
+    return false;
+  
+}
+
+function user_can_assign($context, $targetroleid) {
+    
+    // first check if user has override capability
+    // if not return false;
+    if (!has_capability('moodle/role:assign', $context)) {
+        return false;  
+    }
+    // pull out all active roles of this user from this context(or above)
+    $userroles = get_user_roles($context);
+    foreach ($userroles as $userrole) {
+        // if any in the role_allow_override table, then it's ok
+        if (get_record('role_allow_assign', 'roleid', $userrole->roleid, 'allowassign', $targetroleid)) {
+            return true;
+        }
+    }
+    
+    return false; 
+}
+
+// gets all the user roles assigned in this context, or higher
+function get_user_roles($context) {
+
+    global $USER, $CFG, $db;
+    
+    $parents = get_parent_contexts($context);
+    $parentlists = '('.implode(',' , $parents).')';
+    return get_records_sql('SELECT *
+                             FROM '.$CFG->prefix.'role_assignments ra
+                             WHERE ra.userid = '.$USER->id.'
+                             AND ra.contextid IN '.$parentlists);
+}
+
 ?>
index 0a33d47a93817f2fc66765e6e3a58c5956c6a3ae..bc1917a9fad5394aa3b7a8809f64305f55b2f731 100644 (file)
@@ -256,6 +256,20 @@ $moodle_capabilities = array(
         )
     ),
     
+    'moodle/role:override' => array(
+    
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_SYSTEM,
+        'legacy' => array(
+            'guest' => CAP_PREVENT,
+            'student' => CAP_PREVENT,
+            'teacher' => CAP_PREVENT,
+            'editingteacher' => CAP_PREVENT,
+            'coursecreator' => CAP_PREVENT,
+            'admin' => CAP_ALLOW
+        )
+    ),
+    
     'moodle/role:manage' => array(
     
         'captype' => 'write',