1*37d2401aSAnna Dabrowska<?php 2*37d2401aSAnna Dabrowska 3*37d2401aSAnna Dabrowskause OAuth\Common\Http\Exception\TokenResponseException; 4*37d2401aSAnna Dabrowska 5*37d2401aSAnna Dabrowska/** 6*37d2401aSAnna Dabrowska * DokuWiki Plugin oauth (Action Component) 7*37d2401aSAnna Dabrowska * 8*37d2401aSAnna Dabrowska * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 9*37d2401aSAnna Dabrowska * @author Andreas Gohr <andi@splitbrain.org> 10*37d2401aSAnna Dabrowska */ 11*37d2401aSAnna Dabrowskaclass action_plugin_oauth_login extends DokuWiki_Action_Plugin 12*37d2401aSAnna Dabrowska{ 13*37d2401aSAnna Dabrowska /** @var helper_plugin_oauth */ 14*37d2401aSAnna Dabrowska protected $hlp; 15*37d2401aSAnna Dabrowska 16*37d2401aSAnna Dabrowska /** 17*37d2401aSAnna Dabrowska * Constructor 18*37d2401aSAnna Dabrowska * 19*37d2401aSAnna Dabrowska * Initializes the helper 20*37d2401aSAnna Dabrowska */ 21*37d2401aSAnna Dabrowska public function __construct() 22*37d2401aSAnna Dabrowska { 23*37d2401aSAnna Dabrowska $this->hlp = plugin_load('helper', 'oauth'); 24*37d2401aSAnna Dabrowska } 25*37d2401aSAnna Dabrowska 26*37d2401aSAnna Dabrowska /** 27*37d2401aSAnna Dabrowska * Registers a callback function for a given event 28*37d2401aSAnna Dabrowska * 29*37d2401aSAnna Dabrowska * @param Doku_Event_Handler $controller DokuWiki's event controller object 30*37d2401aSAnna Dabrowska * @return void 31*37d2401aSAnna Dabrowska */ 32*37d2401aSAnna Dabrowska public function register(Doku_Event_Handler $controller) 33*37d2401aSAnna Dabrowska { 34*37d2401aSAnna Dabrowska global $conf; 35*37d2401aSAnna Dabrowska if ($conf['authtype'] != 'oauth') return; 36*37d2401aSAnna Dabrowska 37*37d2401aSAnna Dabrowska $conf['profileconfirm'] = false; // password confirmation doesn't work with oauth only users 38*37d2401aSAnna Dabrowska 39*37d2401aSAnna Dabrowska $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'handleStart'); 40*37d2401aSAnna Dabrowska $controller->register_hook('HTML_LOGINFORM_OUTPUT', 'BEFORE', $this, 'handleLoginform'); 41*37d2401aSAnna Dabrowska $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleDoLogin'); 42*37d2401aSAnna Dabrowska } 43*37d2401aSAnna Dabrowska 44*37d2401aSAnna Dabrowska /** 45*37d2401aSAnna Dabrowska * Start an oAuth login or restore environment after successful login 46*37d2401aSAnna Dabrowska * 47*37d2401aSAnna Dabrowska * @param Doku_Event $event 48*37d2401aSAnna Dabrowska * @return void 49*37d2401aSAnna Dabrowska */ 50*37d2401aSAnna Dabrowska public function handleStart(Doku_Event $event) 51*37d2401aSAnna Dabrowska { 52*37d2401aSAnna Dabrowska global $INPUT; 53*37d2401aSAnna Dabrowska 54*37d2401aSAnna Dabrowska // login has been done, but there's environment to be restored 55*37d2401aSAnna Dabrowska if (isset($_SESSION[DOKU_COOKIE]['oauth-done']['do']) || !empty($_SESSION[DOKU_COOKIE]['oauth-done']['rev'])) { 56*37d2401aSAnna Dabrowska $this->restoreSessionEnvironment(); 57*37d2401aSAnna Dabrowska return; 58*37d2401aSAnna Dabrowska } 59*37d2401aSAnna Dabrowska 60*37d2401aSAnna Dabrowska // see if a login needs to be started 61*37d2401aSAnna Dabrowska $servicename = $INPUT->str('oauthlogin'); 62*37d2401aSAnna Dabrowska if ($servicename) $this->startOAuthLogin($servicename); 63*37d2401aSAnna Dabrowska } 64*37d2401aSAnna Dabrowska 65*37d2401aSAnna Dabrowska /** 66*37d2401aSAnna Dabrowska * Add the oAuth login links 67*37d2401aSAnna Dabrowska * 68*37d2401aSAnna Dabrowska * @param Doku_Event $event event object by reference 69*37d2401aSAnna Dabrowska * @return void 70*37d2401aSAnna Dabrowska */ 71*37d2401aSAnna Dabrowska public function handleLoginform(Doku_Event $event) 72*37d2401aSAnna Dabrowska { 73*37d2401aSAnna Dabrowska /** @var Doku_Form $form */ 74*37d2401aSAnna Dabrowska $form = $event->data; 75*37d2401aSAnna Dabrowska $html = ''; 76*37d2401aSAnna Dabrowska 77*37d2401aSAnna Dabrowska $validDomains = $this->hlp->getValidDomains(); 78*37d2401aSAnna Dabrowska 79*37d2401aSAnna Dabrowska if (count($validDomains) > 0) { 80*37d2401aSAnna Dabrowska $html .= sprintf($this->getLang('eMailRestricted'), join(', ', $validDomains)); 81*37d2401aSAnna Dabrowska } 82*37d2401aSAnna Dabrowska 83*37d2401aSAnna Dabrowska foreach ($this->hlp->listServices() as $service) { 84*37d2401aSAnna Dabrowska $html .= $service->loginButton(); 85*37d2401aSAnna Dabrowska } 86*37d2401aSAnna Dabrowska if (!$html) return; 87*37d2401aSAnna Dabrowska 88*37d2401aSAnna Dabrowska $form->_content[] = form_openfieldset( 89*37d2401aSAnna Dabrowska [ 90*37d2401aSAnna Dabrowska '_legend' => $this->getLang('loginwith'), 91*37d2401aSAnna Dabrowska 'class' => 'plugin_oauth', 92*37d2401aSAnna Dabrowska ] 93*37d2401aSAnna Dabrowska ); 94*37d2401aSAnna Dabrowska $form->_content[] = $html; 95*37d2401aSAnna Dabrowska $form->_content[] = form_closefieldset(); 96*37d2401aSAnna Dabrowska } 97*37d2401aSAnna Dabrowska 98*37d2401aSAnna Dabrowska /** 99*37d2401aSAnna Dabrowska * When singleservice is wanted, do not show login, but execute login right away 100*37d2401aSAnna Dabrowska * 101*37d2401aSAnna Dabrowska * @param Doku_Event $event 102*37d2401aSAnna Dabrowska * @return bool 103*37d2401aSAnna Dabrowska */ 104*37d2401aSAnna Dabrowska public function handleDoLogin(Doku_Event $event) 105*37d2401aSAnna Dabrowska { 106*37d2401aSAnna Dabrowska global $ID; 107*37d2401aSAnna Dabrowska 108*37d2401aSAnna Dabrowska if ($event->data != 'login') return true; 109*37d2401aSAnna Dabrowska 110*37d2401aSAnna Dabrowska $singleService = $this->getConf('singleService'); 111*37d2401aSAnna Dabrowska if (!$singleService) return true; 112*37d2401aSAnna Dabrowska 113*37d2401aSAnna Dabrowska $enabledServices = $this->hlp->listServices(); 114*37d2401aSAnna Dabrowska if (count($enabledServices) !== 1) { 115*37d2401aSAnna Dabrowska msg($this->getLang('wrongConfig'), -1); 116*37d2401aSAnna Dabrowska return false; 117*37d2401aSAnna Dabrowska } 118*37d2401aSAnna Dabrowska 119*37d2401aSAnna Dabrowska $service = array_shift($enabledServices); 120*37d2401aSAnna Dabrowska 121*37d2401aSAnna Dabrowska $url = wl($ID, ['oauthlogin' => $service->getServiceID()], true, '&'); 122*37d2401aSAnna Dabrowska send_redirect($url); 123*37d2401aSAnna Dabrowska return true; // never reached 124*37d2401aSAnna Dabrowska } 125*37d2401aSAnna Dabrowska 126*37d2401aSAnna Dabrowska /** 127*37d2401aSAnna Dabrowska * start the oauth login 128*37d2401aSAnna Dabrowska * 129*37d2401aSAnna Dabrowska * This will redirect to the external service and stop processing in this request. 130*37d2401aSAnna Dabrowska * The second part of the login will happen in auth 131*37d2401aSAnna Dabrowska * 132*37d2401aSAnna Dabrowska * @see auth_plugin_oauth 133*37d2401aSAnna Dabrowska */ 134*37d2401aSAnna Dabrowska protected function startOAuthLogin($servicename) 135*37d2401aSAnna Dabrowska { 136*37d2401aSAnna Dabrowska global $ID; 137*37d2401aSAnna Dabrowska $service = $this->hlp->loadService($servicename); 138*37d2401aSAnna Dabrowska if (is_null($service)) return; 139*37d2401aSAnna Dabrowska 140*37d2401aSAnna Dabrowska // remember service in session 141*37d2401aSAnna Dabrowska session_start(); 142*37d2401aSAnna Dabrowska $_SESSION[DOKU_COOKIE]['oauth-inprogress']['service'] = $servicename; 143*37d2401aSAnna Dabrowska $_SESSION[DOKU_COOKIE]['oauth-inprogress']['id'] = $ID; 144*37d2401aSAnna Dabrowska session_write_close(); 145*37d2401aSAnna Dabrowska 146*37d2401aSAnna Dabrowska try { 147*37d2401aSAnna Dabrowska $service->login(); // redirects 148*37d2401aSAnna Dabrowska } catch (TokenResponseException $e) { 149*37d2401aSAnna Dabrowska $this->hlp->showException($e, 'login failed'); 150*37d2401aSAnna Dabrowska } 151*37d2401aSAnna Dabrowska } 152*37d2401aSAnna Dabrowska 153*37d2401aSAnna Dabrowska /** 154*37d2401aSAnna Dabrowska * Restore the request environment that had been set before the oauth shuffle 155*37d2401aSAnna Dabrowska */ 156*37d2401aSAnna Dabrowska protected function restoreSessionEnvironment() 157*37d2401aSAnna Dabrowska { 158*37d2401aSAnna Dabrowska global $INPUT, $ACT, $TEXT, $PRE, $SUF, $SUM, $RANGE, $DATE_AT, $REV; 159*37d2401aSAnna Dabrowska $ACT = $_SESSION[DOKU_COOKIE]['oauth-done']['do']; 160*37d2401aSAnna Dabrowska $_REQUEST = $_SESSION[DOKU_COOKIE]['oauth-done']['$_REQUEST']; 161*37d2401aSAnna Dabrowska 162*37d2401aSAnna Dabrowska $REV = $INPUT->int('rev'); 163*37d2401aSAnna Dabrowska $DATE_AT = $INPUT->str('at'); 164*37d2401aSAnna Dabrowska $RANGE = $INPUT->str('range'); 165*37d2401aSAnna Dabrowska if ($INPUT->post->has('wikitext')) { 166*37d2401aSAnna Dabrowska $TEXT = cleanText($INPUT->post->str('wikitext')); 167*37d2401aSAnna Dabrowska } 168*37d2401aSAnna Dabrowska $PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1)); 169*37d2401aSAnna Dabrowska $SUF = cleanText($INPUT->post->str('suffix')); 170*37d2401aSAnna Dabrowska $SUM = $INPUT->post->str('summary'); 171*37d2401aSAnna Dabrowska 172*37d2401aSAnna Dabrowska unset($_SESSION[DOKU_COOKIE]['oauth-done']); 173*37d2401aSAnna Dabrowska } 174*37d2401aSAnna Dabrowska} 175