Esempio n. 1
0
/**
 * Call to complete the user login process after authenticate_user_login()
 * has succeeded. It will setup the $USER variable and other required bits
 * and pieces.
 *
 * NOTE:
 * - It will NOT log anything -- up to the caller to decide what to log.
 *
 *
 *
 * @uses $CFG, $USER
 * @param string $user obj
 * @return user|flase A {@link $USER} object or false if error
 */
function complete_user_login($user)
{
    global $CFG, $USER;
    $USER = $user;
    // this is required because we need to access preferences here!
    if (!empty($CFG->regenloginsession)) {
        // please note this setting may break some auth plugins
        session_regenerate_id();
    }
    reload_user_preferences();
    update_user_login_times();
    if (empty($CFG->nolastloggedin)) {
        set_moodle_cookie($USER->username);
    } else {
        // do not store last logged in user in cookie
        // auth plugins can temporarily override this from loginpage_hook()
        // do not save $CFG->nolastloggedin in database!
        set_moodle_cookie('nobody');
    }
    set_login_session_preferences();
    // Call enrolment plugins
    check_enrolment_plugins($user);
    /// This is what lets the user do anything on the site :-)
    load_all_capabilities();
    /// Select password change url
    $userauth = get_auth_plugin($USER->auth);
    /// check whether the user should be changing password
    if (get_user_preferences('auth_forcepasswordchange', false)) {
        if ($userauth->can_change_password()) {
            if ($changeurl = $userauth->change_password_url()) {
                redirect($changeurl);
            } else {
                redirect($CFG->httpswwwroot . '/login/change_password.php');
            }
        } else {
            print_error('nopasswordchangeforced', 'auth');
        }
    }
    return $USER;
}
Esempio n. 2
0
        } else {
            if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) {
                $urltogo = $SESSION->wantsurl;
                /// Because it's an address in this site
                unset($SESSION->wantsurl);
            } else {
                $urltogo = $CFG->wwwroot . '/';
                /// Go to the standard home page
                unset($SESSION->wantsurl);
                /// Just in case
            }
        }
        /// Go to my-moodle page instead of homepage if mymoodleredirect enabled
        if (!has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)) and !empty($CFG->mymoodleredirect) and !isguest()) {
            if ($urltogo == $CFG->wwwroot or $urltogo == $CFG->wwwroot . '/' or $urltogo == $CFG->wwwroot . '/index.php') {
                $urltogo = $CFG->wwwroot . '/my/';
            }
        }
        check_enrolment_plugins($USER);
        load_all_capabilities();
        /// This is what lets the user do anything on the site  :-)
        redirect($urltogo);
        exit;
    } else {
        // For some weird reason the Shibboleth user couldn't be authenticated
    }
} elseif (!empty($_SERVER['HTTP_SHIB_APPLICATION_ID']) || !empty($_SERVER['Shib-Application-ID'])) {
    print_error('shib_no_attributes_error', 'auth', '', '\'' . $pluginconfig->user_attribute . '\', \'' . $pluginconfig->field_map_firstname . '\', \'' . $pluginconfig->field_map_lastname . '\' and \'' . $pluginconfig->field_map_email . '\'');
} else {
    print_error('shib_not_set_up_error', 'auth');
}
Esempio n. 3
0
/**
 * Setup $USER object - called during login, loginas, etc.
 * Preloads capabilities and checks enrolment plugins
 *
 * @param object $user full user record object
 * @return void
 */
function session_set_user($user)
{
    $_SESSION['USER'] = $user;
    unset($_SESSION['USER']->description);
    // conserve memory
    if (!isset($_SESSION['USER']->access)) {
        // check enrolments and load caps only once
        check_enrolment_plugins($_SESSION['USER']);
        load_all_capabilities();
    }
    sesskey();
    // init session key
}
Esempio n. 4
0
/**
 *  A convenience function to completely load all the capabilities 
 *  for the current user.   This is what gets called from login, for example.
 */
