1<?php
2/**
3 * DokuWiki Plugin oauth (Helper Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr <andi@splitbrain.org>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12class helper_plugin_oauth extends DokuWiki_Plugin {
13
14    /**
15     * Load the needed libraries and initialize the named oAuth service
16     *
17     * @param string $servicename
18     * @return null|\OAuth\Plugin\AbstractAdapter
19     */
20    public function loadService(&$servicename) {
21        $id = getID(); // $ID isn't set in trustExternal, yet
22
23        $servicename = preg_replace('/[^a-zA-Z0-9_]+/', '', $servicename);
24        if(!$servicename) return null;
25
26        require_once(__DIR__.'/phpoauthlib/src/OAuth/bootstrap.php');
27        require_once(__DIR__.'/classes/AbstractAdapter.php');
28        require_once(__DIR__.'/classes/oAuthHTTPClient.php');
29        require_once(__DIR__.'/classes/oAuthStorage.php');
30
31        $file = __DIR__.'/classes/'.$servicename.'Adapter.php';
32        if(!file_exists($file)) return null;
33        require_once($file);
34        $class = '\\OAuth\\Plugin\\'.$servicename.'Adapter';
35
36        /** @var \OAuth\Plugin\AbstractAdapter $service */
37        $service = new $class($this->redirectURI());
38        if(!$service->isInitialized()) {
39            msg("Failed to initialize $service authentication service. Check credentials", -1);
40            return null;
41        }
42
43        // The generic service can be externally configured
44        if(is_a($service->oAuth, 'OAuth\\OAuth2\\Service\\Generic')) {
45            $service->oAuth->setAuthorizationEndpoint($this->getAuthEndpoint($servicename));
46            $service->oAuth->setAccessTokenEndpoint($this->getTokenEndpoint($servicename));
47        }
48
49        return $service;
50    }
51
52    /**
53     * The redirect URI used in all oAuth requests
54     *
55     * @return string
56     */
57    public function redirectURI() {
58        if ($this->getConf('custom-redirectURI') !== '') {
59            return $this->getConf('custom-redirectURI');
60        } else {
61            return DOKU_URL . DOKU_SCRIPT;
62        }
63    }
64
65    /**
66     * List available Services
67     *
68     * @param bool $enabledonly list only enabled services
69     * @return array
70     */
71    public function listServices($enabledonly = true) {
72        $services = array();
73        $files    = glob(__DIR__.'/classes/*Adapter.php');
74
75        foreach($files as $file) {
76            $file = basename($file, 'Adapter.php');
77            if($file == 'Abstract') continue;
78            if($enabledonly && !$this->getKey($file)) continue;
79            $services[] = $file;
80        }
81
82        return $services;
83    }
84
85    /**
86     * Return the configured key for the given service
87     *
88     * @param $service
89     * @return string
90     */
91    public function getKey($service) {
92        $service = strtolower($service);
93        return $this->getConf($service.'-key');
94    }
95
96    /**
97     * Return the configured secret for the given service
98     *
99     * @param $service
100     * @return string
101     */
102    public function getSecret($service) {
103        $service = strtolower($service);
104        return $this->getConf($service.'-secret');
105    }
106
107    /**
108     * Return the configured Authentication Endpoint URL for the given service
109     *
110     * @param $service
111     * @return string
112     */
113    public function getAuthEndpoint($service) {
114        $service = strtolower($service);
115        return $this->getConf($service.'-authurl');
116    }
117
118    /**
119     * Return the configured Access Token Endpoint URL for the given service
120     *
121     * @param $service
122     * @return string
123     */
124    public function getTokenEndpoint($service) {
125        $service = strtolower($service);
126        return $this->getConf($service.'-tokenurl');
127    }
128
129    /**
130     * Return the configured User Info Endpoint URL for the given service
131     *
132     * @param $service
133     * @return string
134     */
135    public function getUserInfoEndpoint($service) {
136        $service = strtolower($service);
137        return $this->getConf($service.'-userinfourl');
138    }
139
140    /**
141     * @return array
142     */
143    public function getValidDomains() {
144        if ($this->getConf('mailRestriction') === '') {
145            return array();
146        }
147        $validDomains = explode(',', trim($this->getConf('mailRestriction'), ','));
148        $validDomains = array_map('trim', $validDomains);
149        return $validDomains;
150    }
151
152    /**
153     * @param string $mail
154     *
155     * @return bool
156     */
157    public function checkMail($mail) {
158        $hostedDomains = $this->getValidDomains();
159
160        foreach ($hostedDomains as $validDomain) {
161            if(substr($mail, -strlen($validDomain)) === $validDomain) {
162                return true;
163            }
164        }
165        return false;
166    }
167
168    /**
169     * @param array $session cookie auth session
170     *
171     * @return bool
172     */
173    public function validBrowserID ($session) {
174        return $session['buid'] == auth_browseruid();
175    }
176
177    /**
178     * @param array $session cookie auth session
179     *
180     * @return bool
181     */
182    public function isSessionTimedOut ($session) {
183        global $conf;
184        return $session['time'] < time() - $conf['auth_security_timeout'];
185    }
186
187    /**
188     * @return bool
189     */
190    public function isGETRequest () {
191        global $INPUT;
192        $result = $INPUT->server->str('REQUEST_METHOD') === 'GET';
193        return $result;
194    }
195
196    /**
197     * check if we are handling a request to doku.php. Only doku.php defines $updateVersion
198     *
199     * @return bool
200     */
201    public function isDokuPHP() {
202        global $updateVersion;
203        return isset($updateVersion);
204    }
205}
206
207// vim:ts=4:sw=4:et:
208