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