function load_all_capabilities()
{
    global $USER, $CFG;
    $base = '/' . SYSCONTEXTID;
    if (isguestuser()) {
        $guest = get_guest_role();
        // Load the rdefs
        $USER->access = get_role_access($guest->id);
        // Put the ghost enrolment in place...
        $USER->access['ra'][$base] = array($guest->id);
    } else {
        if (isloggedin()) {
            check_enrolment_plugins($USER);
            $accessdata = get_user_access_sitewide($USER->id);
            //
            // provide "default role" & set 'dr'
            //
            if (!empty($CFG->defaultuserroleid)) {
                $accessdata = get_role_access($CFG->defaultuserroleid, $accessdata);
                if (!isset($accessdata['ra'][$base])) {
                    $accessdata['ra'][$base] = array($CFG->defaultuserroleid);
                } else {
                    array_push($accessdata['ra'][$base], $CFG->defaultuserroleid);
                }
                $accessdata['dr'] = $CFG->defaultuserroleid;
            }
            $frontpagecontext = get_context_instance(CONTEXT_COURSE, SITEID);
            //
            // provide "default frontpage role"
            //
            if (!empty($CFG->defaultfrontpageroleid)) {
                $base = '/' . SYSCONTEXTID . '/' . $frontpagecontext->id;
                $accessdata = get_default_frontpage_role_access($CFG->defaultfrontpageroleid, $accessdata);
                if (!isset($accessdata['ra'][$base])) {
                    $accessdata['ra'][$base] = array($CFG->defaultfrontpageroleid);
                } else {
                    array_push($accessdata['ra'][$base], $CFG->defaultfrontpageroleid);
                }
            }
            $USER->access = $accessdata;
        } else {
            if (!empty($CFG->notloggedinroleid)) {
                $USER->access = get_role_access($CFG->notloggedinroleid);
                $USER->access['ra'][$base] = array($CFG->notloggedinroleid);
            }
        }
    }
    // Timestamp to read
    // dirty context timestamps
    $USER->access['time'] = time();
    // Clear to force a refresh
    unset($USER->mycourses);
}
Esempio n. 5
0
function teosso_authenticate_user()
{
    global $CFG, $USER, $SESSION;
    $pluginconfig = get_config('auth/teosso');
    // retrieve the login data from the HTTP Headers
    $attributes = auth_plugin_teosso::get_sso_attributes();
    // check to see if we got any authentication data
    if (empty($attributes)) {
        redirect($pluginconfig->signin_url);
    }
    // get the http headers for error reporting
    $headers = apache_request_headers();
    $attr_hdrs = array();
    foreach ($headers as $key => $value) {
        if (preg_match('/^HTTP_/', $key)) {
            $attr_hdrs[] = $key . ': ' . $value;
        }
    }
    $headers = implode(' | ', $attr_hdrs);
    // FIND THE VALIDIDTY OF THE HTTP HEADER
    $attrmap = auth_plugin_teosso::get_attributes();
    if (empty($attrmap['idnumber'])) {
        // serious misdemeanour
        print_error('missingidnumber', 'auth_teosso');
    }
    if (empty($attributes[$attrmap['idnumber']])) {
        #
        // not valid session. Ship user off to Federation Manager
        add_to_log(0, 'login', 'error', '/auth/teosso/index.php', get_string('idnumber_error', 'auth_teosso', $headers));
        redirect($pluginconfig->signin_error_url);
    } else {
        // in theory we only need acct_id at this point - we should retrieve the user record to get the username via idnumber
        if (!($user = get_record('user', 'idnumber', $attributes[$attrmap['idnumber']]))) {
            // must be a new user
            if (!empty($attributes[$attrmap['username']])) {
                $attributes['username'] = $attributes[$attrmap['username']];
            } else {
                add_to_log(0, 'login', 'error', '/auth/teosso/index.php', get_string('username_error', 'auth_teosso', $headers));
                redirect($pluginconfig->signin_error_url);
            }
        } else {
            // user must use the auth type teosso or authenticate_user_login() will fail
            if ($user->auth != 'teosso') {
                add_to_log(0, 'login', 'error', '/auth/teosso/index.php', get_string('user_auth_type_error', 'auth_teosso', $headers));
                redirect($pluginconfig->signin_error_url);
            }
            // because we want to retain acct_id as the master ID
            // we need to modify idnumber on mdl_user NOW - so it all lines up later
            if (isset($attributes[$attrmap['username']]) && $user->username != $attributes[$attrmap['username']]) {
                if (!set_field('user', 'username', $attributes[$attrmap['username']], 'id', $user->id)) {
                    print_error('usernameupdatefailed', 'auth_teosso');
                }
                $attributes['username'] = $attributes[$attrmap['username']];
            } else {
                $attributes['username'] = $user->username;
            }
        }
        // Valid session. Register or update user in Moodle, log him on, and redirect to Moodle front
        // we require the plugin to know that we are now doing a teosso login in hook puser_login
        $GLOBALS['teosso_login'] = TRUE;
        // make variables accessible to teosso->get_userinfo. Information will be requested from authenticate_user_login -> create_user_record / update_user_record
        $GLOBALS['teosso_login_attributes'] = $attributes;
        // just passes time as a password. User will never log in directly to moodle with this password anyway or so we hope?
        $USER = authenticate_user_login($attributes['username'], time());
        $USER->loggedin = true;
        $USER->site = $CFG->wwwroot;
        update_user_login_times();
        if ($pluginconfig->notshowusername) {
            // Don't show username on login page
            set_moodle_cookie('nobody');
        }
        set_login_session_preferences();
        add_to_log(SITEID, 'user', 'login', "view.php?id={$USER->id}&course=" . SITEID, $USER->id, 0, $USER->id);
        check_enrolment_plugins($USER);
        load_all_capabilities();
        // just fast copied this from some other module - might not work...
        if (isset($SESSION->wantsurl) and strpos($SESSION->wantsurl, $CFG->wwwroot) === 0) {
            $urltogo = $SESSION->wantsurl;
        } else {
            $urltogo = $CFG->wwwroot . '/';
        }
        unset($SESSION->wantsurl);
        redirect($urltogo);
    }
}
Esempio n. 6
0
/**
 * It will build an array of all the capabilities at each level
 * i.e. site/metacourse/course_category/course/moduleinstance
 * Note we should only load capabilities if they are explicitly assigned already,
 * we should not load all module's capability!
 *
 * [Capabilities] => [26][forum_post] = 1
 *                   [26][forum_start] = -8990
 *                   [26][forum_edit] = -1
 *                   [273][blah blah] = 1
 *                   [273][blah blah blah] = 2
 *
 * @param $capability string - Only get a specific capability (string)
 * @param $context object - Only get capabilities for a specific context object
 * @param $userid integer - the id of the user whose capabilities we want to load
 * @param $checkenrolments boolean - Should we checkenrolment plugins (potentially expensive)
 * @return array of permissions (or nothing if they get assigned to $USER)
 */
