1<?php
2
3// phpcs:disable PSR1.Files.SideEffects.FoundWithSymbols
4
5/**
6 * DokuWiki Plugin oauth (Helper Component)
7 *
8 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
9 * @author  Andreas Gohr <andi@splitbrain.org>
10 */
11
12use dokuwiki\Extension\Plugin;
13use dokuwiki\Extension\Event;
14use dokuwiki\plugin\oauth\Adapter;
15
16require_once(__DIR__ . '/vendor/autoload.php'); // @todo can be removed with next dw release
17
18/**
19 * Basic helper methods for the oauth flow
20 */
21class helper_plugin_oauth extends Plugin
22{
23    /**
24     * Load the needed libraries and initialize the named oAuth service
25     *
26     * @param string $servicename
27     * @return null|Adapter
28     */
29    public function loadService($servicename)
30    {
31        $services = $this->listServices(true);
32        if (!isset($services[$servicename])) return null;
33        return $services[$servicename];
34    }
35
36    /**
37     * The redirect URI used in all oAuth requests
38     *
39     * @return string
40     */
41    public function redirectURI()
42    {
43        if ($this->getConf('custom-redirectURI') !== '') {
44            return $this->getConf('custom-redirectURI');
45        } else {
46            return DOKU_URL . DOKU_SCRIPT;
47        }
48    }
49
50    /**
51     * List available Services
52     *
53     * Services returned here, do not have initialized oAuth providers yet!
54     *
55     * @param bool $enabledonly list only services that have been configured
56     * @triggers PLUGIN_OAUTH_BACKEND_REGISTER
57     * @return Adapter[] list of service objects
58     */
59    public function listServices($enabledonly = true)
60    {
61        $services = [];
62        $event = new Event('PLUGIN_OAUTH_BACKEND_REGISTER', $services);
63        $event->advise_before(false);
64        $event->advise_after();
65
66        // filter out unconfigured services
67        if ($enabledonly) {
68            $services = array_filter($services, static fn($service) =>
69                /** @var Adapter $service */
70                (bool)$service->getKey());
71        }
72
73        return $services;
74    }
75
76    /**
77     * @return array
78     */
79    public function getValidDomains()
80    {
81        if ($this->getConf('mailRestriction') === '') {
82            return [];
83        }
84        $validDomains = explode(',', trim($this->getConf('mailRestriction'), ','));
85        return array_map('trim', $validDomains);
86    }
87
88    /**
89     * @param string $mail
90     *
91     * @return bool
92     */
93    public function checkMail($mail)
94    {
95        $validDomains = $this->getValidDomains();
96        if (empty($validDomains)) return true;
97
98        foreach ($validDomains as $validDomain) {
99            if (str_ends_with($mail, $validDomain)) {
100                return true;
101            }
102        }
103        return false;
104    }
105
106    /**
107     * Display an exception to the user
108     *
109     * @param Exception $e
110     * @param string $friendly - user friendly explanation if available
111     */
112    public function showException(Exception $e, $friendly = '')
113    {
114        global $conf;
115
116        $msg = $e->getMessage();
117
118        // translate the message if possible, using context if available
119        $trans = $this->getLang($msg);
120        if ($trans) {
121            if ($e instanceof \dokuwiki\plugin\oauth\Exception) {
122                $context = $e->getContext();
123                $trans = sprintf($trans, ...$context);
124            }
125            $msg = $trans;
126        }
127
128        msg('OAuth: ' . $friendly . ' ' . hsc($msg), -1);
129        if ($conf['allowdebug']) {
130            $msg = get_class($e) . ' at ' . $e->getFile() . ':' . $e->getLine() . '<br>';
131            $msg .= hsc($e->getTraceAsString());
132            msg("<pre>$msg</pre>", -1);
133        }
134    }
135}
136