1cf22df2fSAndreas Gohr<?php 2cf22df2fSAndreas Gohr 3cf22df2fSAndreas Gohruse dokuwiki\plugin\oauth\Adapter; 4cf22df2fSAndreas Gohruse dokuwiki\plugin\oauthgeneric\DotAccess; 5cf22df2fSAndreas Gohruse dokuwiki\plugin\oauthgeneric\Generic; 6cf22df2fSAndreas Gohr 7cf22df2fSAndreas Gohr/** 8cf22df2fSAndreas Gohr * Service Implementation for oAuth Doorkeeper authentication 9cf22df2fSAndreas Gohr */ 10cf22df2fSAndreas Gohrclass action_plugin_oauthgeneric extends Adapter 11cf22df2fSAndreas Gohr{ 12cf22df2fSAndreas Gohr 13cf22df2fSAndreas Gohr /** @inheritdoc */ 14cf22df2fSAndreas Gohr public function registerServiceClass() 15cf22df2fSAndreas Gohr { 16cf22df2fSAndreas Gohr return Generic::class; 17cf22df2fSAndreas Gohr } 18cf22df2fSAndreas Gohr 19cf22df2fSAndreas Gohr /** * @inheritDoc */ 20cf22df2fSAndreas Gohr public function getUser() 21cf22df2fSAndreas Gohr { 22cf22df2fSAndreas Gohr $oauth = $this->getOAuthService(); 23cf22df2fSAndreas Gohr $data = array(); 24cf22df2fSAndreas Gohr 25cf22df2fSAndreas Gohr $url = $this->getConf('userurl'); 26cf22df2fSAndreas Gohr $raw = $oauth->request($url); 27cf22df2fSAndreas Gohr 28cf22df2fSAndreas Gohr if (!$raw) throw new OAuthException('Failed to fetch data from userurl'); 29cf22df2fSAndreas Gohr $result = json_decode($raw, true); 30cf22df2fSAndreas Gohr if (!$result) throw new OAuthException('Failed to parse data from userurl'); 31cf22df2fSAndreas Gohr 32420dfed2SAndreas Gohr $grpdots = sexplode('[]', $this->getConf('json-grps'), 2); 33cf22df2fSAndreas Gohr $user = DotAccess::get($result, $this->getConf('json-user'), ''); 34cf22df2fSAndreas Gohr $name = DotAccess::get($result, $this->getConf('json-name'), ''); 35cf22df2fSAndreas Gohr $mail = DotAccess::get($result, $this->getConf('json-mail'), ''); 36420dfed2SAndreas Gohr $grps = DotAccess::get($result, $grpdots[0], []); 37420dfed2SAndreas Gohr 38420dfed2SAndreas Gohr // use dot notation on each group 39420dfed2SAndreas Gohr if (is_array($grps) && $grpdots[1]) { 40420dfed2SAndreas Gohr $grps = array_map(function ($grp) use ($grpdots) { 41420dfed2SAndreas Gohr return DotAccess::get($grp, $grpdots[1], ''); 42420dfed2SAndreas Gohr }, $grps); 43420dfed2SAndreas Gohr } 44cf22df2fSAndreas Gohr 45cf22df2fSAndreas Gohr // type fixes 46cf22df2fSAndreas Gohr if (is_array($user)) $user = array_shift($user); 477c8a6248SMoon Sungjoon if (is_array($name)) $name = array_shift($name); 487c8a6248SMoon Sungjoon if (is_array($mail)) $mail = array_shift($mail); 49cf22df2fSAndreas Gohr if (!is_array($grps)) { 50cf22df2fSAndreas Gohr $grps = explode(',', $grps); 51cf22df2fSAndreas Gohr $grps = array_map('trim', $grps); 52cf22df2fSAndreas Gohr } 53cf22df2fSAndreas Gohr 54cf22df2fSAndreas Gohr // fallbacks for user name 55cf22df2fSAndreas Gohr if (empty($user)) { 56cf22df2fSAndreas Gohr if (!empty($name)) { 57cf22df2fSAndreas Gohr $user = $name; 58cf22df2fSAndreas Gohr } elseif (!empty($mail)) { 59cf22df2fSAndreas Gohr list($user) = explode('@', $mail); 60cf22df2fSAndreas Gohr } 61cf22df2fSAndreas Gohr } 62cf22df2fSAndreas Gohr 63cf22df2fSAndreas Gohr // fallback for full name 64cf22df2fSAndreas Gohr if (empty($name)) { 65cf22df2fSAndreas Gohr $name = $user; 66cf22df2fSAndreas Gohr } 67cf22df2fSAndreas Gohr 68cf22df2fSAndreas Gohr return compact('user', 'name', 'mail', 'grps'); 69cf22df2fSAndreas Gohr } 70*ad7ba96dSAndreas Gohr 71*ad7ba96dSAndreas Gohr /** @inheritdoc */ 72*ad7ba96dSAndreas Gohr public function logout() 73*ad7ba96dSAndreas Gohr { 74*ad7ba96dSAndreas Gohr $url = $this->getConf('logouturl'); 75*ad7ba96dSAndreas Gohr if (!$url) { 76*ad7ba96dSAndreas Gohr parent::logout(); 77*ad7ba96dSAndreas Gohr return; 78*ad7ba96dSAndreas Gohr } 79*ad7ba96dSAndreas Gohr 80*ad7ba96dSAndreas Gohr // add ID token if available 81*ad7ba96dSAndreas Gohr $oauth = $this->getOAuthService(); 82*ad7ba96dSAndreas Gohr $token = $oauth->getStorage()->retrieveAccessToken($oauth->service()); 83*ad7ba96dSAndreas Gohr $params = $token->getExtraParams(); 84*ad7ba96dSAndreas Gohr if (isset($params['id_token'])) { 85*ad7ba96dSAndreas Gohr $url .= (strpos($url, '?') === false ? '?' : '&') . 'id_token_hint=' . urlencode($params['id_token']); 86*ad7ba96dSAndreas Gohr } 87*ad7ba96dSAndreas Gohr 88*ad7ba96dSAndreas Gohr // redirect back to dokuwiki after logout 89*ad7ba96dSAndreas Gohr /** @var helper_plugin_oauth $helper */ 90*ad7ba96dSAndreas Gohr $helper = plugin_load('helper', 'oauth'); 91*ad7ba96dSAndreas Gohr $redir = $helper->redirectURI(); 92*ad7ba96dSAndreas Gohr $url .= (strpos($url, '?') === false ? '?' : '&') . 'post_logout_redirect_uri=' . urlencode($redir); 93*ad7ba96dSAndreas Gohr 94*ad7ba96dSAndreas Gohr // add state if needed (we don't check it, but some providers require it) 95*ad7ba96dSAndreas Gohr if ($this->getConf('needs-state')) { 96*ad7ba96dSAndreas Gohr $state = bin2hex(random_bytes(16)); 97*ad7ba96dSAndreas Gohr $url .= (strpos($url, '?') === false ? '?' : '&') . 'state=' . urlencode($state); 98*ad7ba96dSAndreas Gohr } 99*ad7ba96dSAndreas Gohr 100*ad7ba96dSAndreas Gohr parent::logout(); 101*ad7ba96dSAndreas Gohr send_redirect($url); 102*ad7ba96dSAndreas Gohr exit; 103*ad7ba96dSAndreas Gohr } 104*ad7ba96dSAndreas Gohr 105cf22df2fSAndreas Gohr 106cf22df2fSAndreas Gohr /** @inheritdoc */ 107cf22df2fSAndreas Gohr public function getScopes() 108cf22df2fSAndreas Gohr { 109cf22df2fSAndreas Gohr return $this->getConf('scopes'); 110cf22df2fSAndreas Gohr } 111cf22df2fSAndreas Gohr 112cf22df2fSAndreas Gohr /** @inheritDoc */ 113cf22df2fSAndreas Gohr public function getLabel() 114cf22df2fSAndreas Gohr { 115cf22df2fSAndreas Gohr return $this->getConf('label'); 116cf22df2fSAndreas Gohr } 117cf22df2fSAndreas Gohr 118cf22df2fSAndreas Gohr /** @inheritDoc */ 119cf22df2fSAndreas Gohr public function getColor() 120cf22df2fSAndreas Gohr { 121cf22df2fSAndreas Gohr return $this->getConf('color'); 122cf22df2fSAndreas Gohr } 123cf22df2fSAndreas Gohr} 124