function load_user_capability($capability = '', $context = NULL, $userid = NULL, $checkenrolments = true)
{
    global $USER, $CFG;
    // this flag has not been set!
    // (not clean install, or upgraded successfully to 1.7 and up)
    if (empty($CFG->rolesactive)) {
        return false;
    }
    if (empty($userid)) {
        if (empty($USER->id)) {
            // We have no user to get capabilities for
            debugging('User not logged in for load_user_capability!');
            return false;
        }
        unset($USER->capabilities);
        // We don't want possible older capabilites hanging around
        if ($checkenrolments) {
            // Call "enrol" system to ensure that we have the correct picture
            check_enrolment_plugins($USER);
        }
        $userid = $USER->id;
        $otheruserid = false;
    } else {
        if (!($user = get_record('user', 'id', $userid))) {
            debugging('Non-existent userid in load_user_capability!');
            return false;
        }
        if ($checkenrolments) {
            // Call "enrol" system to ensure that we have the correct picture
            check_enrolment_plugins($user);
        }
        $otheruserid = $userid;
    }
    /// First we generate a list of all relevant contexts of the user
    $usercontexts = array();
    if ($context) {
        // if context is specified
        $usercontexts = get_parent_contexts($context);
        $usercontexts[] = $context->id;
        // Add the current context as well
    } else {
        // else, we load everything
        if ($userroles = get_records('role_assignments', 'userid', $userid)) {
            foreach ($userroles as $userrole) {
                if (!in_array($userrole->contextid, $usercontexts)) {
                    $usercontexts[] = $userrole->contextid;
                }
            }
        }
    }
    /// Set up SQL fragments for searching contexts
    if ($usercontexts) {
        $listofcontexts = '(' . implode(',', $usercontexts) . ')';
        $searchcontexts1 = "c1.id IN {$listofcontexts} AND";
    } else {
        $searchcontexts1 = '';
    }
    if ($capability) {
        // the doanything may override the requested capability
        $capsearch = " AND (rc.capability = '{$capability}' OR rc.capability = 'moodle/site:doanything') ";
    } else {
        $capsearch = "";
    }
    /// Then we use 1 giant SQL to bring out all relevant capabilities.
    /// The first part gets the capabilities of orginal role.
    /// The second part gets the capabilities of overriden roles.
    $siteinstance = get_context_instance(CONTEXT_SYSTEM);
    $capabilities = array();
    // Reinitialize.
    // SQL for normal capabilities
    $SQL1 = "SELECT rc.capability, c1.id as id1, c1.id as id2, (c1.contextlevel * 100) AS aggrlevel,\n                     SUM(rc.permission) AS sum\n                     FROM\n                     {$CFG->prefix}role_assignments ra,\n                     {$CFG->prefix}role_capabilities rc,\n                     {$CFG->prefix}context c1\n                     WHERE\n                     ra.contextid=c1.id AND\n                     ra.roleid=rc.roleid AND\n                     ra.userid={$userid} AND\n                     {$searchcontexts1}\n                     rc.contextid={$siteinstance->id}\n                     {$capsearch}\n              GROUP BY\n                     rc.capability, c1.id, c1.contextlevel * 100\n                     HAVING\n                     SUM(rc.permission) != 0          \n            \n              UNION ALL\n             \n              SELECT rc.capability, c1.id as id1, c2.id as id2, (c1.contextlevel * 100 + c2.contextlevel) AS aggrlevel,                    \n                     SUM(rc.permission) AS sum\n                     FROM\n                     {$CFG->prefix}role_assignments ra LEFT JOIN\n                     {$CFG->prefix}role_capabilities rc on ra.roleid = rc.roleid LEFT JOIN\n                     {$CFG->prefix}context c1 on ra.contextid = c1.id LEFT JOIN\n                     {$CFG->prefix}context c2 on rc.contextid = c2.id LEFT JOIN\n                     {$CFG->prefix}context_rel cr on cr.c1 = c2.id\n                     WHERE\n                     ra.userid={$userid} AND\n                     {$searchcontexts1}\n                     rc.contextid != {$siteinstance->id}\n                     {$capsearch}\n                     AND cr.c2 = c1.id\n              GROUP BY\n                     rc.capability, c1.id, c2.id, c1.contextlevel * 100 + c2.contextlevel\n                     HAVING\n                     SUM(rc.permission) != 0\n              ORDER BY\n                     aggrlevel ASC";
    if (!($rs = get_recordset_sql($SQL1))) {
        error("Query failed in load_user_capability.");
    }
    if ($rs && $rs->RecordCount() > 0) {
        while ($caprec = rs_fetch_next_record($rs)) {
            $array = (array) $caprec;
            $temprecord = new object();
            foreach ($array as $key => $val) {
                if ($key == 'aggrlevel') {
                    $temprecord->contextlevel = $val;
                } else {
                    $temprecord->{$key} = $val;
                }
            }
            $capabilities[] = $temprecord;
        }
        rs_close($rs);
    }
    // SQL for overrides
    // this is take out because we have no way of making sure c1 is indeed related to c2 (parent)
    // if we do not group by sum, it is possible to have multiple records of rc.capability, c1.id, c2.id, tuple having
    // different values, we can maually sum it when we go through the list
    /* 
        
        $SQL2 = "SELECT rc.capability, c1.id as id1, c2.id as id2, (c1.contextlevel * 100 + c2.contextlevel) AS aggrlevel,
                         rc.permission AS sum
                         FROM
                         {$CFG->prefix}role_assignments ra,
                         {$CFG->prefix}role_capabilities rc,
                         {$CFG->prefix}context c1,
                         {$CFG->prefix}context c2
                         WHERE
                         ra.contextid=c1.id AND
                         ra.roleid=rc.roleid AND
                         ra.userid=$userid AND
                         rc.contextid=c2.id AND
                         $searchcontexts1
                         rc.contextid != $siteinstance->id
                         $capsearch
    
                  GROUP BY
                         rc.capability, (c1.contextlevel * 100 + c2.contextlevel), c1.id, c2.id, rc.permission
                  ORDER BY
                         aggrlevel ASC
                ";*/
    /*
        if (!$rs = get_recordset_sql($SQL2)) {
            error("Query failed in load_user_capability.");
        }
    
        if ($rs && $rs->RecordCount() > 0) {
            while ($caprec = rs_fetch_next_record($rs)) {
                $array = (array)$caprec;
                $temprecord = new object;
    
                foreach ($array as $key=>$val) {
                    if ($key == 'aggrlevel') {
                        $temprecord->contextlevel = $val;
                    } else {
                        $temprecord->{$key} = $val;
                    }
                }
                // for overrides, we have to make sure that context2 is a child of context1
                // otherwise the combination makes no sense
                //if (is_parent_context($temprecord->id1, $temprecord->id2)) {
                    $capabilities[] = $temprecord;
                //} // only write if relevant
            }
            rs_close($rs);
        }
    
        // this step sorts capabilities according to the contextlevel
        // it is very important because the order matters when we 
        // go through each capabilities later. (i.e. higher level contextlevel
        // will override lower contextlevel settings
        usort($capabilities, 'roles_context_cmp');
    */
    /* so up to this point we should have somethign like this
         * $capabilities[1]    ->contextlevel = 1000
                               ->module = 0 // changed from SITEID in 1.8 (??)
                               ->capability = do_anything
                               ->id = 1 (id is the context id)
                               ->sum = 0
    
         * $capabilities[2]     ->contextlevel = 1000
                                ->module = 0 // changed from SITEID in 1.8 (??)
                                ->capability = post_messages
                                ->id = 1
                                ->sum = -9000
    
         * $capabilittes[3]     ->contextlevel = 3000
                                ->module = course
                                ->capability = view_course_activities
                                ->id = 25
                                ->sum = 1
    
         * $capabilittes[4]     ->contextlevel = 3000
                                ->module = course
                                ->capability = view_course_activities
                                ->id = 26
                                ->sum = 0 (this is another course)
    
         * $capabilities[5]     ->contextlevel = 3050
                                ->module = course
                                ->capability = view_course_activities
                                ->id = 25 (override in course 25)
                                ->sum = -1
         * ....
         * now we proceed to write the session array, going from top to bottom
         * at anypoint, we need to go up and check parent to look for prohibit
         */
    // print_object($capabilities);
    /* This is where we write to the actualy capabilities array
     * what we need to do from here on is
     * going down the array from lowest level to highest level
     * 1) recursively check for prohibit,
     *  if any, we write prohibit
     *  else, we write the value
     * 2) at an override level, we overwrite current level
     *  if it's not set to prohibit already, and if different
     *  ........ that should be it ........
     */
    // This is the flag used for detecting the current context level. Since we are going through
    // the array in ascending order of context level. For normal capabilities, there should only
    // be 1 value per (capability,  contextlevel, context), because they are already summed. But,
    // for overrides, since we are processing them separate, we need to sum the relevcant entries.
    // We set this flag when we hit a new level.
    // If the flag is already set, we keep adding (summing), otherwise, we just override previous
    // settings (from lower level contexts)
    $capflags = array();
    // (contextid, contextlevel, capability)
    $usercap = array();
    // for other user's capabilities
    foreach ($capabilities as $capability) {
        if (!($context = get_context_instance_by_id($capability->id2))) {
            continue;
            // incorrect stale context
        }
        if (!empty($otheruserid)) {
            // we are pulling out other user's capabilities, do not write to session
            if (capability_prohibits($capability->capability, $context, $capability->sum, $usercap)) {
                $usercap[$capability->id2][$capability->capability] = CAP_PROHIBIT;
                continue;
            }
            if (isset($usercap[$capability->id2][$capability->capability])) {
                // use isset because it can be sum 0
                if (!empty($capflags[$capability->id2][$capability->contextlevel][$capability->capability])) {
                    $usercap[$capability->id2][$capability->capability] += $capability->sum;
                } else {
                    // else we override, and update flag
                    $usercap[$capability->id2][$capability->capability] = $capability->sum;
                    $capflags[$capability->id2][$capability->contextlevel][$capability->capability] = true;
                }
            } else {
                $usercap[$capability->id2][$capability->capability] = $capability->sum;
                $capflags[$capability->id2][$capability->contextlevel][$capability->capability] = true;
            }
        } else {
            if (capability_prohibits($capability->capability, $context, $capability->sum)) {
                // if any parent or parent's parent is set to prohibit
                $USER->capabilities[$capability->id2][$capability->capability] = CAP_PROHIBIT;
                continue;
            }
            // if no parental prohibit set
            // just write to session, i am not sure this is correct yet
            // since 3050 shows up after 3000, and 3070 shows up after 3050,
            // it should be ok just to overwrite like this, provided that there's no
            // parental prohibits
            // we need to write even if it's 0, because it could be an inherit override
            if (isset($USER->capabilities[$capability->id2][$capability->capability])) {
                if (!empty($capflags[$capability->id2][$capability->contextlevel][$capability->capability])) {
                    $USER->capabilities[$capability->id2][$capability->capability] += $capability->sum;
                } else {
                    // else we override, and update flag
                    $USER->capabilities[$capability->id2][$capability->capability] = $capability->sum;
                    $capflags[$capability->id2][$capability->contextlevel][$capability->capability] = true;
                }
            } else {
                $USER->capabilities[$capability->id2][$capability->capability] = $capability->sum;
                $capflags[$capability->id2][$capability->contextlevel][$capability->capability] = true;
            }
        }
    }
    // now we don't care about the huge array anymore, we can dispose it.
    unset($capabilities);
    unset($capflags);
    if (!empty($otheruserid)) {
        return $usercap;
        // return the array
    }
}