1<?php
2
3namespace OAuth\Plugin;
4
5use OAuth\OAuth2\Service\EveOnline;
6
7/**
8 * Class DoorkeeperAdapter
9 *
10 * This is an example on how to implement your own adapter for making DokuWiki login against
11 * a custom oAuth provider. The used Generic Service backend expects the authorization and
12 * token endpoints to be configured in the DokuWiki backend.
13 *
14 * Your custom API to access user data has to be implemented in the getUser function. The one here
15 * is setup to work with the demo setup of the "Doorkeeper" ruby gem.
16 *
17 * @link https://github.com/doorkeeper-gem/doorkeeper
18 * @package OAuth\Plugin
19 */
20class EveOnlineAdapter extends AbstractAdapter {
21
22    /**
23     * Retrieve the user's data
24     *
25     * The array needs to contain at least 'user', 'mail', 'name' and optional 'grps'
26     *
27     * @return array
28     */
29    public function getUser() {
30        $http = new \DokuHTTPClient();
31        $data = array();
32
33        //Get access_token
34        $access_token = $this->oAuth->getStorage()->retrieveAccessToken($this->oAuth->service())->getAccessToken();
35
36        //Split JWT into 3 parts > Take the 2nd part (payload) > base64 decode it > json decode it
37        $jwt_payload = json_decode(base64_decode(str_replace('_', '/', str_replace('-','+',explode('.', $access_token)[1]))));
38
39        //Get character name and id
40        $character_name=$jwt_payload->name; //Character Name
41        $character_id=explode(":",$jwt_payload->sub)[2]; //Charater ID (remove the extra stuff)
42
43        if (!isset($character_id)) {
44            return $data;
45        }
46
47        //Set character name and id
48        $data['user'] = $character_name;
49        $data['name'] = $character_name;
50        $data['mail'] = $character_id . '@eveonline.com';
51
52        //Get character corporation, alliance, and faction
53        $affiliation_post = $http->post('https://esi.evetech.net/latest/characters/affiliation/?datasource=tranquility', '[' . $character_id . ']');
54        if ($affiliation_post === false) {
55            return $data;
56        }
57        $affiliation_result = json_decode($affiliation_post, true);
58
59        $ids = array();
60        foreach ($affiliation_result as $entry) {
61            if (isset($entry['alliance_id'])) {
62                $ids[] = $entry['alliance_id'];
63            }
64            if (isset($entry['faction_id'])) {
65                $ids[] = $entry['faction_id'];
66            }
67            $ids[] = $entry['corporation_id'];
68        }
69
70        //Convert ids to names
71        $names_post = $http->post('https://esi.evetech.net/latest/universe/names/?datasource=tranquility', '[' . implode(",", $ids) . ']');
72        if ($names_post === false) {
73            return $data;
74        }
75        $names_result = json_decode($names_post, true);
76
77        foreach ($names_result as $entry) {
78            $name = strtolower(str_replace(" ", "_", str_replace(".", "-", $entry['name'])));
79            $category = $entry['category'];
80            if ($category == 'corporation') {
81                $data['grps'][] = 'eve-corp-' . $name;
82            } elseif ($category == 'alliance') {
83                $data['grps'][] = 'eve-alliance-' . $name;
84            } elseif ($category == 'faction') {
85                $data['grps'][] = 'eve-faction-' . $name;
86            }
87        }
88
89        return $data;
90    }
91
92    public function getScope() {
93        return array(EveOnline::SCOPE_PUBLIC_DATA);
94    }
95
96    public function login() {
97        $parameters = array();
98        $parameters['state'] = urlencode(base64_encode(json_encode(array('state' => md5(rand())))));
99        $this->storage->storeAuthorizationState($this->oAuth->service(), $parameters['state']);
100        $url = $this->oAuth->getAuthorizationUri($parameters);
101        send_redirect($url);
102    }
103}