Chamilo is a learning management system focused on ease of use and accessibility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
chamilo-lms/main/auth/shibboleth/app/shibboleth.class.php

265 lines
7.8 KiB

<?php
namespace Shibboleth;
use \Redirect;
/**
* Shibboleth main class. Provides access to various Shibboleth sub components and
* provides the high level functionalities.
*
* @license see /license.txt
* @author Laurent Opprecht <laurent@opprecht.info>, Nicolas Rod for the University of Geneva
*/
class Shibboleth
{
const NAME = 'shibboleth';
const UNKNOWN_STATUS = -1;
const TEACHER_STATUS = 1;
const STUDENT_STATUS = 5;
static $config = null;
public static function format_status($status)
{
if ($status == Shibboleth::TEACHER_STATUS) {
return 'Teacher';
} else if ($status == Shibboleth::STUDENT_STATUS) {
return 'Student';
} else if ($status == Shibboleth::UNKNOWN_STATUS) {
return 'Unknown';
} else {
return '???';
}
}
/**
*
* @return ShibbolethConfig
*/
public static function config()
{
self::$config = self::$config ? self::$config : new ShibbolethConfig();
return self::$config;
}
public static function set_config($config)
{
self::$config = $config;
}
/**
*
* @return ShibbolethSession
*/
public static function session()
{
return ShibbolethSession::instance();
}
/**
*
* @return ShibbolethStore
*/
public static function store()
{
return ShibbolethStore::instance();
}
/**
*
* @return ShibbolethDisplay
*/
public static function display()
{
return ShibbolethDisplay::instance();
}
public static function sys_path()
{
$path = dirname(__FILE__) . '/../';
return $path;
}
public static function url($path = '')
{
$result = api_get_path('WEB_PATH');
$result .= '/main/auth/shibboleth/' . $path;
return $result;
}
public static function redirect($url = '')
{
if (empty($url)) {
$url = isset($_SESSION['shibb_direct_url']) ? $_SESSION['shibb_direct_url'] : '';
unset($_SESSION['shibb_direct_url']);
/*
* Tests if the user tried to login directly in a protected course before to come here
* (this variable could be set in the modified code of /chamilo/inc/lib/main_api.lib.php)
*
* Note:
* this part was added to give the possibility to access Chamilo directly on a course URL from a link diplayed in a portal.
* This is not a direct Shibboleth related functionnality, but this could be used in a shibbolethized
* Dokeos installation, mainly if you have a SSO system in your network.
* Please note that the file /claroline/inc/lib/main_api.lib.php must be adapted to your Shibboleth settings
* If any interest or question, please contact Nicolas.Rod_at_adm.unige.ch
*
*/
}
if ($url) {
//needed to log the user in his courses. Normally it is done by visiting /chamilo/index.php
// $include_path = api_get_path(INCLUDE_PATH);
// require("$include_path/local.inc.php");
//
// if (strpos($url, '?') === false) {
// $url = "$url?";
// }
//
// $rootWeb = api_get_path('WEB_PATH');
// $first_slash_pos = strpos($rootWeb, '/', 8);
// $rootWeb_wo_uri = substr($rootWeb, 0, $first_slash_pos);
// $url = $rootWeb_wo_uri . $course_url . '_stop';
Redirect::go($url);
}
Redirect::home();
}
/**
*
* @param ShibbolethUser $user
*/
public static function save($shibb_user)
{
$shibb_user->status = self::infer_user_status($shibb_user);
$shibb_user->status_request = self::infer_status_request($shibb_user);
$shibb_user->shibb_unique_id = $shibb_user->unique_id;
$shibb_user->shibb_persistent_id = $shibb_user->persistent_id;
$user = User::store()->get_by_shibboleth_id($shibb_user->unique_id);
if (empty($user)) {
$shibb_user->auth_source == self::NAME;
return User::create($shibb_user)->save();
}
$shibb_user->status_request = false;
$fields = self::config()->update_fields;
foreach ($fields as $key => $updatable) {
if ($updatable) {
$user->{$key} = $shibb_user->{$key};
}
}
$user->auth_source == self::NAME;
$user->shibb_unique_id = $shibb_user->shibb_unique_id;
$user->shibb_persistent_id = $shibb_user->shibb_persistent_id;
$user->save();
return $result;
}
/**
* Infer the rights/status the user can have in Chamilo based on his affiliation attribute
*
* @param ShibbolethUser $user
* @return The Chamilo user status, one of TEACHER, STUDENT or UNKNOWN
*/
public static function infer_user_status($user)
{
$affiliations = $user->affiliation;
$affiliations = is_array($affiliations) ? $affiliations : array($affiliations);
$map = self::config()->affiliation_status;
$rights = array();
foreach ($affiliations as $affiliation) {
$affiliation = strtolower($affiliation);
if (isset($map[$affiliation])) {
$right = $map[$affiliation];
$rights[$right] = $right;
}
}
$teacher_status = isset($rights[self::TEACHER_STATUS]);
$student_status = isset($rights[self::STUDENT_STATUS]);
//if the user has got teacher rights, we doesn't check anything else
if ($teacher_status) {
return self::TEACHER_STATUS;
}
if ($student_status) {
return self::STUDENT_STATUS;
}
$result = self::config()->default_status;
$result = (int) $result;
$result = ($result == Shibboleth::TEACHER_STATUS || $result == Shibboleth::STUDENT_STATUS) ? $result : Shibboleth::UNKNOWN_STATUS;
return $result;
}
/**
* Return true if the user can ask for a greater status than student.
* This happens for staff members.
*
* @param ShibbolethUser $user
* @return boolean
*/
public static function infer_status_request($user)
{
if ($user->status == self::TEACHER_STATUS) {
return false;
}
if ($user->status == self::UNKNOWN_STATUS) {
return true;
}
$config = Shibboleth::config();
$affiliations = $user->affiliation;
$affiliations = is_array($affiliations) ? $affiliations : array($affiliations);
foreach ($affiliations as $affiliation) {
$result = isset($config->affiliation_status_request[$affiliation]) ? $config->affiliation_status_request[$affiliation] : false;
if ($result) {
return true;
}
}
return false;
}
/**
* Sends an email to the Chamilo and Shibboleth administrators in the name
* of the logged-in user.
*
*/
public static function email_admin($subject, $message)
{
$user = Shibboleth::session()->user();
$firstname = $user['firstname'];
$lastname = $user['lastname'];
$email = $user['email'];
$status = $user['status'];
$status = self::format_status($status);
$signagure = <<<EOT
_________________________
$firstname $lastname
$email
$status
EOT;
$message .= $signagure;
$header = "From: $email \n";
$shibb_admin_email = Shibboleth::config()->admnistrator_email;
if ($shibb_admin_email) {
$header .= "Cc: $shibb_admin_email";
}
$administrator_email = api_get_setting('emailAdministrator');
$result = mail($administrator_email, $subject, $message);
return (bool) $result;
}
}