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