ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 
6 
7 include_once './Services/Authentication/classes/Provider/class.ilAuthProvider.php';
8 include_once './Services/Authentication/interfaces/interface.ilAuthProviderInterface.php';
9 include_once './Services/LTI/classes/InternalProvider/class.ilLTIToolProvider.php';
10 require_once 'Services/LTI/classes/class.ilLTIDataConnector.php';
20 {
21  const AUTH_MODE_PREFIX = 'lti';
22  private $dataConnector = null;
23 
28  public function doAuthentication(\ilAuthStatus $status)
29  {
30  //fix for Ilias Consumer
31  if (isset($_POST['launch_presentation_document_target']) && $_POST['launch_presentation_document_target'] == 'blank') {
32  $_POST['launch_presentation_document_target'] = 'window';
33  }
34 
35  if (isset($_POST['launch_presentation_css_url'])) {
36  $_SESSION['lti_launch_css_url'] = $_POST['launch_presentation_css_url'];
37  //Bsp.: 'http://192.168.0.74/lti_custom.css';
38  }
39  if (isset($_POST['launch_presentation_return_url']) && (strlen(trim($_POST['launch_presentation_return_url'])) > 0)) {
40  $_SESSION['lti_launch_presentation_return_url'] = $_POST['launch_presentation_return_url'];
41  // Bsp.: 'http://192.168.0.74/ilias51/ilias.php?ref_id=128&cmd=viewEmbed&cmdClass=ilobjexternalcontentgui&cmdNode=hx:gc&baseClass=ilObjPluginDispatchGUI';
42  }
43 
44  $this->dataConnector = new ilLTIDataConnector();
45 
46  $lti_provider = new ilLTIToolProvider($this->dataConnector);
47  // $lti_provider = new ToolProvider\ToolProvider($this->dataConnector);
48  $ok = $lti_provider->handleRequest();
49 
50  if (!$ok) {
51  $this->getLogger()->warning('LTI authentication failed with message: ' . $lti_provider->reason);
52  $status->setReason($lti_provider->reason);
54  return false;
55  } else {
56  $this->getLogger()->debug('LTI authentication success');
57  }
58  // if ($lti_provider->reason != "") die($lti_provider->reason);//ACHTUNG später Rückgabe prüfen und nicht vergessen UWE
59 
60  // sm: this does only load the standard lti date connector, not the ilLTIToolConsumer with extended data, like prefix.
61  $consumer = new ilLTIToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
62 
67  $consumer->getRecordId(),
69  );
70 
71  $_SESSION['lti_context_id'] = $consumer->getRefId();
72  $_GET['target'] = ilObject::_lookupType($consumer->getRefId(), true) . '_' . $consumer->getRefId();
73 
74 
75  // lti service activation
76  if (!$consumer->enabled) {
77  $this->getLogger()->warning('Consumer is not enabled');
78  $status->setReason('lti_consumer_inactive');
80  return false;
81  }
82  // global activation status
83  if (!$consumer->getActive()) {
84  $this->getLogger()->warning('Consumer is not active');
85  $status->setReason('lti_consumer_inactive');
87  return false;
88  }
89 
90 
91  $lti_id = $consumer->getExtConsumerId();
92  if (!$lti_id) {
93  $status->setReason('lti_auth_failed_invalid_key');
95  return false;
96  }
97 
98  $this->getLogger()->debug('Using prefix:' . $consumer->getPrefix());
99 
100  $internal_account = $this->findUserId($this->getCredentials()->getUsername(), $lti_id, $consumer->getPrefix());
101 
102  if ($internal_account) {
103  $this->updateUser($internal_account, $consumer);
104  } else {
105  $internal_account = $this->createUser($consumer);
106  }
107 
108  $this->handleLocalRoleAssignments($internal_account, $consumer);
109 
111  $status->setAuthenticatedUserId($internal_account);
112 
113  $lti_lis_person_name_full = "";
114  if (isset($_POST['lis_person_name_given'])) {
115  $_SESSION['lti_lis_person_name_given'] = $_POST['lis_person_name_given'];
116  $lti_lis_person_name_full = $_POST['lis_person_name_given'] . ' ';
117  }
118  if (isset($_POST['lis_person_name_family'])) {
119  $_SESSION['lti_lis_person_name_family'] = $_POST['lis_person_name_family'];
120  $lti_lis_person_name_full .= $_POST['lis_person_name_family'];
121  }
122  if (isset($_POST['lis_person_name_full']) && (strlen(trim($_POST['lis_person_name_full'])) > 0)) {
123  $_SESSION['lti_lis_person_name_full'] = $_POST['lis_person_name_full'];
124  } else {
125  $_SESSION['lti_lis_person_name_full'] = $lti_lis_person_name_full;
126  }
127 
128 
129 
130  return true;
131  }
132 
133 
140  protected function findAuthKeyId($a_oauth_consumer_key)
141  {
142  global $ilDB;
143 
144  $query = 'SELECT consumer_pk from lti2_consumer where consumer_key256 = ' . $ilDB->quote($a_oauth_consumer_key, 'text');
145  // $query = 'SELECT id from lti_ext_consumer where consumer_key = '.$ilDB->quote($a_oauth_consumer_key,'text');
146  $this->getLogger()->debug($query);
147  $res = $ilDB->query($query);
148 
149  $lti_id = 0;
150  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
151  $lti_id = $row->consumer_pk;
152  // $lti_id = $row->id;
153  }
154  $this->getLogger()->debug('External consumer key is: ' . (int) $lti_id);
155  return $lti_id;
156  }
157 
162  protected function findAuthPrefix($a_lti_id)
163  {
164  global $ilDB;
165 
166  $query = 'SELECT prefix from lti_ext_consumer where id = ' . $ilDB->quote($a_lti_id, 'integer');
167  $this->getLogger()->debug($query);
168  $res = $ilDB->query($query);
169 
170  // $prefix = 'lti'.$a_lti_id.'_';
171  $prefix = '';
172  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
173  $prefix = $row->prefix;
174  }
175  $this->getLogger()->debug('LTI prefix: ' . $prefix);
176  return $prefix;
177  }
178 
182  protected function findGlobalRole($a_lti_id)
183  {
184  global $ilDB;
185 
186  $query = 'SELECT role from lti_ext_consumer where id = ' . $ilDB->quote($a_lti_id, 'integer');
187  $this->getLogger()->debug($query);
188  $res = $ilDB->query($query);
189 
190  $role = '';
191  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
192  $role = $row->role;
193  }
194  $this->getLogger()->debug('LTI role: ' . $role);
195  return $role;
196  }
197 
203  protected function findUserId($a_oauth_user, $a_oauth_id, $a_user_prefix)
204  {
206  self::AUTH_MODE_PREFIX . '_' . $a_oauth_id,
207  $a_oauth_user
208  );
209  $user_id = 0;
210  if ($user_name) {
211  $user_id = ilObjUser::_lookupId($user_name);
212  }
213  $this->getLogger()->debug('Found user with auth mode lti_' . $a_oauth_id . ' with user_id: ' . $user_id);
214  return $user_id;
215  }
216 
223  {
224  global $ilClientIniFile, $ilSetting;
225 
226  $userObj = new ilObjUser();
227 
228  include_once('./Services/Authentication/classes/class.ilAuthUtils.php');
229  $local_user = ilAuthUtils::_generateLogin($consumer->getPrefix() . '_' . $this->getCredentials()->getUsername());
230 
231  $newUser["login"] = $local_user;
232  $newUser["firstname"] = $_POST['lis_person_name_given'];
233  $newUser["lastname"] = $_POST['lis_person_name_family'];
234  $newUser['email'] = $_POST['lis_person_contact_email_primary'];
235 
236 
237  // set "plain md5" password (= no valid password)
238  $newUser["passwd"] = "";
239  $newUser["passwd_type"] = IL_PASSWD_CRYPTED;
240 
241  $newUser["auth_mode"] = 'lti_' . $consumer->getExtConsumerId();
242  $newUser['ext_account'] = $this->getCredentials()->getUsername();
243  $newUser["profile_incomplete"] = 0;
244 
245  // system data
246  $userObj->assignData($newUser);
247  $userObj->setTitle($userObj->getFullname());
248  $userObj->setDescription($userObj->getEmail());
249 
250  // set user language to system language
251  $userObj->setLanguage($ilSetting->get("language"));
252 
253  // Time limit
254  $userObj->setTimeLimitOwner(7);
255  $userObj->setTimeLimitUnlimited(0);
256  $userObj->setTimeLimitFrom(time() - 5);
257  $userObj->setTimeLimitUntil(time() + $ilClientIniFile->readVariable("session", "expire"));
258 
259 
260  // Create user in DB
261  $userObj->setOwner(6);
262  $userObj->create();
263  $userObj->setActive(1);
264  $userObj->updateOwner();
265  $userObj->saveAsNew();
266  $userObj->writePrefs();
267 
268  $GLOBALS['DIC']->rbac()->admin()->assignUser($consumer->getRole(), $userObj->getId());
269 
270  $this->getLogger()->info('Created new lti user with uid: ' . $userObj->getId() . ' and login: ' . $userObj->getLogin());
271  return $userObj->getId();
272  }
273 
279  protected function updateUser($a_local_user_id, ilLTIToolConsumer $consumer)
280  {
281  global $ilClientIniFile,$ilLog,$rbacadmin;
282 
283  $user_obj = new ilObjUser($a_local_user_id);
284  $user_obj->setFirstname($_POST['lis_person_name_given']);
285  $user_obj->setLastname($_POST['lis_person_name_family']);
286  $user_obj->setEmail($_POST['lis_person_contact_email_primary']);
287  $user_obj->setActive(true);
288 
289  $until = $user_obj->getTimeLimitUntil();
290 
291  if ($until < (time() + $ilClientIniFile->readVariable('session', 'expire'))) {
292  $user_obj->setTimeLimitFrom(time() - 60);
293  $user_obj->setTimeLimitUntil(time() + $ilClientIniFile->readVariable("session", "expire"));
294  }
295  $user_obj->update();
296  $user_obj->refreshLogin();
297 
298  $GLOBALS['DIC']->rbac()->admin()->assignUser($consumer->getRole(), $user_obj->getId());
299  $this->getLogger()->debug('Assigned user to: ' . $consumer->getRole());
300 
301  $this->getLogger()->info('Update of lti user with uid: ' . $user_obj->getId() . ' and login: ' . $user_obj->getLogin());
302  return $user_obj->getId();
303  }
304 
306  {
307  $target_ref_id = $_SESSION['lti_context_id'];
308  if (!$target_ref_id) {
309  $this->getLogger()->debug('No target id given');
310  return false;
311  }
312  $obj_settings = new ilLTIProviderObjectSetting($target_ref_id, $consumer->getExtConsumerId());
313 
314  // @todo read from lti data
315  $roles = $_POST['roles'];
316  if (!strlen($roles)) {
317  $this->getLogger()->debug('No role information given');
318  return false;
319  }
320  $role_arr = explode(',', $roles);
321 
322  foreach ($role_arr as $role_name) {
323  $role_name = trim($role_name);
324  switch ($role_name) {
325  case 'Administrator':
326 
327  $this->getLogger()->debug('Administrator role handling');
328  if ($obj_settings->getAdminRole()) {
329  $GLOBALS['DIC']->rbac()->admin()->assignUser(
330  $obj_settings->getAdminRole(),
331  $user_id
332  );
333  }
334  break;
335 
336  case 'Instructor':
337  $this->getLogger()->debug('Instructor role handling');
338  $this->getLogger()->debug('Tutor role for request: ' . $obj_settings->getTutorRole());
339  if ($obj_settings->getTutorRole()) {
340  $GLOBALS['DIC']->rbac()->admin()->assignUser(
341  $obj_settings->getTutorRole(),
342  $user_id
343  );
344  }
345  break;
346 
347  case 'Member':
348  case 'Learner':
349  $this->getLogger()->debug('Member role handling');
350  if ($obj_settings->getMemberRole()) {
351  $GLOBALS['DIC']->rbac()->admin()->assignUser(
352  $obj_settings->getMemberRole(),
353  $user_id
354  );
355  }
356  break;
357  }
358  }
359  }
360 
366  public static function getAuthModeByKey($a_auth_key)
367  {
368  $auth_arr = explode('_', $a_auth_key);
369  if (count((array) $auth_arr) > 1) {
370  return 'lti_' . $auth_arr[1];
371  }
372  return 'lti';
373  }
374 
380  public static function getKeyByAuthMode($a_auth_mode)
381  {
382  $auth_arr = explode('_', $a_auth_mode);
383  if (count((array) $auth_arr) > 1) {
384  return AUTH_PROVIDER_LTI . '_' . $auth_arr[1];
385  }
386  return AUTH_PROVIDER_LTI;
387  }
388 
389 
393  public static function getActiveAuthModes()
394  {
395  global $ilDB;
396 
397  // move to connector
398  $query = 'SELECT consumer_pk from lti2_consumer where enabled = ' . $ilDB->quote(1, 'integer');
399  $res = $ilDB->query($query);
400 
401  $sids = array();
402  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
403  $sids[] = $row->consumer_pk;
404  }
405  return $sids;
406  }
407 
408  public static function getAuthModes()
409  {
410  global $ilDB;
411 
412  // move to connector
413  $query = 'SELECT distinct(consumer_pk) consumer_pk from lti2_consumer';
414  $res = $ilDB->query($query);
415 
416  $sids = array();
417  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
418  $sids[] = $row->consumer_pk;
419  }
420  return $sids;
421  }
422 
428  public static function lookupConsumer($a_sid)
429  {
430  include_once './Services/LTI/classes/class.ilLTIDataConnector.php';
431  $connector = new ilLTIDataConnector();
432  include_once './Services/LTI/classes/InternalProvider/class.ilLTIToolConsumer.php';
433  $consumer = ilLTIToolConsumer::fromRecordId($a_sid, $connector);
434  return $consumer->getTitle();
435  }
436 
442  public static function getServerIdByAuthMode($a_auth_mode)
443  {
444  if (self::isAuthModeLTI($a_auth_mode)) {
445  $auth_arr = explode('_', $a_auth_mode);
446  return $auth_arr[1];
447  }
448  return null;
449  }
450 
455  public static function isAuthModeLTI($a_auth_mode)
456  {
457  if (!$a_auth_mode) {
458  ilLoggerFactory::getLogger('lti')->warning('No auth mode given.');
459  return false;
460  }
461  $auth_arr = explode('_', $a_auth_mode);
462  return ($auth_arr[0] == AUTH_PROVIDER_LTI) and $auth_arr[1];
463  }
464 }
static fromRecordId($id, $dataConnector)
Load the tool consumer from the database by its record ID.
updateUser($a_local_user_id, ilLTIToolConsumer $consumer)
update existing user
$_SESSION["AccountId"]
static getKeyByAuthMode($a_auth_mode)
Get auth id by auth mode.
static getServerIdByAuthMode($a_auth_mode)
Get auth id by auth mode.
$_GET["client_id"]
Class to represent an LTI Data Connector for ILIAS.
const STATUS_AUTHENTICATION_FAILED
LTI provider for LTI launch.
const IL_PASSWD_CRYPTED
findAuthKeyId($a_oauth_consumer_key)
find consumer key id type $ilDB
static _generateLogin($a_login)
generate free login by starting with a default string and adding postfix numbers
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
static lookupConsumer($a_sid)
Lookup consumer title.
static _lookupId($a_user_str)
Lookup id by login.
createUser(ilLTIToolConsumer $consumer)
create new user
setAuthenticatedUserId($a_id)
Base class for authentication providers (radius, ldap, apache, ...)
Standard interface for auth provider implementations.
static getActiveAuthModes()
get all active authmode server ids
handleLocalRoleAssignments($user_id, ilLTIToolConsumer $consumer)
LTI provider for LTI launch.
setStatus($a_status)
Set auth status.
foreach($_POST as $key=> $value) $res
findGlobalRole($a_lti_id)
find global role of consumer
$query
$consumer
Definition: demo.php:30
setReason($a_reason)
Set reason.
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
findUserId($a_oauth_user, $a_oauth_id, $a_user_prefix)
Find user by auth mode and lti id.
static _checkExternalAuthAccount($a_auth, $a_account, $tryFallback=true)
check whether external account and authentication method matches with a user
getLogger()
Get logger.
OAuth based lti authentication.
static isAuthModeLTI($a_auth_mode)
Check if user auth mode is LDAP.
static getAuthModeByKey($a_auth_key)
Get auth mode by key.
findAuthPrefix($a_lti_id)
find lti id
global $ilSetting
Definition: privfeed.php:17
global $ilDB
static getLogger($a_component_id)
Get component logger.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
doAuthentication(\ilAuthStatus $status)
Do authentication.
Auth status implementation.
const AUTH_PROVIDER_LTI
$_POST["username"]