16 require_once SQ_PACKAGES_PATH.
'/cms/page_templates/page_asset_builder/page_asset_builder.inc';
17 require_once SQ_INCLUDE_PATH.
'/asset.inc';
18 require_once SQ_DATA_PATH.
'/private/conf/tools.inc';
35 var $saml_auth_manager;
47 parent::__construct($assetid);
49 require_once SQ_TOOL_SIMPLESAMLPHP_PATH.
'/lib/_autoload.php';
50 require_once SQ_PACKAGES_PATH.
'/saml/lib/saml_auth_manager.inc';
67 $this->saml_auth_manager = null;
68 $this->idp_entityid = null;
80 require_once SQ_PACKAGES_PATH.
'/saml/lib/saml_auth_manager.inc';
81 if($this->saml_auth_manager)
return $this->saml_auth_manager;
83 return $this->saml_auth_manager;
94 if($this->idp_entityid)
return $this->idp_entityid;
95 require SQ_TOOL_SIMPLESAMLPHP_PATH.
'/config/authsources.php';
96 $authConfig = array_get_index($config, $this->
attr(
'auth_source'));
97 $this->idp_entityid = array_get_index($authConfig,
'idp');
98 return $this->idp_entityid;
111 $authData = $saml_auth_manager->getAuthDataArray();
113 $location = $this->
attr(
'saml_userid_location');
114 if($location ==
'nameid') {
116 $nameid_array = array_get_index($authData,
'saml:sp:NameID');
117 return (array_get_index($nameid_array,
'Value'));
121 $attribute = $this->
attr(
'saml_userid_attribute');
122 $attributes_array = array_get_index($authData,
'Attributes');
123 return (array_get_index(array_get_index($attributes_array, $attribute), 0));
138 return (SQ_TOOL_SIMPLESAMLPHP_PATH && file_exists(SQ_TOOL_SIMPLESAMLPHP_PATH.
'/lib/_autoload.php'));
150 return parent::create($link);
167 if (!parent::_createAdditional($link))
return FALSE;
170 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'saml2_acs');
171 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'saml2_sls');
174 'saml2_assertion_consumer_service' =>
'saml2_acs',
175 'saml2_single_logout_service' =>
'saml2_sls',
178 foreach ($sub_assets as $name => $type) {
179 $asset =
new $type();
180 $copy_link = Array(
'asset' => &$this,
'value' => $name ,
'link_type' => SQ_LINK_TYPE_2,
'is_dependant' => 1,
'is_exclusive' => 1);
182 $asset->setAttrValue(
'name', ucwords(str_replace(
'_',
' ', $name)));
183 if (!$asset->create($copy_link))
return FALSE;
184 $GLOBALS[
'SQ_SYSTEM']->am->forgetAsset($asset);
203 $page_links = parent::_getAllowedLinks();
204 $page_links[SQ_LINK_TYPE_2][
'saml2_acs'] = Array(
'card' =>
'M',
'exclusive' => TRUE);
205 $page_links[SQ_LINK_TYPE_2][
'saml2_sls'] = Array(
'card' =>
'M',
'exclusive' => TRUE);
222 trigger_error(
'Simplesamlphp library is not installed');
225 require_once SQ_TOOL_SIMPLESAMLPHP_PATH.
'/lib/_autoload.php';
226 require_once SQ_PACKAGES_PATH.
'/saml/lib/saml_auth_manager.inc';
231 if(!isset($_SESSION[
'sq_saml_account_manager_current_state_redirect_url'])) {
233 if(!empty($redirect_url))
234 $_SESSION[
'sq_saml_account_manager_current_state_redirect_url'] = $redirect_url;
244 if(isset($_GET[
'showMetadata'])) {
246 $acs_asset = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'saml2_acs', TRUE,
'saml2_assertion_consumer_service',
'major',
'1');
247 $acs_url = array_get_index( $GLOBALS[
'SQ_SYSTEM']->am->getAssetURL(Array($acs_asset[
'minorid'])), $acs_asset[
'minorid']);
250 $sls_asset = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'saml2_sls', TRUE,
'saml2_single_logout_service',
'major',
'1');
251 $sls_url = array_get_index( $GLOBALS[
'SQ_SYSTEM']->am->getAssetURL(Array($sls_asset[
'minorid'])), $sls_asset[
'minorid']);
253 $xml = $saml_auth_manager->printSPMetadataXML($acs_url, $sls_url);
254 header(
'Content-Type: application/samlmetadata+xml');
260 if(isset($_GET[
'linkAccounts'])) {
261 $allow_create_link = $this->
attr(
'allow_link');
263 if($allow_create_link && $saml_auth_manager->isAuthenticated()) {
266 $current_user = $GLOBALS[
'SQ_SYSTEM']->user;
268 if($current_user && !($current_user instanceof
Public_User)) {
273 if($this->
attr(
'redirect_after_link')) {
274 if(isset($_SESSION[
'sq_saml_account_manager_current_state_redirect_url']) && $_SESSION[
'sq_saml_account_manager_current_state_redirect_url']) {
275 $redirect_url = $_SESSION[
'sq_saml_account_manager_current_state_redirect_url'];
276 unset($_SESSION[
'sq_saml_account_manager_current_state_redirect_url']);
277 do_redirect($redirect_url);
281 unset($_SESSION[
'sq_saml_account_manager_current_state_redirect_url']);
314 if(isset($_GET[
'logout'])) {
319 if($saml_auth_manager->isAuthenticated()) {
323 $options[
'ReturnTo'] = $return_url;
325 $saml_auth_manager->logout($options);
332 parent::printFrontend();
349 if (isset($_POST[
'AB_'.$this->
id.
'_ASSET_BUILDER_ACTION'])) {
350 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
353 $this->_current_state =
'';
354 $current_user = $GLOBALS[
'SQ_SYSTEM']->user;
355 set_error_handler(Array(&$this,
'_errorHandler'));
357 restore_error_handler();
360 if (isset($_POST[
'AB_'.$this->
id.
'_ASSET_BUILDER_ACTION']) && !$success) {
361 $this->_replacements[strtolower($_POST[
'AB_'.$this->
id.
'_ASSET_BUILDER_ACTION']).
'_error'] = $this->
attr(strtolower($_POST[
'AB_'.$this->
id.
'_ASSET_BUILDER_ACTION']).
'_error');
363 if (!empty($this->_errors)) {
365 foreach ($this->_errors as $text) {
366 $errors .=
'<li>'.$text.
'</li>';
368 $this->_replacements[strtolower($_POST[
'AB_'.$this->
id.
'_ASSET_BUILDER_ACTION']).
'_error'] .=
'<ul>'.$errors.
'</ul>';
371 if(isset($_SESSION[
'sq_saml_account_manager_auth_error'])) {
372 $this->_replacements[
'auth_error'] = $_SESSION[
'sq_saml_account_manager_auth_error'];
373 $this->_current_state =
'auth_fail';
374 unset($_SESSION[
'sq_saml_account_manager_auth_error']);
378 $GLOBALS[
'SQ_SYSTEM']->pm->startTimer($this,
'printBody');
383 if (isset($this->_tmp[
'created_asset'])) {
385 unset($this->_tmp[
'created_asset']);
390 $allow_create_link = $this->
attr(
'allow_link');
391 if(empty($this->_current_state) && !$allow_create_link) {
392 if(!is_null($current_user) && !($current_user instanceof
Public_User))
393 $this->_current_state =
'logged_in';
396 if (empty($this->_current_state)) {
401 if(!$saml_auth_manager->isAuthenticated()) {
405 if($this->
attr(
'use_extensions')) {
406 $extensions = $this->
attr(
'extensions');
408 if(!empty($extensions)) {
409 $dom =
new DOMDocument();
410 $dom->loadXML($extensions);
411 $extension_node = $dom->getElementsByTagName(
'Extensions')->item(0);
412 $child_nodes = $extension_node->childNodes;
413 foreach ($child_nodes as $node) {
414 $ext[] =
new SAML2_XML_Chunk($node);
418 $options[
'saml:Extensions'] = $ext;
423 $acs_asset = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'saml2_acs', TRUE,
'saml2_assertion_consumer_service',
'major',
'1');
424 $acs_url = array_get_index( $GLOBALS[
'SQ_SYSTEM']->am->getAssetURL(Array($acs_asset[
'minorid'])), $acs_asset[
'minorid']);
425 $options[
'acs_url'] = $acs_url;
428 $protocol_binding = $this->
attr(
'protocol_binding');
429 $nameid_policy = $this->
attr(
'nameid_policy');
430 $authn_context_class_ref = $this->
attr(
'authn_context_class_ref');
432 if(!empty($protocol_binding)) {
433 $options[
'ProtocolBinding'] = $protocol_binding;
435 if(!empty($nameid_policy)) {
436 $options[
'saml:NameIDPolicy'] = $nameid_policy;
438 if(!empty($authn_context_class_ref)) {
439 $options[
'saml:AuthnContextClassRef'] = $authn_context_class_ref;
443 while (ob_get_level() > SQ_INIT_OB_LEVEL) {
448 $saml_auth_manager->login($options);
462 if ((is_null($current_user) || ($current_user instanceof
Public_User)) && $matrixUserid) {
464 $current_user = $GLOBALS[
'SQ_SYSTEM']->user;
470 if (is_null($current_user) || ($current_user instanceof Public_User)) {
471 $auto_create = $this->
attr(
'auto_create');
474 $create_type = $this->
attr(
'create_type');
475 $create_type = array_pop(array_keys($create_type));
479 $this->_current_state =
'create_user';
486 if($GLOBALS[
'SQ_SYSTEM']->currentUserId() == $matrixUserid) {
488 $this->_current_state =
'logged_in';
492 $this->_current_state =
'create_link';
501 if( $this->_current_state ==
'logged_in' && $this->
attr(
'redirect_after_login') && isset($_SESSION[
'sq_saml_account_manager_current_state_redirect_url']) && $_SESSION[
'sq_saml_account_manager_current_state_redirect_url']) {
502 $redirect_url = $_SESSION[
'sq_saml_account_manager_current_state_redirect_url'];
503 unset($_SESSION[
'sq_saml_account_manager_current_state_redirect_url']);
504 do_redirect($redirect_url);
508 $fn =
'_load'.$this->_default_state.
'Replacements';
509 $this->_loadcreateReplacements();
514 if($saml_auth_manager->isAuthenticated()) {
515 $auth_data = $saml_auth_manager->getAuthDataArray();
516 $attributes_array = array_get_index($auth_data,
'Attributes');
519 if(!empty($attributes_array)) {
521 $bodycopy_data = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_TYPE_2,
'bodycopy', TRUE, $this->_current_state,
'major',
'1');
522 if(!empty($bodycopy_data)) {
523 $bodycopy = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($bodycopy_data[
'minorid'], $bodycopy_data[
'minor_type_code']);
524 $keywords = $bodycopy->getKeywords();
525 foreach($keywords as $word) {
526 $keyword = parse_keyword($word, $modifiers);
527 if($keyword ===
'user_attributes_xml') {
529 $xml =
new SimpleXMLElement(
'<root/>');
530 arrayToXml($attributes_array, $xml);
531 $replacement = $xml->asXML();
532 apply_keyword_modifiers($replacement, $modifiers);
533 $this->_replacements[$word] = $replacement;
548 $GLOBALS[
'SQ_SYSTEM']->pm->stopTimer($this,
'printBody');
550 if (isset($_POST[
'AB_'.$this->
id.
'_ASSET_BUILDER_ACTION'])) {
551 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
574 $this->vars[
'create_status'][
'value'] = SQ_STATUS_LIVE;
576 $success = parent::_processGlobalActions();
577 if (!$success)
return FALSE;
582 if($this->_current_state ===
'created' && !empty($this->_tmp[
'created_asset'])) {
585 if(!empty($samlUserid))
588 $this->
_loginUser($this->_tmp[
'created_asset']->
id);
590 $this->_current_state =
'logged_in';
611 if (empty($samlUserid))
616 'samlid' => $samlUserid,
620 if(empty($result))
return NULL;
622 return ($result[0][
'assetid']);
637 if (empty($matrixUserid) || empty($samlUserid) )
642 if($existingMatrixUserid) {
644 'assetid' => $matrixUserid,
645 'samlid' => $samlUserid,
647 'updated' => ts_iso8601(time()),
657 'assetid' => $matrixUserid,
658 'samlid' => $samlUserid,
660 'created' => ts_iso8601(time()),
661 'updated' => ts_iso8601(time()),
679 if (empty($matrixUserid) || empty($samlUserid) )
684 'assetid' => $matrixUserid,
685 'samlid' => $samlUserid,
705 $notice_links = unserialize(file_to_string($this->data_path.
'/.sq_notice_links'));
706 foreach ($notice_links as $link) {
707 if ($link[
'value'] ==
'redirect_asset') {
708 $redirect_link = $link;
713 if (!empty($this->
id)) {
714 $link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_NOTICE,
'', TRUE,
'redirect_asset');
718 $res = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($link[
'minorid'], $link[
'minor_type_code']);
736 $old_link = $GLOBALS[
'SQ_SYSTEM']->am->getLink($this->
id, SQ_LINK_NOTICE,
'', TRUE,
'redirect_asset');
737 $GLOBALS[
'SQ_SYSTEM']->changeDatabaseConnection(
'db2');
738 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'BEGIN');
739 if (empty($old_link)) {
741 if (is_null($asset)) {
742 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
743 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
748 }
else if (!is_null($asset) && $old_link[
'minorid'] == $asset->id) {
749 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
750 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
755 if (!$this->
deleteLink($old_link[
'linkid'])) {
756 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
757 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
762 if (!is_null($asset)) {
763 if (!$this->
createLink($asset, SQ_LINK_NOTICE,
'redirect_asset')) {
764 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'ROLLBACK');
765 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
770 $GLOBALS[
'SQ_SYSTEM']->doTransaction(
'COMMIT');
771 $GLOBALS[
'SQ_SYSTEM']->restoreDatabaseConnection();
788 $qrystr_param = $this->
attr(
'use_querystring_parameter');
789 $url = trim($this->
attr(
'redirect_url'));
790 if ($qrystr_param && isset($_GET[$qrystr_param]) && trim($_GET[$qrystr_param]) !=
'') {
791 $url = trim($_GET[$qrystr_param]);
794 }
else if ($url !=
'') {
796 replace_global_keywords($url);
801 if (!is_null($redirect_asset)) {
802 if (($url = $redirect_asset->getURL()) ==
'') {
803 $url = current_url().
'?a='.$redirect_asset->id;
816 $stripchars = array();
817 for ($i = 0; $i < 32; $stripchars[] = chr($i), $i++);
818 $url = str_replace($stripchars,
'', $url);
840 if (!isset($vars[
'keywords']))
return;
843 $parents = $GLOBALS[
'SQ_SYSTEM']->am->getParents($broadcaster->id,
'bodycopy', TRUE);
844 $type_links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($this->
id, SQ_LINK_TYPE_2,
'bodycopy');
846 foreach ($type_links as $link_info) {
847 if (isset($parents[$link_info[
'minorid']])) {
848 $bodycopy_type = $link_info[
'value'];
852 switch ($bodycopy_type) {
857 $vars[
'keywords'] = array_merge($vars[
'keywords'], Array(
'auth_error' => translate(
'saml_account_manager_auth_error')));
862 $vars[
'keywords'] = array_merge($vars[
'keywords'], Array(
'user_attributes_xml' => translate(
'saml_account_manager_user_attributes_xml')));
863 $vars[
'keywords'] = array_merge($vars[
'keywords'], Array(
'user_saml_id' => translate(
'saml_account_manager_user_saml_id')));
881 $res[
'create_user']= Array(
882 'name' => translate(
'saml_account_manager_create_user'),
883 'content' =>
'%create_error% %login_error% %login_invite% %login_form% %create_form%',
885 $res[
'create_link']= Array(
886 'name' => translate(
'saml_account_manager_create_link'),
887 'content' =>
'SAML account is not linked to current Matrix user. <a href="?linkAccounts">Link them now</a>.',
889 $res[
'logged_in']= Array(
890 'name' => translate(
'logged_in'),
891 'content' =>
'logged in as %globals_user_name%',
893 $res[
'auth_fail']= Array(
894 'name' => translate(
'saml_account_manager_auth_fail'),
895 'content' =>
'%auth_error%',
911 $user = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($userid);
912 if($user && $user->canLogin()) {
913 unset($_SESSION[
'SQ_RETURN_TO_HTTP']);
914 $GLOBALS[
'SQ_SYSTEM']->loginUser($user);
916 if($this->
attr(
'redirect_after_login')) {
917 if(isset($_SESSION[
'sq_saml_account_manager_current_state_redirect_url']) && $_SESSION[
'sq_saml_account_manager_current_state_redirect_url']) {
918 $redirect_url = $_SESSION[
'sq_saml_account_manager_current_state_redirect_url'];
919 unset($_SESSION[
'sq_saml_account_manager_current_state_redirect_url']);
920 do_redirect($redirect_url);
924 unset($_SESSION[
'sq_saml_account_manager_current_state_redirect_url']);
938 $for_real = ( $GLOBALS[
'SQ_SYSTEM']->user && !($GLOBALS[
'SQ_SYSTEM']->user instanceof
Public_User));
939 $old_user = &$GLOBALS[
'SQ_SYSTEM']->user;
941 $GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_before_user_logout', $old_user, NULL);
943 foreach (array_keys($_SESSION) as $key) {
944 if ($key ==
'SQ_RETURN_TO_HTTP')
continue;
947 if ($key ==
'user_login_attempts')
continue;
949 if( !$clear_saml_session && $key ==
'SimpleSAMLphp_SESSION')
continue;
951 unset($_SESSION[$key]);
954 $GLOBALS[
'SQ_SYSTEM']->broadcastTriggerEvent(
'trigger_event_user_logout', $old_user, NULL);
956 $GLOBALS[
'SQ_SYSTEM']->loginPublicUser();
957 $GLOBALS[
'SQ_SYSTEM']->generateLoginKey(TRUE);
959 if($clear_saml_session) {
960 $this->saml_auth_manager = null;
975 $_POST[
'AB_'.$this->id.
'_ASSET_BUILDER_ACTION'] =
'create';
976 $_POST[
'AB_'.$this->id.
'_ASSET_BUILDER_CREATE_TYPE'] = $create_type;
978 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset($create_type);
979 $new_user =
new $create_type();
980 $prefix = $new_user->getPrefix();
981 $username_attr = $new_user->getAttribute(
'username', TRUE);
982 $password_attr = $new_user->getAttribute(
'password', TRUE);
983 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'user');
986 $user_username_attr = $user->getAttribute(
'username', TRUE);
987 $_POST[
'asset_action'] =
'create';
988 $_REQUEST[
'asset_action'] =
'create';
992 $valid_username = $new_user->getValidUsername($user_username_attr->id, $samlid);
993 $valid_password = random_user_password(Array($valid_username));
995 $_REQUEST[$prefix.
'_'.$username_attr->id] = $valid_username;
996 $_REQUEST[$prefix.
'_'.$password_attr->id.
'_one'] = $valid_password;
997 $_REQUEST[$prefix.
'_'.$password_attr->id.
'_two'] = $valid_password;