blob: 7dc5602513a41eeb0e5646a13f169f5ec119d3bf [file] [log] [blame]
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01001<?php
2function oauth2($_action, $_type, $_data = null) {
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +02003 global $pdo;
4 global $redis;
5 global $lang;
6 if ($_SESSION['mailcow_cc_role'] != "admin") {
7 $_SESSION['return'][] = array(
8 'type' => 'danger',
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01009 'log' => array(__FUNCTION__, $_action, $_type, $_data),
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020010 'msg' => 'access_denied'
11 );
12 return false;
13 }
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010014 switch ($_action) {
15 case 'add':
16 switch ($_type) {
17 case 'client':
18 $client_id = bin2hex(random_bytes(6));
19 $client_secret = bin2hex(random_bytes(12));
20 $redirect_uri = $_data['redirect_uri'];
21 $scope = 'profile';
22 // For future use
23 // $grant_type = isset($_data['grant_type']) ? $_data['grant_type'] : 'authorization_code';
24 // $scope = isset($_data['scope']) ? $_data['scope'] : 'profile';
25 // if ($grant_type != "authorization_code" && $grant_type != "password") {
26 // $_SESSION['return'][] = array(
27 // 'type' => 'danger',
28 // 'log' => array(__FUNCTION__, $_action, $_type, $_data),
29 // 'msg' => 'access_denied'
30 // );
31 // return false;
32 // }
33 if ($scope != "profile") {
34 $_SESSION['return'][] = array(
35 'type' => 'danger',
36 'log' => array(__FUNCTION__, $_action, $_type, $_data),
37 'msg' => 'Invalid scope'
38 );
39 return false;
40 }
41 $stmt = $pdo->prepare("SELECT 'client' FROM `oauth_clients`
42 WHERE `client_id` = :client_id");
43 $stmt->execute(array(':client_id' => $client_id));
44 $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
45 if ($num_results != 0) {
46 $_SESSION['return'][] = array(
47 'type' => 'danger',
48 'log' => array(__FUNCTION__, $_action, $_type, $_data),
49 'msg' => 'Client ID exists'
50 );
51 return false;
52 }
53 $stmt = $pdo->prepare("INSERT INTO `oauth_clients` (`client_id`, `client_secret`, `redirect_uri`, `scope`)
54 VALUES (:client_id, :client_secret, :redirect_uri, :scope)");
55 $stmt->execute(array(
56 ':client_id' => $client_id,
57 ':client_secret' => $client_secret,
58 ':redirect_uri' => $redirect_uri,
59 ':scope' => $scope
60 ));
61 $_SESSION['return'][] = array(
62 'type' => 'success',
63 'log' => array(__FUNCTION__, $_action, $_type, $_data),
64 'msg' => 'Added client access'
65 );
66 break;
67 }
68 break;
69 case 'edit':
70 switch ($_type) {
71 case 'client':
72 $ids = (array)$_data['id'];
73 foreach ($ids as $id) {
74 $is_now = oauth2('details', 'client', $id);
75 if (!empty($is_now)) {
76 $redirect_uri = (!empty($_data['redirect_uri'])) ? $_data['redirect_uri'] : $is_now['redirect_uri'];
77 }
78 else {
79 $_SESSION['return'][] = array(
80 'type' => 'danger',
81 'log' => array(__FUNCTION__, $_action, $_type, $_data),
82 'msg' => 'access_denied'
83 );
84 return false;
85 }
86 if (isset($_data['revoke_tokens'])) {
87 $stmt = $pdo->prepare("DELETE FROM `oauth_access_tokens`
88 WHERE `client_id` IN (
89 SELECT `client_id` FROM `oauth_clients` WHERE `id` = :id
90 )");
91 $stmt->execute(array(
92 ':id' => $id
93 ));
94 $stmt = $pdo->prepare("DELETE FROM `oauth_refresh_tokens`
95 WHERE `client_id` IN (
96 SELECT `client_id` FROM `oauth_clients` WHERE `id` = :id
97 )");
98 $stmt->execute(array(
99 ':id' => $id
100 ));
101 $_SESSION['return'][] = array(
102 'type' => 'success',
103 'log' => array(__FUNCTION__, $_action, $_type, $_data),
104 'msg' => array('object_modified', htmlspecialchars($id))
105 );
106 continue;
107 }
108 if (isset($_data['renew_secret'])) {
109 $client_secret = bin2hex(random_bytes(12));
110 $stmt = $pdo->prepare("UPDATE `oauth_clients` SET `client_secret` = :client_secret WHERE `id` = :id");
111 $stmt->execute(array(
112 ':client_secret' => $client_secret,
113 ':id' => $id
114 ));
115 $_SESSION['return'][] = array(
116 'type' => 'success',
117 'log' => array(__FUNCTION__, $_action, $_type, $_data),
118 'msg' => array('object_modified', htmlspecialchars($id))
119 );
120 continue;
121 }
122 if (empty($redirect_uri)) {
123 $_SESSION['return'][] = array(
124 'type' => 'danger',
125 'log' => array(__FUNCTION__, $_action, $_type, $_data),
126 'msg' => 'Redirect/Callback URL cannot be empty'
127 );
128 continue;
129 }
130 $stmt = $pdo->prepare("UPDATE `oauth_clients` SET
131 `redirect_uri` = :redirect_uri
132 WHERE `id` = :id");
133 $stmt->execute(array(
134 ':id' => $id,
135 ':redirect_uri' => $redirect_uri
136 ));
137 $_SESSION['return'][] = array(
138 'type' => 'success',
139 'log' => array(__FUNCTION__, $_action, $_type, $_data),
140 'msg' => array('object_modified', htmlspecialchars($id))
141 );
142 }
143 break;
144 }
145 break;
146 case 'delete':
147 switch ($_type) {
148 case 'client':
149 (array)$ids = $_data['id'];
150 foreach ($ids as $id) {
151 if (!is_numeric($id)) {
152 $_SESSION['return'][] = array(
153 'type' => 'danger',
154 'log' => array(__FUNCTION__, $_action, $_type, $_data),
155 'msg' => 'access_denied'
156 );
157 continue;
158 }
159 $stmt = $pdo->prepare("DELETE FROM `oauth_clients`
160 WHERE `id` = :id");
161 $stmt->execute(array(
162 ':id' => $id
163 ));
164 }
165 $_SESSION['return'][] = array(
166 'type' => 'success',
167 'log' => array(__FUNCTION__, $_action, $_type, $_data),
168 'msg' => array('items_deleted', htmlspecialchars($id))
169 );
170 break;
171 case 'access_token':
172 (array)$access_tokens = $_data['access_token'];
173 foreach ($access_tokens as $access_token) {
174 if (!ctype_alnum($access_token)) {
175 $_SESSION['return'][] = array(
176 'type' => 'danger',
177 'log' => array(__FUNCTION__, $_action, $_type, $_data),
178 'msg' => 'access_denied'
179 );
180 return false;
181 }
182 $stmt = $pdo->prepare("DELETE FROM `oauth_access_tokens`
183 WHERE `access_token` = :access_token");
184 $stmt->execute(array(
185 ':access_token' => $access_token
186 ));
187 }
188 $_SESSION['return'][] = array(
189 'type' => 'success',
190 'log' => array(__FUNCTION__, $_action, $_type, $_data),
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200191 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', (array)$access_tokens))
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100192 );
193 break;
194 case 'refresh_token':
195 (array)$refresh_tokens = $_data['refresh_token'];
196 foreach ($refresh_tokens as $refresh_token) {
197 if (!ctype_alnum($refresh_token)) {
198 $_SESSION['return'][] = array(
199 'type' => 'danger',
200 'log' => array(__FUNCTION__, $_action, $_type, $_data),
201 'msg' => 'access_denied'
202 );
203 return false;
204 }
205 $stmt = $pdo->prepare("DELETE FROM `oauth_refresh_tokens` WHERE `refresh_token` = :refresh_token");
206 $stmt->execute(array(
207 ':refresh_token' => $refresh_token
208 ));
209 }
210 $_SESSION['return'][] = array(
211 'type' => 'success',
212 'log' => array(__FUNCTION__, $_action, $_type, $_data),
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200213 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', (array)$refresh_tokens))
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +0100214 );
215 break;
216 }
217 break;
218 case 'get':
219 switch ($_type) {
220 case 'clients':
221 $stmt = $pdo->query("SELECT `id` FROM `oauth_clients`");
222 $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
223 while ($row = array_shift($rows)) {
224 $oauth_clients[] = $row['id'];
225 }
226 return $oauth_clients;
227 break;
228 }
229 break;
230 case 'details':
231 switch ($_type) {
232 case 'client':
233 $stmt = $pdo->prepare("SELECT * FROM `oauth_clients`
234 WHERE `id` = :id");
235 $stmt->execute(array(':id' => $_data));
236 $oauth_client_details = $stmt->fetch(PDO::FETCH_ASSOC);
237 return $oauth_client_details;
238 break;
239 }
240 break;
241 }
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +0200242}