functions.oauth2.inc.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. function oauth2($_action, $_type, $_data = null) {
  3. global $pdo;
  4. global $redis;
  5. global $lang;
  6. if ($_SESSION['mailcow_cc_role'] != "admin") {
  7. $_SESSION['return'][] = array(
  8. 'type' => 'danger',
  9. 'log' => array(__FUNCTION__, $_action, $_type, $_data),
  10. 'msg' => 'access_denied'
  11. );
  12. return false;
  13. }
  14. 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),
  191. 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', (array)$access_tokens))
  192. );
  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),
  213. 'msg' => sprintf($lang['success']['items_deleted'], implode(', ', (array)$refresh_tokens))
  214. );
  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. }
  242. }