1<?php
2/***********************************************************
3 * Copyright (C) 2019 Siemens AG
4 * Author: Gaurav Mishra <mishra.gaurav@siemens.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **********************************************************/
19namespace Fossology\UI\Ajax;
20
21use Fossology\Lib\Db\DbManager;
22use Fossology\Lib\Plugin\DefaultPlugin;
23use Fossology\Lib\Auth\Auth;
24use Symfony\Component\HttpFoundation\Request;
25use Symfony\Component\HttpFoundation\JsonResponse;
26use Fossology\UI\Api\Helper\RestHelper;
27
28/**
29 * @class AjaxManageToken
30 * @brief Class to handle ajax calls to revoke an API token
31 */
32class AjaxManageToken extends DefaultPlugin
33{
34
35  const NAME = "manage-token";
36
37  /** @var DbManager $dbManager
38   * DB manager to use */
39  private $dbManager;
40
41  function __construct()
42  {
43    parent::__construct(self::NAME,
44      array(
45        self::PERMISSION => Auth::PERM_WRITE
46      ));
47    $this->dbManager = $this->getObject('db.manager');
48  }
49
50  /**
51   * @brief Revoke an active API token
52   * @param Request $request
53   * @return Response Status as true if token is revoked or false on failure.
54   */
55  protected function handle(Request $request)
56  {
57    $task = GetParm('task', PARM_STRING);
58    $tokenId = GetParm('token-id', PARM_STRING);
59    $response = null;
60
61    list($tokenPk, $userId) = explode(".", $tokenId);
62    if (Auth::getUserId() != $userId) {
63      $task = "invalid";
64    } else {
65      $verifySql = "SELECT user_fk FROM personal_access_tokens " .
66                   "WHERE pat_pk = $1 LIMIT 1;";
67
68      $row = $this->dbManager->getSingleRow($verifySql, [$tokenPk],
69        __METHOD__ . ".verifyToken");
70      if (empty($row) || $row['user_fk'] != $userId) {
71        $task = "invalid";
72      }
73    }
74    switch ($task) {
75      case "reveal":
76        $response = new JsonResponse($this->revealToken($tokenPk,
77          $request->getHost()));
78        break;
79      case "revoke":
80        $response = new JsonResponse($this->invalidateToken($tokenPk));
81        break;
82      default:
83        $response = new JsonResponse(["status" => false], 400);
84    }
85    return $response;
86  }
87
88  /**
89   * Regenerate the JWT token from DB.
90   *
91   * @param int    $tokenPk  The token id
92   * @param string $hostname Host issuing the token
93   * @returns array Array with success status and token.
94   */
95  private function revealToken($tokenPk, $hostname)
96  {
97    global $container;
98    $restDbHelper = $container->get("helper.dbHelper");
99    $authHelper = $container->get('helper.authHelper');
100    $user_pk = Auth::getUserId();
101    $jti = "$tokenPk.$user_pk";
102
103    $tokenInfo = $restDbHelper->getTokenKey($tokenPk);
104    $tokenScope = array_search($tokenInfo['token_scope'], RestHelper::SCOPE_DB_MAP);
105
106    $jwtToken = $authHelper->generateJwtToken($tokenInfo['expire_on'],
107      $tokenInfo['created_on'], $jti, $tokenScope, $tokenInfo['token_key']);
108    return array(
109      "status" => true,
110      "token" => $jwtToken
111    );
112  }
113
114  /**
115   * Mark a token as invalid/inactive.
116   *
117   * @param int $tokenPk  The token id to be revoked
118   * @returns array Array with success status.
119   */
120  private function invalidateToken($tokenPk)
121  {
122    global $container;
123    $restDbHelper = $container->get("helper.dbHelper");
124    $restDbHelper->invalidateToken($tokenPk);
125    return array(
126      "status" => true
127    );
128  }
129}
130
131register_plugin(new AjaxManageToken());
132