1<?php
2
3use dokuwiki\plugin\oauth\Adapter;
4use dokuwiki\plugin\oauthazure\Azure;
5
6/**
7 * Service Implementation for Azure authentication
8 */
9class action_plugin_oauthazure extends Adapter
10{
11    /** @inheritdoc */
12    public function registerServiceClass()
13    {
14        return Azure::class;
15    }
16
17    /**
18     * @inheritdoc
19     * @throws \OAuth\Common\Exception\Exception
20     */
21    public function logout()
22    {
23        /** @var Azure */
24        $oauth = $this->getOAuthService();
25        $oauth->logout();
26    }
27
28    /** * @inheritDoc */
29    public function getUser()
30    {
31        /** @var Azure */
32        $oauth = $this->getOAuthService();
33
34        $tokenExtras = $oauth->getStorage()->retrieveAccessToken($oauth->service())->getExtraParams();
35        $idToken = $tokenExtras['id_token'] ?? '';
36
37        $decodedObj = json_decode(base64_decode(str_replace('_', '/',
38            str_replace('-', '+', explode('.', $idToken)[1]))));
39        $result = (array)$decodedObj;
40        if (!$result) throw new OAuthException('Failed to parse data from userinfo from JWT');
41
42        $data = [];
43        $data['user'] = $result['preferred_username'];
44        $data['name'] = $result['name'];
45        $data['mail'] = $result['email'];
46        $data['grps'] = array_merge($result['groups'] ?? [], $result['roles'] ?? []);
47
48        if ($this->getConf('stripdomain')) {
49            $data['user'] = explode('@', $data['user'], 2)[0];
50        }
51
52        if ($this->getConf('fetchgroups')) {
53            $usergroups = $oauth->request(Azure::GRAPH_MEMBEROF);
54            $usergroups = json_decode($usergroups, true);
55            if (!$usergroups) throw new OAuthException('Failed to parse group data');
56
57            if (isset($usergroups['value'])) {
58                $data['grps'] = array_map(function ($item) {
59                    return $item['displayName'] ?? $item['id'];
60                }, $usergroups['value']);
61            }
62        }
63
64        return $data;
65    }
66
67    /** @inheritdoc */
68    public function getScopes()
69    {
70        $scopes = [
71            Azure::SCOPE_OPENID,
72            Azure::SCOPE_EMAIL,
73            Azure::SCOPE_PROFILE,
74            Azure::SCOPE_OFFLINE,
75        ];
76
77        // use additional scopes to read group membership
78        if ($this->getConf('fetchgroups')) {
79            $scopes[] = Azure::SCOPE_USERREAD;
80            $scopes[] = Azure::SCOPE_GROUPMEMBER;
81        }
82
83        return $scopes;
84    }
85
86    /** @inheritDoc */
87    public function getLabel()
88    {
89        return 'Azure';
90    }
91
92    /** @inheritDoc */
93    public function getColor()
94    {
95        return '#008AD7';
96    }
97}
98