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