b3096d16518c4493402c7cd52899f36932c48dff
[authserver.git] / api.php
1 <?php
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 // Called e.g. as /api?access_token=...&whatever_api_parameters
7 // access_token can be handed via GET or POST or an 'Authorization: Bearer' header.
8 // Response is always JSON.
9
10 // Include the common auth system files (including the OAuth2 Server object).
11 require_once(__DIR__.'/authsystem.inc.php');
12
13 $errors = $utils->checkForSecureConnection();
14
15 if (!count($errors)) {
16   // Handle a request to a resource and authenticate the access token
17   $token_OK = $server->verifyResourceRequest(OAuth2\Request::createFromGlobals());
18   if (!$token_OK) {
19     $server->getResponse()->send();
20     exit();
21   }
22   $token = $server->getAccessTokenData(OAuth2\Request::createFromGlobals());
23   // API request successful, return requested resource.
24   if (array_key_exists('email', $_GET)) {
25     if ($token['scope'] == 'email') {
26       if (intval(@$token['user_id'])) {
27         $result = $db->prepare('SELECT `id`,`email` FROM `auth_users` WHERE `id` = :userid;');
28         $result->execute(array(':userid' => $token['user_id']));
29         $user = $result->fetch(PDO::FETCH_ASSOC);
30         if (!$user['id']) {
31           $utils->log('user_token_failure', 'token: '.$token['access_token']);
32           print(json_encode(array('error' => 'unknown_user',
33                                   'error_description' => 'The user the access token is connected to was not recognized.')));
34         }
35         else {
36           print(json_encode(array('success' => true, 'email' => $user['email'])));
37         }
38       }
39       else {
40         print(json_encode(array('error' => 'no_user',
41                                 'error_description' => 'The access token is not connected to a user.')));
42       }
43     }
44     else {
45       print(json_encode(array('error' => 'insufficient_scope',
46                               'error_description' => 'The scope of the token you used in this API request is insufficient to access this resource.')));
47     }
48   }
49   elseif (array_key_exists('newclient', $_GET)) {
50     if ($token['scope'] == 'clientreg') {
51       if (intval(@$token['user_id'])) {
52         $result = $db->prepare('SELECT `id`,`email` FROM `auth_users` WHERE `id` = :userid;');
53         $result->execute(array(':userid' => $token['user_id']));
54         $user = $result->fetch(PDO::FETCH_ASSOC);
55         if (!$user['id']) {
56           $utils->log('user_token_failure', 'token: '.$token['access_token']);
57           print(json_encode(array('error' => 'unknown_user',
58                                   'error_description' => 'The user the access token is connected to was not recognized.')));
59         }
60         else {
61           if (in_array($user['email'], $utils->client_reg_email_whitelist)) {
62             if (strlen(@$_GET['client_id']) >= 5) {
63               $result = $db->prepare('SELECT `client_id`,`user_id` FROM `oauth_clients` WHERE `client_id` = :clientid;');
64               $result->execute(array(':clientid' => $_GET['client_id']));
65               $client = $result->fetch(PDO::FETCH_ASSOC);
66               if (!$client['client_id']) {
67                 // Set new client ID.
68                 $clientsecret = $utils->createClientSecret();
69                 $result = $db->prepare('INSERT INTO `oauth_clients` (`client_id`, `client_secret`, `redirect_uri`, `scope`, `user_id`) VALUES (:clientid, :secret, :rediruri, :scope, :userid);');
70                 if ($result->execute(array(':clientid' => $_GET['client_id'],
71                                            ':secret' => $clientsecret,
72                                            ':rediruri' => (strlen(@$_GET['redirect_uri']) ? $_GET['redirect_uri'] : ''),
73                                            ':scope' => (strlen(@$_GET['scope']) ? $_GET['scope'] : ''),
74                                            ':userid' => $user['id']))) {
75                   print(json_encode(array('success' => true, 'client_secret' => $clientsecret)));
76                 }
77                 else {
78                   $utils->log('client_save_failure', 'client: '.$client['client_id']);
79                   print(json_encode(array('error' => 'unexpected_save_failure',
80                                           'error_description' => 'Unexpectedly failed to save new client information.')));
81                 }
82               }
83               elseif ($client['user_id'] == $user['id']) {
84                 // The client ID was set by this user, set new secret and return.
85                 $clientsecret = $utils->createClientSecret();
86                 $result = $db->prepare('UPDATE `oauth_clients` SET `client_secret` = :secret WHERE `client_id` = :clientid;');
87                 if (!$result->execute(array(':secret' => $clientsecret,':clientid' => $client['client_id']))) {
88                   $utils->log('client_save_failure', 'client: '.$client['client_id'].', new secret - '.$result->errorInfo()[2]);
89                   print(json_encode(array('error' => 'unexpected_save_failure',
90                                           'error_description' => 'Unexpectedly failed to save new secret.')));
91                 }
92                 else {
93                   if (strlen(@$_GET['redirect_uri'])) {
94                     $result = $db->prepare('UPDATE `oauth_clients` SET `redirect_uri` = :rediruri WHERE `client_id` = :clientid;');
95                     if (!$result->execute(array(':rediruri' => $_GET['redirect_uri'],':clientid' => $client['client_id']))) {
96                       $utils->log('client_save_failure', 'client: '.$client['client_id'].', new redirect_uri: '.$_GET['redirect_uri'].' - '.$result->errorInfo()[2]);
97                     }
98                   }
99                   if (strlen(@$_GET['scope'])) {
100                     $result = $db->prepare('UPDATE `oauth_clients` SET `scope` = :scope WHERE `client_id` = :clientid;');
101                     if (!$result->execute(array(':scope' => $_GET['scope'],':clientid' => $client['client_id']))) {
102                       $utils->log('client_save_failure', 'client: '.$client['client_id'].', new scope: '.$_GET['scope'].' - '.$result->errorInfo()[2]);
103                     }
104                   }
105                   print(json_encode(array('success' => true, 'client_secret' => $clientsecret)));
106                 }
107               }
108               else {
109                 print(json_encode(array('error' => 'client_id_used',
110                                         'error_description' => 'This client ID is in use by a different user.')));
111               }
112             }
113             else {
114               print(json_encode(array('error' => 'invalid_client_id_',
115                                       'error_description' => 'A client ID of at least 5 characters needs to be supplied.')));
116             }
117           }
118           else {
119             print(json_encode(array('error' => 'insufficient_privileges',
120                                     'error_description' => 'This user is not allowed to register new clients.')));
121           }
122         }
123       }
124       else {
125         print(json_encode(array('error' => 'no_user',
126                                 'error_description' => 'The access token is not connected to a user.')));
127       }
128     }
129     else {
130       print(json_encode(array('error' => 'insufficient_scope',
131                               'error_description' => 'The scope of the token you used in this API request is insufficient to access this resource.')));
132     }
133   }
134   else {
135     print(json_encode(array('error' => 'invalid_resource',
136                             'error_description' => 'The resource requested from the API is unknown.')));
137   }
138 }
139 else {
140   print(json_encode(array('error' => 'insecure_connection',
141                           'error_description' => 'Your connection is insecure. The API can only be accessed on secure connections.')));
142 }
143 ?>