xref: /plugin/oauthgeneric/action.php (revision ad7ba96d107a088eb9cfedef27a11192c4c72648)
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