137d2401aSAnna Dabrowska<?php 237d2401aSAnna Dabrowska 31fad6988SAndreas Gohruse dokuwiki\Form\Form; 4d9be1cb5SAnna Dabrowskause dokuwiki\plugin\oauth\SessionManager; 537d2401aSAnna Dabrowskause OAuth\Common\Http\Exception\TokenResponseException; 637d2401aSAnna Dabrowska 737d2401aSAnna Dabrowska/** 837d2401aSAnna Dabrowska * DokuWiki Plugin oauth (Action Component) 937d2401aSAnna Dabrowska * 10*74b4d4a4SAndreas Gohr * This adds buttons to the login page and initializes the oAuth flow by redirecting the user 11*74b4d4a4SAndreas Gohr * to the third party service 12*74b4d4a4SAndreas Gohr * 1337d2401aSAnna Dabrowska * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 1437d2401aSAnna Dabrowska * @author Andreas Gohr <andi@splitbrain.org> 1537d2401aSAnna Dabrowska */ 1637d2401aSAnna Dabrowskaclass action_plugin_oauth_login extends DokuWiki_Action_Plugin 1737d2401aSAnna Dabrowska{ 1837d2401aSAnna Dabrowska /** @var helper_plugin_oauth */ 1937d2401aSAnna Dabrowska protected $hlp; 2037d2401aSAnna Dabrowska 2137d2401aSAnna Dabrowska /** 2237d2401aSAnna Dabrowska * Constructor 2337d2401aSAnna Dabrowska * 2437d2401aSAnna Dabrowska * Initializes the helper 2537d2401aSAnna Dabrowska */ 2637d2401aSAnna Dabrowska public function __construct() 2737d2401aSAnna Dabrowska { 2837d2401aSAnna Dabrowska $this->hlp = plugin_load('helper', 'oauth'); 2937d2401aSAnna Dabrowska } 3037d2401aSAnna Dabrowska 3137d2401aSAnna Dabrowska /** 3237d2401aSAnna Dabrowska * Registers a callback function for a given event 3337d2401aSAnna Dabrowska * 3437d2401aSAnna Dabrowska * @param Doku_Event_Handler $controller DokuWiki's event controller object 3537d2401aSAnna Dabrowska * @return void 3637d2401aSAnna Dabrowska */ 3737d2401aSAnna Dabrowska public function register(Doku_Event_Handler $controller) 3837d2401aSAnna Dabrowska { 3937d2401aSAnna Dabrowska global $conf; 4037d2401aSAnna Dabrowska if ($conf['authtype'] != 'oauth') return; 4137d2401aSAnna Dabrowska 4237d2401aSAnna Dabrowska $conf['profileconfirm'] = false; // password confirmation doesn't work with oauth only users 4337d2401aSAnna Dabrowska 4437d2401aSAnna Dabrowska $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'handleStart'); 451fad6988SAndreas Gohr $controller->register_hook('HTML_LOGINFORM_OUTPUT', 'BEFORE', $this, 'handleOldLoginForm'); // @deprecated 461fad6988SAndreas Gohr $controller->register_hook('FORM_LOGIN_OUTPUT', 'BEFORE', $this, 'handleLoginForm'); 4737d2401aSAnna Dabrowska $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleDoLogin'); 4837d2401aSAnna Dabrowska } 4937d2401aSAnna Dabrowska 5037d2401aSAnna Dabrowska /** 5137d2401aSAnna Dabrowska * Start an oAuth login or restore environment after successful login 5237d2401aSAnna Dabrowska * 5337d2401aSAnna Dabrowska * @param Doku_Event $event 5437d2401aSAnna Dabrowska * @return void 5537d2401aSAnna Dabrowska */ 5637d2401aSAnna Dabrowska public function handleStart(Doku_Event $event) 5737d2401aSAnna Dabrowska { 5837d2401aSAnna Dabrowska global $INPUT; 5937d2401aSAnna Dabrowska 6037d2401aSAnna Dabrowska // login has been done, but there's environment to be restored 61d9be1cb5SAnna Dabrowska // TODO when is this the case? 62d9be1cb5SAnna Dabrowska $sessionManager = SessionManager::getInstance(); 63d9be1cb5SAnna Dabrowska if ($sessionManager->getDo() || $sessionManager->getRev()) { 6437d2401aSAnna Dabrowska $this->restoreSessionEnvironment(); 6537d2401aSAnna Dabrowska return; 6637d2401aSAnna Dabrowska } 6737d2401aSAnna Dabrowska 6837d2401aSAnna Dabrowska // see if a login needs to be started 6937d2401aSAnna Dabrowska $servicename = $INPUT->str('oauthlogin'); 7037d2401aSAnna Dabrowska if ($servicename) $this->startOAuthLogin($servicename); 7137d2401aSAnna Dabrowska } 7237d2401aSAnna Dabrowska 7337d2401aSAnna Dabrowska /** 74d9be1cb5SAnna Dabrowska * Add the oAuth login links to login form 7537d2401aSAnna Dabrowska * 7637d2401aSAnna Dabrowska * @param Doku_Event $event event object by reference 7737d2401aSAnna Dabrowska * @return void 78*74b4d4a4SAndreas Gohr * @deprecated can be removed in the future 7937d2401aSAnna Dabrowska */ 801fad6988SAndreas Gohr public function handleOldLoginForm(Doku_Event $event) 8137d2401aSAnna Dabrowska { 8237d2401aSAnna Dabrowska /** @var Doku_Form $form */ 8337d2401aSAnna Dabrowska $form = $event->data; 841fad6988SAndreas Gohr $html = $this->prepareLoginButtons(); 851fad6988SAndreas Gohr if (!$html) return; 861fad6988SAndreas Gohr 871fad6988SAndreas Gohr $form->_content[] = form_openfieldset( 881fad6988SAndreas Gohr [ 891fad6988SAndreas Gohr '_legend' => $this->getLang('loginwith'), 901fad6988SAndreas Gohr 'class' => 'plugin_oauth', 911fad6988SAndreas Gohr ] 921fad6988SAndreas Gohr ); 931fad6988SAndreas Gohr $form->_content[] = $html; 941fad6988SAndreas Gohr $form->_content[] = form_closefieldset(); 951fad6988SAndreas Gohr } 961fad6988SAndreas Gohr 971fad6988SAndreas Gohr /** 981fad6988SAndreas Gohr * Add the oAuth login links to login form 991fad6988SAndreas Gohr * 1001fad6988SAndreas Gohr * @param Doku_Event $event event object by reference 1011fad6988SAndreas Gohr * @return void 102*74b4d4a4SAndreas Gohr * @deprecated can be removed in the future 1031fad6988SAndreas Gohr */ 1041fad6988SAndreas Gohr public function handleLoginForm(Doku_Event $event) 1051fad6988SAndreas Gohr { 1061fad6988SAndreas Gohr /** @var Form $form */ 1071fad6988SAndreas Gohr $form = $event->data; 1081fad6988SAndreas Gohr $html = $this->prepareLoginButtons(); 1091fad6988SAndreas Gohr if (!$html) return; 1101fad6988SAndreas Gohr 1111fad6988SAndreas Gohr $form->addFieldsetOpen($this->getLang('loginwith'))->addClass('plugin_oauth'); 1121fad6988SAndreas Gohr $form->addHTML($html); 1131fad6988SAndreas Gohr $form->addFieldsetClose(); 1141fad6988SAndreas Gohr } 1151fad6988SAndreas Gohr 1161fad6988SAndreas Gohr /** 1171fad6988SAndreas Gohr * Create HTML for the various login buttons 1181fad6988SAndreas Gohr * 1191fad6988SAndreas Gohr * @return string the HTML 1201fad6988SAndreas Gohr */ 121*74b4d4a4SAndreas Gohr protected function prepareLoginButtons() 122*74b4d4a4SAndreas Gohr { 12337d2401aSAnna Dabrowska $html = ''; 12437d2401aSAnna Dabrowska 12537d2401aSAnna Dabrowska $validDomains = $this->hlp->getValidDomains(); 12637d2401aSAnna Dabrowska 12737d2401aSAnna Dabrowska if (count($validDomains) > 0) { 1286f3a59e8SAndreas Gohr $html .= '<p class="plugin-oauth-emailrestriction">' . sprintf( 1296f3a59e8SAndreas Gohr $this->getLang('eMailRestricted'), 1306f3a59e8SAndreas Gohr '<b>' . join(', ', $validDomains) . '</b>' 1316f3a59e8SAndreas Gohr ) . '</p>'; 13237d2401aSAnna Dabrowska } 13337d2401aSAnna Dabrowska 13437d2401aSAnna Dabrowska foreach ($this->hlp->listServices() as $service) { 13537d2401aSAnna Dabrowska $html .= $service->loginButton(); 13637d2401aSAnna Dabrowska } 13737d2401aSAnna Dabrowska 1381fad6988SAndreas Gohr return $html; 13937d2401aSAnna Dabrowska } 14037d2401aSAnna Dabrowska 14137d2401aSAnna Dabrowska /** 14237d2401aSAnna Dabrowska * When singleservice is wanted, do not show login, but execute login right away 14337d2401aSAnna Dabrowska * 14437d2401aSAnna Dabrowska * @param Doku_Event $event 14537d2401aSAnna Dabrowska * @return bool 14637d2401aSAnna Dabrowska */ 14737d2401aSAnna Dabrowska public function handleDoLogin(Doku_Event $event) 14837d2401aSAnna Dabrowska { 14937d2401aSAnna Dabrowska global $ID; 15037d2401aSAnna Dabrowska 15137d2401aSAnna Dabrowska if ($event->data != 'login') return true; 15237d2401aSAnna Dabrowska 15337d2401aSAnna Dabrowska $singleService = $this->getConf('singleService'); 15437d2401aSAnna Dabrowska if (!$singleService) return true; 15537d2401aSAnna Dabrowska 15637d2401aSAnna Dabrowska $enabledServices = $this->hlp->listServices(); 15737d2401aSAnna Dabrowska if (count($enabledServices) !== 1) { 15837d2401aSAnna Dabrowska msg($this->getLang('wrongConfig'), -1); 15937d2401aSAnna Dabrowska return false; 16037d2401aSAnna Dabrowska } 16137d2401aSAnna Dabrowska 16237d2401aSAnna Dabrowska $service = array_shift($enabledServices); 16337d2401aSAnna Dabrowska 16437d2401aSAnna Dabrowska $url = wl($ID, ['oauthlogin' => $service->getServiceID()], true, '&'); 16537d2401aSAnna Dabrowska send_redirect($url); 16637d2401aSAnna Dabrowska return true; // never reached 16737d2401aSAnna Dabrowska } 16837d2401aSAnna Dabrowska 16937d2401aSAnna Dabrowska /** 17037d2401aSAnna Dabrowska * start the oauth login 17137d2401aSAnna Dabrowska * 17237d2401aSAnna Dabrowska * This will redirect to the external service and stop processing in this request. 17337d2401aSAnna Dabrowska * The second part of the login will happen in auth 17437d2401aSAnna Dabrowska * 17537d2401aSAnna Dabrowska * @see auth_plugin_oauth 17637d2401aSAnna Dabrowska */ 17737d2401aSAnna Dabrowska protected function startOAuthLogin($servicename) 17837d2401aSAnna Dabrowska { 17937d2401aSAnna Dabrowska global $ID; 180*74b4d4a4SAndreas Gohr// $service = $this->hlp->loadService($servicename); 181*74b4d4a4SAndreas Gohr// if (is_null($service)) return; 182*74b4d4a4SAndreas Gohr// 183*74b4d4a4SAndreas Gohr// // remember service in session 184*74b4d4a4SAndreas Gohr// $sessionManager = SessionManager::getInstance(); 185*74b4d4a4SAndreas Gohr// $sessionManager->setServiceName($servicename); 186*74b4d4a4SAndreas Gohr// $sessionManager->setPid($ID); 187*74b4d4a4SAndreas Gohr// $sessionManager->saveState(); 18837d2401aSAnna Dabrowska 18937d2401aSAnna Dabrowska try { 190*74b4d4a4SAndreas Gohr $om = new \dokuwiki\plugin\oauth\OAuthManager(); 191*74b4d4a4SAndreas Gohr $om->startFlow($servicename); 192*74b4d4a4SAndreas Gohr } catch (TokenResponseException|Exception $e) { 19337d2401aSAnna Dabrowska $this->hlp->showException($e, 'login failed'); 19437d2401aSAnna Dabrowska } 19537d2401aSAnna Dabrowska } 19637d2401aSAnna Dabrowska 19737d2401aSAnna Dabrowska /** 19837d2401aSAnna Dabrowska * Restore the request environment that had been set before the oauth shuffle 199*74b4d4a4SAndreas Gohr * @todo this should be handled by the session manager, if we really need it 20037d2401aSAnna Dabrowska */ 20137d2401aSAnna Dabrowska protected function restoreSessionEnvironment() 20237d2401aSAnna Dabrowska { 20337d2401aSAnna Dabrowska global $INPUT, $ACT, $TEXT, $PRE, $SUF, $SUM, $RANGE, $DATE_AT, $REV; 204d9be1cb5SAnna Dabrowska 205d9be1cb5SAnna Dabrowska $sessionManager = SessionManager::getInstance(); 206d9be1cb5SAnna Dabrowska $ACT = $sessionManager->getDo(); 207d9be1cb5SAnna Dabrowska $_REQUEST = $sessionManager->getRequest(); 20837d2401aSAnna Dabrowska 20937d2401aSAnna Dabrowska $REV = $INPUT->int('rev'); 21037d2401aSAnna Dabrowska $DATE_AT = $INPUT->str('at'); 21137d2401aSAnna Dabrowska $RANGE = $INPUT->str('range'); 21237d2401aSAnna Dabrowska if ($INPUT->post->has('wikitext')) { 21337d2401aSAnna Dabrowska $TEXT = cleanText($INPUT->post->str('wikitext')); 21437d2401aSAnna Dabrowska } 21537d2401aSAnna Dabrowska $PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1)); 21637d2401aSAnna Dabrowska $SUF = cleanText($INPUT->post->str('suffix')); 21737d2401aSAnna Dabrowska $SUM = $INPUT->post->str('summary'); 21837d2401aSAnna Dabrowska 219d9be1cb5SAnna Dabrowska $sessionManager->setDo(''); 220d9be1cb5SAnna Dabrowska $sessionManager->setRequest([]); 221d9be1cb5SAnna Dabrowska $sessionManager->saveState(); 22237d2401aSAnna Dabrowska } 22337d2401aSAnna Dabrowska} 224