1<?php
2
3namespace dokuwiki\plugin\oauthazure;
4
5use dokuwiki\HTTP\DokuHTTPClient;
6use dokuwiki\plugin\oauth\Service\AbstractOAuth2Base;
7use OAuth\Common\Http\Uri\Uri;
8
9/**
10 * Custom Service for Azure oAuth
11 */
12class Azure extends AbstractOAuth2Base
13{
14    /**
15     * Defined scopes are listed here:
16     * @link https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent
17     */
18    const SCOPE_OPENID = 'openid';
19    const SCOPE_EMAIL = 'email';
20    const SCOPE_PROFILE = 'profile';
21    const SCOPE_OFFLINE = 'offline_access';
22    const SCOPE_USERREAD = 'https://graph.microsoft.com/user.read';
23    const SCOPE_GROUPMEMBER = 'https://graph.microsoft.com/GroupMember.Read.All';
24
25    /**
26     * Endpoints are listed here:
27     * @link https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata
28     */
29    const ENDPOINT_AUTH = 'authorization_endpoint';
30    const ENDPOINT_TOKEN = 'token_endpoint';
31    const ENDPOINT_USERINFO = 'userinfo_endpoint';
32    const ENDPOINT_LOGOUT = 'end_session_endpoint';
33
34    // graph API endpoint to read group memberships
35    const GRAPH_MEMBEROF = 'https://graph.microsoft.com/v1.0/me/memberof';
36
37    /** @var string[] discovery URL cache */
38    protected $discovery;
39
40    /**
41     * Return URI of discovered endpoint
42     *
43     * @return string
44     */
45    public function getEndpoint(string $endpoint)
46    {
47        if (!isset($this->discovery)) {
48            $plugin = plugin_load('action', 'oauthazure');
49            $discover = 'https://login.microsoftonline.com/%s/v2.0/.well-known/openid-configuration';
50            $discover = sprintf($discover, $plugin->getConf('tenant'));
51
52            $http = new DokuHTTPClient();
53            $json = $http->get($discover);
54            if (!$json) return '';
55            $this->discovery = json_decode($json, true);
56        }
57        if (!isset($this->discovery[$endpoint])) return '';
58        return $this->discovery[$endpoint];
59    }
60
61    /** @inheritdoc */
62    public function getAuthorizationEndpoint()
63    {
64        return new Uri($this->getEndpoint(self::ENDPOINT_AUTH));
65    }
66
67    /** @inheritdoc */
68    public function getAccessTokenEndpoint()
69    {
70        $uri = new Uri($this->getEndpoint(self::ENDPOINT_TOKEN));
71        //$uri->addToQuery('requested_token_use', 'on_behalf_of');
72        return $uri;
73    }
74
75    /** @inheritdoc */
76    protected function getAuthorizationMethod()
77    {
78        return static::AUTHORIZATION_METHOD_HEADER_BEARER;
79    }
80
81    /**
82     * Logout from Azure
83     *
84     * @return void
85     * @throws \OAuth\Common\Exception\Exception
86     */
87    public function logout()
88    {
89        send_redirect($this->getEndpoint(self::ENDPOINT_LOGOUT));
90    }
91}
92