*/ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); class action_plugin_evesso extends DokuWiki_Action_Plugin { /** * Registers a callback function for a given event * * @param Doku_Event_Handler $controller DokuWiki's event controller object * @return void */ public function register(Doku_Event_Handler $controller) { global $conf; if($conf['authtype'] != 'evesso') return; $conf['profileconfirm'] = false; // password confirmation doesn't work with oauth only users $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'handle_start'); $controller->register_hook('HTML_LOGINFORM_OUTPUT', 'BEFORE', $this, 'handle_loginform'); $controller->register_hook('HTML_UPDATEPROFILEFORM_OUTPUT', 'BEFORE', $this, 'handle_profileform'); $controller->register_hook('FORM_LOGIN_OUTPUT', 'BEFORE', $this, 'handle_loginform'); $controller->register_hook('FORM_UPDATEPROFILE_OUTPUT', 'BEFORE', $this, 'handle_profileform'); $controller->register_hook('AUTH_USER_CHANGE', 'BEFORE', $this, 'handle_usermod'); $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_dologin'); } /** * Start an oAuth login or restore environment after successful login * * @param Doku_Event $event event object by reference * @param mixed $param [the parameters passed as fifth argument to register_hook() when this * handler was registered] * @return void */ public function handle_start(Doku_Event &$event, $param) { global $ID; if (isset($_SESSION[DOKU_COOKIE]['oauth-logout'])){ unset($_SESSION[DOKU_COOKIE]['oauth-logout']); send_redirect(wl($ID)); return; } if (isset($_SESSION[DOKU_COOKIE]['oauth-done']['do']) || !empty($_SESSION[DOKU_COOKIE]['oauth-done']['rev'])){ $this->restoreSessionEnvironment(); return; } $this->updateGroups(); $this->startOAuthLogin(); } public function updateGroups() { global $AUTH_ACL, $ID; $showMessage = false; $updateACL = false; foreach ($AUTH_ACL as $index => $value) { //Search $acl = preg_split("/\s/", $value); if ($this->startsWith($acl[1], "@eve%2d")) { $showMessage = true; if ($acl[2] != 0) { $updateACL = true; } } } if ($updateACL) { $apa = plugin_load('admin', 'acl'); foreach ($AUTH_ACL as $index => $value) { $acl = preg_split("/\s/", $value); if ($this->startsWith($acl[1], "@eve%2d") && $acl[2] != 0) { if (method_exists($apa, "addOrUpdateACL")) { $apa->addOrUpdateACL($acl[0], rawurldecode($acl[1]), 0); //Scope, User/Group } else { //Greebo and bellow $apa->_acl_del($acl[0], rawurldecode($acl[1])); // first make sure we won't end up with 2 lines matching this user and scope. $apa->_acl_add($acl[0], rawurldecode($acl[1]), 0); //Scope, User/Group } $AUTH_ACL[$index] = $acl[0] . ' ' . $acl[1] . ' ' . '0'; } } } if ($showMessage) { msg('EVESSO:
' . 'The naming of eve groups was changed in this version of EVESSO.
' . 'Access for all the deprecated groups have been set to None.
' . 'See the readme for the details on how the naming have changed.
' . 'Update your ACL settings to restore access.
' . 'This message will remain until the deprecated groups are removed from ACL.
' , 2, '', '', MSG_ADMINS_ONLY); } } private function startOAuthLogin() { global $INPUT, $ID; /** @var helper_plugin_evesso $hlp */ $hlp = plugin_load('helper', 'evesso'); $servicename = $INPUT->str('evessologin'); $service = $hlp->loadService($servicename); if(is_null($service)) return; // remember service in session session_start(); $_SESSION[DOKU_COOKIE]['oauth-inprogress']['service'] = $servicename; $_SESSION[DOKU_COOKIE]['oauth-inprogress']['id'] = $ID; session_write_close(); $service->login(); } private function restoreSessionEnvironment() { global $INPUT, $ACT, $TEXT, $PRE, $SUF, $SUM, $RANGE, $DATE_AT, $REV; $ACT = $_SESSION[DOKU_COOKIE]['oauth-done']['do']; $_REQUEST = $_SESSION[DOKU_COOKIE]['oauth-done']['$_REQUEST']; $REV = $INPUT->int('rev'); $DATE_AT = $INPUT->str('at'); $RANGE = $INPUT->str('range'); if($INPUT->post->has('wikitext')) { $TEXT = cleanText($INPUT->post->str('wikitext')); } $PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1)); $SUF = cleanText($INPUT->post->str('suffix')); $SUM = $INPUT->post->str('summary'); unset($_SESSION[DOKU_COOKIE]['oauth-done']); } /** * Save groups for all the services a user has enabled * * @param Doku_Event $event event object by reference * @param mixed $param [the parameters passed as fifth argument to register_hook() when this * handler was registered] * @return void */ public function handle_usermod(Doku_Event &$event, $param) { global $ACT; global $USERINFO; global $auth; global $INPUT; if($event->data['type'] != 'modify') return; if($ACT != 'profile') return; // we want to modify the user's groups $groups = $USERINFO['grps']; //current groups if(isset($event->data['params'][1]['grps'])) { // something already defined new groups $groups = $event->data['params'][1]['grps']; } /** @var helper_plugin_evesso $hlp */ $hlp = plugin_load('helper', 'evesso'); // get enabled and configured services $enabled = $INPUT->arr('oauth_group'); // add all enabled services as group, remove all disabled services if(isset($enabled['EveOnline'])) { //Add EveOnline $groups[] = 'eveonline'; } else { //Remove EveOnline $idx = array_search('eveonline', $groups); if($idx !== false) unset($groups[$idx]); } $groups = array_unique($groups); // add new group array to event data $event->data['params'][1]['grps'] = $groups; } /** * Add service selection to user profile * * @param Doku_Event $event event object by reference * @param mixed $param [the parameters passed as fifth argument to register_hook() when this * handler was registered] * @return void */ public function handle_profileform(Doku_Event &$event, $param) { global $USERINFO; /** @var auth_plugin_authplain $auth */ global $auth; /** @var helper_plugin_evesso $hlp */ $hlp = plugin_load('helper', 'evesso'); /** @var Doku_Form $form */ $form =& $event->data; if (!in_array('eveonline', $USERINFO['grps'])) { return; //Continue as normal } if(is_a($form, \dokuwiki\Form\Form::class)) { //Igor and later //Disable fullname field $pos = $form->findPositionByAttribute('name', 'fullname'); $form->getElementAt($pos)->attr('disabled', 'disabled'); //Remove all fields except username and fullname $start = $form->findPositionByAttribute('name', 'fullname') + 1; $done = 0; while ($form->elementCount() > $start && $done < 11) { $form->removeElement($start); $done++; } $pos = $form->elementCount(); //Add corporation, alliance, faction fields foreach ($USERINFO['grps'] as $group) { if ($this->startsWith($group, helper_plugin_evesso::CORPORATION_PREFIX)) { $corp = $this->replaceFirst($group, helper_plugin_evesso::CORPORATION_PREFIX); } if ($this->startsWith($group, helper_plugin_evesso::ALLIANCE_PREFIX)) { $alliance = $this->replaceFirst($group, helper_plugin_evesso::ALLIANCE_PREFIX); } if ($this->startsWith($group, helper_plugin_evesso::FACTION_PREFIX)) { $faction = $this->replaceFirst($group, helper_plugin_evesso::FACTION_PREFIX); } } if (isset($faction)) { //str_starts_with $this->insertTextInput($form, $pos, $faction, $this->getLang('faction')); } if (isset($alliance)) { //str_starts_with $this->insertTextInput($form, $pos, $alliance, $this->getLang('alliance')); } if (isset($corp)) { //str_starts_with $this->insertTextInput($form, $pos, $corp, $this->getLang('corporation')); } } else { //Hogfather and earlier //Remove all fields except username and fullname array_splice($form->_content, 3); //Disable fullname field $form->getElementAt(3)['disabled'] = 'disabled'; //Add corporation, alliance, faction fields $pos = count($form->_content); foreach ($USERINFO['grps'] as $group) { if ($this->startsWith($group, helper_plugin_evesso::CORPORATION_PREFIX)) { $corp = $this->replaceFirst($group, helper_plugin_evesso::CORPORATION_PREFIX); } if ($this->startsWith($group, helper_plugin_evesso::ALLIANCE_PREFIX)) { $alliance = $this->replaceFirst($group, helper_plugin_evesso::ALLIANCE_PREFIX); } if ($this->startsWith($group, helper_plugin_evesso::FACTION_PREFIX)) { $faction = $this->replaceFirst($group, helper_plugin_evesso::FACTION_PREFIX); } } $form->insertElement($pos, form_closefieldset()); if (isset($faction)) { //str_starts_with $form->insertElement($pos, form_makeTextField($faction, $faction, $this->getLang('faction'), '', 'block', array('disabled' => 'disabled', 'size' => '50'))); } if (isset($alliance)) { //str_starts_with $form->insertElement($pos, form_makeTextField($alliance, $alliance, $this->getLang('alliance'), '', 'block', array('disabled' => 'disabled', 'size' => '50'))); } if (isset($corp)) { //str_starts_with $form->insertElement($pos, form_makeTextField($corp, $corp, $this->getLang('corporation'), '', 'block', array('disabled' => 'disabled', 'size' => '50'))); } } } private function startsWith($haystack, $needle) { $length = strlen($needle); return (substr($haystack, 0, $length) === $needle); } private function replaceFirst($haystack, $needle, $replace = '') { $pos = strpos($haystack, $needle); if ($pos !== false) { $haystack = substr_replace($haystack, $replace, $pos, strlen($needle)); } return $haystack; } private function insertTextInput($form, $pos, $value, $name) { $textInput = $form->addTextInput($value, $name, $pos); $textInput->attr('size', '50'); $textInput->attr('class', 'edit'); $textInput->attr('value', $value); $textInput->attr('disabled', 'disabled'); $label = $textInput->getLabel(); $label->attr('class', 'block'); $form->addHTML('
', $pos); } private function insertElement($form, $pos, $out) { if(is_a($form, \dokuwiki\Form\Form::class)) { //Igor and later $form->addHtml($out, $pos); } else { //Hogfather and earlier $form->insertElement($pos, $out); } } /** * Add the oAuth login links * * @param Doku_Event $event event object by reference * @param mixed $param [the parameters passed as fifth argument to register_hook() when this * handler was registered] * @return void */ public function handle_loginform(Doku_Event &$event, $param) { /** @var helper_plugin_evesso $hlp */ $hlp = plugin_load('helper', 'evesso'); $service = $hlp->getService(); /** @var Doku_Form $form */ $form =& $event->data; $html = ''; if ($hlp->isEveAuth()) { //Set Html if(is_a($form, \dokuwiki\Form\Form::class)) { //Igor and later while ($form->elementCount() > 0) { $form->removeElement(0); } $pos = $form->elementCount() - 3; //At the end } else { //Hogfather and earlier $form->_content = array(); $pos = 0; } $html = $this->service_html($service); }else{ //PlainAuth and EveAuth $html .= $this->service_html($service); if(is_a($form, \dokuwiki\Form\Form::class)) { //Igor and later $pos = $form->elementCount(); //At the end } else { //Hogfather and earlier $pos = count($form->_content); } } if(is_a($form, \dokuwiki\Form\Form::class)) { //Igor and later $form->addFieldsetOpen($this->getLang('loginwith'), ++$pos); $form->addHtml($html, ++$pos); $form->addFieldsetClose(); } else { //Hogfather and earlier $form->insertElement(++$pos, form_openfieldset(array('_legend' => $this->getLang('loginwith'), 'class' => 'plugin_evesso'))); $form->insertElement(++$pos, $html); $form->insertElement(++$pos, form_closefieldset()); } } function service_html($service) { global $ID; $html = ''; $html .= ''; if ($this->getConf('login-button') == 'Button') { $html .= '
'; } elseif ($this->getConf('login-button') == 'LargeLight') { $html .= '
'; } elseif ($this->getConf('login-button') == 'LargeDark') { $html .= '
'; } elseif ($this->getConf('login-button') == 'SmallLight') { $html .= '
'; } elseif ($this->getConf('login-button') == 'SmallDark') { $html .= '
'; } else { $html .= $this->getLang('loginButton'); } $html .= '
'; return $html; } public function handle_dologin(Doku_Event &$event, $param) { global $lang; global $ID; $hlp = plugin_load('helper', 'evesso'); if($event->data == 'logout' && $hlp->isEveAuth()) { session_start(); $_SESSION[DOKU_COOKIE]['oauth-logout'] = 'logout'; session_write_close(); } if ($hlp->isAuthPlain()) return true; if($event->data != 'login') return true; if($hlp->isEveAuthDirect()) { $lang['btn_login'] = $this->getLang('loginButton'); $url = wl($ID, array('evessologin' => $hlp->getService()), true, '&'); send_redirect($url); } } } // vim:ts=4:sw=4:et: