180852c15SAndreas Gohr<?php 23e7ac5b1SAndreas Gohr 3e170f465SAndreas Gohruse dokuwiki\plugin\oauth\OAuthManager; 4e170f465SAndreas Gohruse dokuwiki\plugin\oauth\Session; 5e170f465SAndreas Gohruse dokuwiki\Subscriptions\RegistrationSubscriptionSender; 6e170f465SAndreas Gohruse OAuth\Common\Exception\Exception as OAuthException; 7e170f465SAndreas Gohr 880852c15SAndreas Gohr/** 980852c15SAndreas Gohr * DokuWiki Plugin oauth (Auth Component) 1080852c15SAndreas Gohr * 1180852c15SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 1280852c15SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1380852c15SAndreas Gohr */ 143e7ac5b1SAndreas Gohrclass auth_plugin_oauth extends auth_plugin_authplain 153e7ac5b1SAndreas Gohr{ 16e170f465SAndreas Gohr /** @var helper_plugin_oauth */ 17e170f465SAndreas Gohr protected $hlp; 18e170f465SAndreas Gohr 19e170f465SAndreas Gohr // region standard auth methods 2080852c15SAndreas Gohr 213e7ac5b1SAndreas Gohr /** @inheritDoc */ 223e7ac5b1SAndreas Gohr public function __construct() 233e7ac5b1SAndreas Gohr { 24f10e09e2SAndreas Gohr parent::__construct(); 25f10e09e2SAndreas Gohr $this->cando['external'] = true; 26e170f465SAndreas Gohr $this->hlp = $this->loadHelper('oauth'); 2780852c15SAndreas Gohr } 2880852c15SAndreas Gohr 293e7ac5b1SAndreas Gohr /** @inheritDoc */ 30311a6606SAnna Dabrowska public function trustExternal($user, $pass, $sticky = false) 313e7ac5b1SAndreas Gohr { 32a02a5d81SAnna Dabrowska global $INPUT; 33438dcc52SMichael Grosse 34*8523e9d0SAndreas Gohr // handle redirects from farmer to animal wiki instances 35*8523e9d0SAndreas Gohr if ($INPUT->has('state') && plugin_load('helper', 'farmer')) { 36d9be1cb5SAnna Dabrowska $this->handleFarmState($INPUT->str('state')); 37438dcc52SMichael Grosse } 3880852c15SAndreas Gohr 3974b4d4a4SAndreas Gohr try { 4074b4d4a4SAndreas Gohr // either oauth or "normal" plain auth login via form 41e170f465SAndreas Gohr $om = new OAuthManager(); 4274b4d4a4SAndreas Gohr return $om->continueFlow() || auth_login($user, $pass, $sticky); 43e170f465SAndreas Gohr } catch (OAuthException $e) { 44e170f465SAndreas Gohr $this->hlp->showException($e); 4574b4d4a4SAndreas Gohr return false; 46a7a8f46aSAndreas Gohr } 47a7a8f46aSAndreas Gohr } 4880852c15SAndreas Gohr 49f2e164b0SMichael Große /** 50311a6606SAnna Dabrowska * Enhance function to check against duplicate emails 51311a6606SAnna Dabrowska * 52e170f465SAndreas Gohr * @inheritdoc 53311a6606SAnna Dabrowska */ 54311a6606SAnna Dabrowska public function createUser($user, $pwd, $name, $mail, $grps = null) 55311a6606SAnna Dabrowska { 56311a6606SAnna Dabrowska if ($this->getUserByEmail($mail)) { 57311a6606SAnna Dabrowska msg($this->getLang('emailduplicate'), -1); 58311a6606SAnna Dabrowska return false; 59311a6606SAnna Dabrowska } 60311a6606SAnna Dabrowska 61311a6606SAnna Dabrowska return parent::createUser($user, $pwd, $name, $mail, $grps); 62311a6606SAnna Dabrowska } 63311a6606SAnna Dabrowska 64311a6606SAnna Dabrowska /** 65311a6606SAnna Dabrowska * Enhance function to check against duplicate emails 66311a6606SAnna Dabrowska * 67e170f465SAndreas Gohr * @inheritdoc 68311a6606SAnna Dabrowska */ 69311a6606SAnna Dabrowska public function modifyUser($user, $changes) 70311a6606SAnna Dabrowska { 71311a6606SAnna Dabrowska global $conf; 72311a6606SAnna Dabrowska 73311a6606SAnna Dabrowska if (isset($changes['mail'])) { 74311a6606SAnna Dabrowska $found = $this->getUserByEmail($changes['mail']); 75311a6606SAnna Dabrowska if ($found && $found != $user) { 76311a6606SAnna Dabrowska msg($this->getLang('emailduplicate'), -1); 77311a6606SAnna Dabrowska return false; 78311a6606SAnna Dabrowska } 79311a6606SAnna Dabrowska } 80311a6606SAnna Dabrowska 81311a6606SAnna Dabrowska $ok = parent::modifyUser($user, $changes); 82311a6606SAnna Dabrowska 83311a6606SAnna Dabrowska // refresh session cache 84311a6606SAnna Dabrowska touch($conf['cachedir'] . '/sessionpurge'); 85311a6606SAnna Dabrowska return $ok; 86311a6606SAnna Dabrowska } 87311a6606SAnna Dabrowska 88311a6606SAnna Dabrowska /** 89311a6606SAnna Dabrowska * Unset additional stuff in session on logout 90311a6606SAnna Dabrowska */ 91311a6606SAnna Dabrowska public function logOff() 92311a6606SAnna Dabrowska { 93311a6606SAnna Dabrowska parent::logOff(); 94e170f465SAndreas Gohr (Session::getInstance())->clear(); 95311a6606SAnna Dabrowska } 96311a6606SAnna Dabrowska 97e170f465SAndreas Gohr // endregion 98e170f465SAndreas Gohr 99311a6606SAnna Dabrowska /** 100e170f465SAndreas Gohr * Register a new user logged in by oauth 101f2e164b0SMichael Große * 102e170f465SAndreas Gohr * It ensures the username is unique, by adding a number if needed. 103e170f465SAndreas Gohr * Default and service name groups are set here. 104e170f465SAndreas Gohr * Registration notifications are triggered. 105a02a5d81SAnna Dabrowska * 106e170f465SAndreas Gohr * @param array $userinfo This will be updated with the new username 107b2b9fbc7SMichael Große * @param string $servicename 108b2b9fbc7SMichael Große * 109b2b9fbc7SMichael Große * @return bool 110e170f465SAndreas Gohr * @todo - should this be part of the OAuthManager class instead? 111b2b9fbc7SMichael Große */ 112e170f465SAndreas Gohr public function registerOAuthUser(&$userinfo, $servicename) 1133e7ac5b1SAndreas Gohr { 114b2b9fbc7SMichael Große global $conf; 115a02a5d81SAnna Dabrowska $user = $userinfo['user']; 116b2b9fbc7SMichael Große $count = ''; 117b2b9fbc7SMichael Große while ($this->getUserData($user . $count)) { 118b2b9fbc7SMichael Große if ($count) { 119b2b9fbc7SMichael Große $count++; 120b2b9fbc7SMichael Große } else { 121b2b9fbc7SMichael Große $count = 1; 122b2b9fbc7SMichael Große } 123b2b9fbc7SMichael Große } 124b2b9fbc7SMichael Große $user = $user . $count; 125a02a5d81SAnna Dabrowska $userinfo['user'] = $user; 126e170f465SAndreas Gohr $groups_on_creation = []; 127b2b9fbc7SMichael Große $groups_on_creation[] = $conf['defaultgroup']; 128b2b9fbc7SMichael Große $groups_on_creation[] = $this->cleanGroup($servicename); // add service as group 129a02a5d81SAnna Dabrowska $userinfo['grps'] = array_merge((array)$userinfo['grps'], $groups_on_creation); 130b2b9fbc7SMichael Große 131e170f465SAndreas Gohr // the password set here will remain unknown to the user 132b2b9fbc7SMichael Große $ok = $this->triggerUserMod( 133b2b9fbc7SMichael Große 'create', 134e170f465SAndreas Gohr [ 135e170f465SAndreas Gohr $user, 136e170f465SAndreas Gohr auth_pwgen($user), 137e170f465SAndreas Gohr $userinfo['name'], 138e170f465SAndreas Gohr $userinfo['mail'], 139e170f465SAndreas Gohr $groups_on_creation, 140e170f465SAndreas Gohr ] 141b2b9fbc7SMichael Große ); 142b2b9fbc7SMichael Große if (!$ok) { 143b2b9fbc7SMichael Große return false; 144b2b9fbc7SMichael Große } 145b2b9fbc7SMichael Große 146e170f465SAndreas Gohr // send notification about the new user 147e170f465SAndreas Gohr $subscriptionSender = new RegistrationSubscriptionSender(); 148e170f465SAndreas Gohr $subscriptionSender->sendRegister($user, $userinfo['name'], $userinfo['mail']); 149e170f465SAndreas Gohr 150b2b9fbc7SMichael Große return true; 151b2b9fbc7SMichael Große } 152b2b9fbc7SMichael Große 153b2b9fbc7SMichael Große /** 154a02a5d81SAnna Dabrowska * Find a user by email address 155b2b9fbc7SMichael Große * 156b2b9fbc7SMichael Große * @param $mail 157b2b9fbc7SMichael Große * @return bool|string 158b2b9fbc7SMichael Große */ 15974b4d4a4SAndreas Gohr public function getUserByEmail($mail) 1603e7ac5b1SAndreas Gohr { 1618b214edcSAndreas Gohr if ($this->users === null) { 1628b214edcSAndreas Gohr $this->loadUserData(); 1638b214edcSAndreas Gohr } 164b2b9fbc7SMichael Große $mail = strtolower($mail); 165b2b9fbc7SMichael Große 166a02a5d81SAnna Dabrowska foreach ($this->users as $user => $userinfo) { 167a02a5d81SAnna Dabrowska if (strtolower($userinfo['mail']) == $mail) return $user; 168b2b9fbc7SMichael Große } 169b2b9fbc7SMichael Große 170b2b9fbc7SMichael Große return false; 171b2b9fbc7SMichael Große } 172b2b9fbc7SMichael Große 173b2b9fbc7SMichael Große /** 174b8ca6a42SAnna Dabrowska * Farmer plugin support 175b8ca6a42SAnna Dabrowska * 176b8ca6a42SAnna Dabrowska * When coming back to farmer instance via OAUTH redirectURI, we need to redirect again 177b8ca6a42SAnna Dabrowska * to a proper animal instance detected from $state 178b2b9fbc7SMichael Große * 179311a6606SAnna Dabrowska * @param $state 180b2b9fbc7SMichael Große */ 181e170f465SAndreas Gohr protected function handleFarmState($state) 1823e7ac5b1SAndreas Gohr { 183311a6606SAnna Dabrowska /** @var \helper_plugin_farmer $farmer */ 184311a6606SAnna Dabrowska $farmer = plugin_load('helper', 'farmer', false, true); 185311a6606SAnna Dabrowska $data = json_decode(base64_decode(urldecode($state))); 186311a6606SAnna Dabrowska if (empty($data->animal) || $farmer->getAnimal() == $data->animal) { 187311a6606SAnna Dabrowska return; 188827232fcSMichael Große } 189311a6606SAnna Dabrowska $animal = $data->animal; 190311a6606SAnna Dabrowska $allAnimals = $farmer->getAllAnimals(); 191311a6606SAnna Dabrowska if (!in_array($animal, $allAnimals)) { 192311a6606SAnna Dabrowska msg('Animal ' . $animal . ' does not exist!'); 193311a6606SAnna Dabrowska return; 194827232fcSMichael Große } 195311a6606SAnna Dabrowska global $INPUT; 196311a6606SAnna Dabrowska $url = $farmer->getAnimalURL($animal) . '/doku.php?' . $INPUT->server->str('QUERY_STRING'); 197311a6606SAnna Dabrowska send_redirect($url); 198b2b9fbc7SMichael Große } 199b2b9fbc7SMichael Große} 200