ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilAuthProviderLTI.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5use ILIAS\LTI\ToolProvider;
6
7include_once './Services/Authentication/classes/Provider/class.ilAuthProvider.php';
8include_once './Services/Authentication/interfaces/interface.ilAuthProviderInterface.php';
9include_once './Services/LTI/classes/InternalProvider/class.ilLTIToolProvider.php';
10require_once 'Services/LTI/classes/class.ilLTIDataConnector.php';
20{
21 const AUTH_MODE_PREFIX = 'lti';
22 private $dataConnector = null;
23 private $lti_context_id = "";
24
29 public function doAuthentication(\ilAuthStatus $status)
30 {
31 //fix for Ilias Consumer
32 if (isset($_POST['launch_presentation_document_target']) && $_POST['launch_presentation_document_target'] == 'blank') {
33 $_POST['launch_presentation_document_target'] = 'window';
34 }
35
36 $this->dataConnector = new ilLTIDataConnector();
37
38 $lti_provider = new ilLTIToolProvider($this->dataConnector);
39 // $lti_provider = new ToolProvider\ToolProvider($this->dataConnector);
40 $ok = $lti_provider->handleRequest();
41
42 if (!$ok) {
43 $this->getLogger()->info('LTI authentication failed with message: ' . $lti_provider->reason);
44 $status->setReason($lti_provider->reason);
46 return false;
47 } else {
48 $this->getLogger()->debug('LTI authentication success');
49 }
50 // if ($lti_provider->reason != "") die($lti_provider->reason);//ACHTUNG später Rückgabe prüfen und nicht vergessen UWE
51
52 // sm: this does only load the standard lti date connector, not the ilLTIToolConsumer with extended data, like prefix.
53 $consumer = new ilLTIToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
54
59 $consumer->getRecordId(),
60 $this->dataConnector
61 );
62
63 $this->ref_id = $consumer->getRefId();
64 // stores ref_ids of all lti consumer within active LTI User Session
65 $lti_context_ids = $_SESSION['lti_context_ids'];
66 // if session object exists only add ref_id if not already exists
67 if (isset($lti_context_ids) && is_array($lti_context_ids)) {
68 if (!in_array($this->ref_id, $lti_context_ids)) {
69 $this->getLogger()->debug("push new lti ref_id: " . $this->ref_id);
70 array_push($lti_context_ids,$this->ref_id);
71 $_SESSION['lti_context_ids'] = $lti_context_ids;
72 $this->getLogger()->debug(var_export($_SESSION['lti_context_ids'], true));
73 }
74 }
75 else {
76 $this->getLogger()->debug("lti_context_ids is not set. Create new array...");
77 $_SESSION['lti_context_ids'] = array($this->ref_id);
78 $this->getLogger()->debug(var_export($_SESSION['lti_context_ids'], true));
79 }
80
81 // for testing external css
82 // $_POST['launch_presentation_css_url'] = "https://ltiprovider6.example.com/Services/LTI/templates/default/lti_extern.css";
83
84 // store POST into Consumer Session
85 $_SESSION['lti_' . $this->ref_id . '_post_data'] = $_POST;
86
87 $_GET['target'] = ilObject::_lookupType($this->ref_id, true) . '_' . $this->ref_id;
88
89 // lti service activation
90 if (!$consumer->enabled) {
91 $this->getLogger()->warning('Consumer is not enabled');
92 $status->setReason('lti_consumer_inactive');
94 return false;
95 }
96 // global activation status
97 if (!$consumer->getActive()) {
98 $this->getLogger()->warning('Consumer is not active');
99 $status->setReason('lti_consumer_inactive');
101 return false;
102 }
103
104 $lti_id = $consumer->getExtConsumerId();
105 if (!$lti_id) {
106 $status->setReason('lti_auth_failed_invalid_key');
108 return false;
109 }
110
111 $this->getLogger()->debug('Using prefix:' . $consumer->getPrefix());
112
113 $internal_account = $this->findUserId($this->getCredentials()->getUsername(), $lti_id, $consumer->getPrefix());
114
115 if ($internal_account) {
116 $this->updateUser($internal_account, $consumer);
117 } else {
118 $internal_account = $this->createUser($consumer);
119 }
120
121 $this->handleLocalRoleAssignments($internal_account, $consumer);
122
124 $status->setAuthenticatedUserId($internal_account);
125
126 return true;
127 }
128
129
136 protected function findAuthKeyId($a_oauth_consumer_key)
137 {
138 global $ilDB;
139
140 $query = 'SELECT consumer_pk from lti2_consumer where consumer_key256 = ' . $ilDB->quote($a_oauth_consumer_key, 'text');
141 // $query = 'SELECT id from lti_ext_consumer where consumer_key = '.$ilDB->quote($a_oauth_consumer_key,'text');
142 $this->getLogger()->debug($query);
143 $res = $ilDB->query($query);
144
145 $lti_id = 0;
146 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
147 $lti_id = $row->consumer_pk;
148 // $lti_id = $row->id;
149 }
150 $this->getLogger()->debug('External consumer key is: ' . (int) $lti_id);
151 return $lti_id;
152 }
153
158 protected function findAuthPrefix($a_lti_id)
159 {
160 global $ilDB;
161
162 $query = 'SELECT prefix from lti_ext_consumer where id = ' . $ilDB->quote($a_lti_id, 'integer');
163 $this->getLogger()->debug($query);
164 $res = $ilDB->query($query);
165
166 // $prefix = 'lti'.$a_lti_id.'_';
167 $prefix = '';
168 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
169 $prefix = $row->prefix;
170 }
171 $this->getLogger()->debug('LTI prefix: ' . $prefix);
172 return $prefix;
173 }
174
178 protected function findGlobalRole($a_lti_id)
179 {
180 global $ilDB;
181
182 $query = 'SELECT role from lti_ext_consumer where id = ' . $ilDB->quote($a_lti_id, 'integer');
183 $this->getLogger()->debug($query);
184 $res = $ilDB->query($query);
185
186 $role = '';
187 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
188 $role = $row->role;
189 }
190 $this->getLogger()->debug('LTI role: ' . $role);
191 return $role;
192 }
193
199 protected function findUserId($a_oauth_user, $a_oauth_id, $a_user_prefix)
200 {
202 self::AUTH_MODE_PREFIX . '_' . $a_oauth_id,
203 $a_oauth_user
204 );
205 $user_id = 0;
206 if ($user_name) {
207 $user_id = ilObjUser::_lookupId($user_name);
208 }
209 $this->getLogger()->debug('Found user with auth mode lti_' . $a_oauth_id . ' with user_id: ' . $user_id);
210 return $user_id;
211 }
212
218 protected function createUser(ilLTIToolConsumer $consumer)
219 {
220 global $ilClientIniFile, $ilSetting;
221
222 $userObj = new ilObjUser();
223
224 include_once('./Services/Authentication/classes/class.ilAuthUtils.php');
225 $local_user = ilAuthUtils::_generateLogin($consumer->getPrefix() . '_' . $this->getCredentials()->getUsername());
226
227 $newUser["login"] = $local_user;
228 $newUser["firstname"] = $_POST['lis_person_name_given'];
229 $newUser["lastname"] = $_POST['lis_person_name_family'];
230 $newUser['email'] = $_POST['lis_person_contact_email_primary'];
231
232
233 // set "plain md5" password (= no valid password)
234 $newUser["passwd"] = "";
235 $newUser["passwd_type"] = IL_PASSWD_CRYPTED;
236
237 $newUser["auth_mode"] = 'lti_' . $consumer->getExtConsumerId();
238 $newUser['ext_account'] = $this->getCredentials()->getUsername();
239 $newUser["profile_incomplete"] = 0;
240
241 // system data
242 $userObj->assignData($newUser);
243 $userObj->setTitle($userObj->getFullname());
244 $userObj->setDescription($userObj->getEmail());
245
246 // set user language
247 $userObj->setLanguage($consumer->getLanguage());
248
249 // Time limit
250 $userObj->setTimeLimitOwner(7);
251 $userObj->setTimeLimitUnlimited(0);
252 $userObj->setTimeLimitFrom(time() - 5);
253 $userObj->setTimeLimitUntil(time() + $ilClientIniFile->readVariable("session", "expire"));
254
255
256 // Create user in DB
257 $userObj->setOwner(6);
258 $userObj->create();
259 $userObj->setActive(1);
260 $userObj->updateOwner();
261 $userObj->saveAsNew();
262 $userObj->writePrefs();
263
264 $GLOBALS['DIC']->rbac()->admin()->assignUser($consumer->getRole(), $userObj->getId());
265
266 $this->getLogger()->info('Created new lti user with uid: ' . $userObj->getId() . ' and login: ' . $userObj->getLogin());
267 return $userObj->getId();
268 }
269
275 protected function updateUser($a_local_user_id, ilLTIToolConsumer $consumer)
276 {
277 global $ilClientIniFile,$ilLog,$rbacadmin;
278
279 $user_obj = new ilObjUser($a_local_user_id);
280 $user_obj->setFirstname($_POST['lis_person_name_given']);
281 $user_obj->setLastname($_POST['lis_person_name_family']);
282 $user_obj->setEmail($_POST['lis_person_contact_email_primary']);
283 $user_obj->setActive(true);
284
285 $until = $user_obj->getTimeLimitUntil();
286
287 if ($until < (time() + $ilClientIniFile->readVariable('session', 'expire'))) {
288 $user_obj->setTimeLimitFrom(time() - 60);
289 $user_obj->setTimeLimitUntil(time() + $ilClientIniFile->readVariable("session", "expire"));
290 }
291 $user_obj->update();
292 $user_obj->refreshLogin();
293
294 $GLOBALS['DIC']->rbac()->admin()->assignUser($consumer->getRole(), $user_obj->getId());
295 $this->getLogger()->debug('Assigned user to: ' . $consumer->getRole());
296
297 $this->getLogger()->info('Update of lti user with uid: ' . $user_obj->getId() . ' and login: ' . $user_obj->getLogin());
298 return $user_obj->getId();
299 }
300
302 {
303 //$target_ref_id = $_SESSION['lti_current_context_id'];
304 $target_ref_id = $this->ref_id;
305 $this->getLogger()->info('$target_ref_id: ' . $target_ref_id);
306 if (!$target_ref_id) {
307 $this->getLogger()->warning('No target id given');
308 return false;
309 }
310
311 $obj_settings = new ilLTIProviderObjectSetting($target_ref_id, $consumer->getExtConsumerId());
312
313 // @todo read from lti data
314 $roles = $_POST['roles'];
315 if (!strlen($roles)) {
316 $this->getLogger()->warning('No role information given');
317 return false;
318 }
319 $role_arr = explode(',', $roles);
320 foreach ($role_arr as $role_name) {
321 $role_name = trim($role_name);
322 switch ($role_name) {
323 case 'Administrator':
324 $this->getLogger()->info('Administrator role handling');
325 if ($obj_settings->getAdminRole()) {
326 $GLOBALS['DIC']->rbac()->admin()->assignUser(
327 $obj_settings->getAdminRole(),
329 );
330 }
331 break;
332
333 case 'Instructor':
334 $this->getLogger()->info('Instructor role handling');
335 $this->getLogger()->info('Tutor role for request: ' . $obj_settings->getTutorRole());
336 if ($obj_settings->getTutorRole()) {
337 $GLOBALS['DIC']->rbac()->admin()->assignUser(
338 $obj_settings->getTutorRole(),
340 );
341 }
342 break;
343
344 case 'Member':
345 case 'Learner':
346 $this->getLogger()->info('Member role handling');
347 if ($obj_settings->getMemberRole()) {
348 $GLOBALS['DIC']->rbac()->admin()->assignUser(
349 $obj_settings->getMemberRole(),
351 );
352 }
353 break;
354 }
355 }
356 }
357
363 public static function getAuthModeByKey($a_auth_key)
364 {
365 $auth_arr = explode('_', $a_auth_key);
366 if (count((array) $auth_arr) > 1) {
367 return 'lti_' . $auth_arr[1];
368 }
369 return 'lti';
370 }
371
377 public static function getKeyByAuthMode($a_auth_mode)
378 {
379 $auth_arr = explode('_', $a_auth_mode);
380 if (count((array) $auth_arr) > 1) {
381 return AUTH_PROVIDER_LTI . '_' . $auth_arr[1];
382 }
383 return AUTH_PROVIDER_LTI;
384 }
385
386
390 public static function getActiveAuthModes()
391 {
392 global $ilDB;
393
394 // move to connector
395 $query = 'SELECT consumer_pk from lti2_consumer where enabled = ' . $ilDB->quote(1, 'integer');
396 $res = $ilDB->query($query);
397
398 $sids = array();
399 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
400 $sids[] = $row->consumer_pk;
401 }
402 return $sids;
403 }
404
405 public static function getAuthModes()
406 {
407 global $ilDB;
408
409 // move to connector
410 $query = 'SELECT distinct(consumer_pk) consumer_pk from lti2_consumer';
411 $res = $ilDB->query($query);
412
413 $sids = array();
414 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
415 $sids[] = $row->consumer_pk;
416 }
417 return $sids;
418 }
419
425 public static function lookupConsumer($a_sid)
426 {
427 include_once './Services/LTI/classes/class.ilLTIDataConnector.php';
428 $connector = new ilLTIDataConnector();
429 include_once './Services/LTI/classes/InternalProvider/class.ilLTIToolConsumer.php';
430 $consumer = ilLTIToolConsumer::fromRecordId($a_sid, $connector);
431 return $consumer->getTitle();
432 }
433
439 public static function getServerIdByAuthMode($a_auth_mode)
440 {
441 if (self::isAuthModeLTI($a_auth_mode)) {
442 $auth_arr = explode('_', $a_auth_mode);
443 return $auth_arr[1];
444 }
445 return null;
446 }
447
452 public static function isAuthModeLTI($a_auth_mode)
453 {
454 if (!$a_auth_mode) {
455 ilLoggerFactory::getLogger('lti')->warning('No auth mode given.');
456 return false;
457 }
458 $auth_arr = explode('_', $a_auth_mode);
459 return ($auth_arr[0] == AUTH_PROVIDER_LTI) and $auth_arr[1];
460 }
461}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
$_GET["client_id"]
$_POST["username"]
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
const AUTH_PROVIDER_LTI
const IL_PASSWD_CRYPTED
OAuth based lti authentication.
static getActiveAuthModes()
get all active authmode server ids
static getKeyByAuthMode($a_auth_mode)
Get auth id by auth mode.
updateUser($a_local_user_id, ilLTIToolConsumer $consumer)
update existing user
findGlobalRole($a_lti_id)
find global role of consumer
static lookupConsumer($a_sid)
Lookup consumer title.
findUserId($a_oauth_user, $a_oauth_id, $a_user_prefix)
Find user by auth mode and lti id.
findAuthKeyId($a_oauth_consumer_key)
find consumer key id @global type $ilDB
findAuthPrefix($a_lti_id)
find lti id
createUser(ilLTIToolConsumer $consumer)
create new user
handleLocalRoleAssignments($user_id, ilLTIToolConsumer $consumer)
static getServerIdByAuthMode($a_auth_mode)
Get auth id by auth mode.
static isAuthModeLTI($a_auth_mode)
Check if user auth mode is LTI.
static getAuthModeByKey($a_auth_key)
Get auth mode by key.
Base class for authentication providers (radius, ldap, apache, ...)
getLogger()
Get logger.
Auth status implementation.
setReason($a_reason)
Set reason.
const STATUS_AUTHENTICATION_FAILED
static _generateLogin($a_login)
generate free login by starting with a default string and adding postfix numbers
Class to represent an LTI Data Connector for ILIAS.
LTI provider for LTI launch.
static fromRecordId($id, $dataConnector)
Load the tool consumer from the database by its record ID.
LTI provider for LTI launch.
static getLogger($a_component_id)
Get component logger.
static _checkExternalAuthAccount($a_auth, $a_account, $tryFallback=true)
check whether external account and authentication method matches with a user
static _lookupId($a_user_str)
Lookup id by login.
static _lookupType($a_id, $a_reference=false)
lookup object type
Standard interface for auth provider implementations.
doAuthentication(\ilAuthStatus $status)
Do authentication.
global $ilSetting
Definition: privfeed.php:17
$query
foreach($_POST as $key=> $value) $res
global $ilDB