Skip to content

Commit

Permalink
Merge pull request #101 from checkmarx-ltd/Q1_2024_integration_branch
Browse files Browse the repository at this point in the history
Changes related to result state and plugin name in user agent header
  • Loading branch information
ThokalSameer authored Jan 25, 2024
2 parents d71134d + 5e63dd2 commit 8863782
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 18 deletions.
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@checkmarx/cx-common-js-client",
"version": "0.1.83",
"version": "0.1.84",
"description": "Client for interaction with Checkmarx products.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -38,22 +38,23 @@
"dependencies": {
"archiver": "^3.0.0",
"dateformat": "^3.0.3",
"debug": "^4.3.2",
"glob-parent": "^5.1.2",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
"micromatch": "^3.1.0",
"mkdirp": "^0.5.4",
"parse-ms": "^2.1.0",
"promise-poller": "^1.9.1",
"proxy-agent": "^4.0.1",
"snapdragon": "^0.12.1",
"superagent": "^5.1.0",
"superagent-proxy": "^2.1.0",
"tmp": "^0.1.0",
"upath": "^1.2.0",
"walk": "^2.3.14",
"xml2js": "^0.4.22",
"debug": "^4.3.2",
"lodash": "^4.17.21",
"glob-parent": "^5.1.2",
"y18n": "^4.0.1",
"snapdragon": "^0.12.1"
"y18n": "^4.0.1"
},
"devDependencies": {
"@types/archiver": "^2.1.3",
Expand Down
3 changes: 2 additions & 1 deletion src/dto/apiConstant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export class APIConstants {

public static readonly authorizationEP:string = 'auth/identity/connect/authorize';
public static readonly accessTokenEP:string = 'auth/identity/connect/token';
public static readonly userInfoEP:string = 'auth/identity/connect/userinfo';
public static readonly responseType:string = 'code';
public static readonly CLIENT_ID:string = 'client_id';
public static readonly SCOPE:string = 'scope';
Expand All @@ -14,5 +15,5 @@ export class APIConstants {
public static readonly GRANT_TYPE:string = 'grant_type';
public static readonly AUTHORIZATION_CODE:string = 'authorization_code';
public static readonly REFRESH_TOKEN:string = 'refresh_token';

public static readonly BEARER:string = 'BEARER';
}
1 change: 1 addition & 0 deletions src/dto/scanConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ export interface ScanConfig {
sastConfig?: SastConfig;
scaConfig?: ScaConfig;
proxyConfig?: ProxyConfig;
version?: string;
}
8 changes: 4 additions & 4 deletions src/services/clients/cxClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,11 @@ export class CxClient {
sastProxyConfig.proxyUrl = this.proxyConfig.sastProxyUrl != '' ? this.proxyConfig.sastProxyUrl : this.proxyConfig.proxyUrl;
sastProxyConfig.sastProxyUrl = '';
sastProxyConfig.scaProxyUrl = '';
this.httpClient = new HttpClient(baseUrl, this.config.cxOrigin, this.config.cxOriginUrl, this.log, sastProxyConfig, this.sastConfig.cacert_chainFilePath);
this.httpClient = new HttpClient(baseUrl, this.config.cxOrigin, this.config.cxOriginUrl, this.log, sastProxyConfig, this.sastConfig.cacert_chainFilePath,this.config.version);
}
else
{
this.httpClient = new HttpClient(baseUrl, this.config.cxOrigin, this.config.cxOriginUrl, this.log, undefined, this.sastConfig.cacert_chainFilePath);
this.httpClient = new HttpClient(baseUrl, this.config.cxOrigin, this.config.cxOriginUrl, this.log, undefined, this.sastConfig.cacert_chainFilePath,this.config.version);
}
await this.httpClient.getPacProxyResolve();
await this.httpClient.login(this.sastConfig.username, this.sastConfig.password);
Expand All @@ -165,11 +165,11 @@ export class CxClient {
scaProxyConfig.sastProxyUrl = '';
scaProxyConfig.scaProxyUrl = '';
this.log.info("Overriten URL "+this.config.proxyConfig.sastProxyUrl);
scaHttpClient = new HttpClient(this.scaConfig.apiUrl, this.config.cxOrigin, this.config.cxOriginUrl,this.log, scaProxyConfig, this.scaConfig.cacert_chainFilePath);
scaHttpClient = new HttpClient(this.scaConfig.apiUrl, this.config.cxOrigin, this.config.cxOriginUrl,this.log, scaProxyConfig, this.scaConfig.cacert_chainFilePath,this.config.version);
}
else
{
scaHttpClient = new HttpClient(this.scaConfig.apiUrl, this.config.cxOrigin, this.config.cxOriginUrl,this.log, undefined, this.scaConfig.cacert_chainFilePath);
scaHttpClient = new HttpClient(this.scaConfig.apiUrl, this.config.cxOrigin, this.config.cxOriginUrl,this.log, undefined, this.scaConfig.cacert_chainFilePath,this.config.version);
}
await scaHttpClient.getPacProxyResolve();
this.scaClient = new ScaClient(this.scaConfig, this.config.sourceLocation, scaHttpClient, this.log,scaProxyConfig, this.config);
Expand Down
84 changes: 77 additions & 7 deletions src/services/clients/httpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { AuthSSODetails } from "../../dto/authSSODetails";
import { APIConstants } from "../../dto/apiConstant";
import fs = require('fs');
import pac = require('pac-resolver');

import {jwtDecode, JwtPayload } from 'jwt-decode';

interface InternalRequestOptions extends RequestOptions {
method: 'put' | 'post' | 'get' | 'patch';
Expand Down Expand Up @@ -47,15 +47,17 @@ export class HttpClient {
accessToken: string = '';
refreshToken: string = '';
tokenExpTime: number = 0;
permissions : Array<string> | any;

private proxyResult = '';
private proxyContent = '';
private scaSettings: ScaLoginSettings | any;
isSsoLogin: boolean = false;
private loginType:string = '';
private certificate : string | any;
public readonly SAST_PERMISSION:string = 'sast-permissions';

constructor(private readonly baseUrl: string, private readonly origin: string, private readonly originUrl : string, private readonly log: Logger, private proxyConfig?: ProxyConfig, private certFilePath? : string ) {
constructor(private readonly baseUrl: string, private readonly origin: string, private readonly originUrl : string, private readonly log: Logger, private proxyConfig?: ProxyConfig, private certFilePath? : string, private version? : string ) {

if(this.certFilePath)
{
Expand Down Expand Up @@ -169,6 +171,44 @@ export class HttpClient {
return authCodeURL;
}

/**
* This method gets all user permission details
* @returns
*/

async getPermissionsFromUserInfo(){
var authHeader = {'Content-Length':'0','Authorization' :APIConstants.BEARER + this.accessToken};
const fullUrl = url.resolve(this.baseUrl, APIConstants.userInfoEP);
const response = await this.postRequestWithAuthHeader(fullUrl, request,authHeader);
this.permissions = response[this.SAST_PERMISSION];
}


/**
* This method decodes access token using jwt decode
* @returns
*/
async getDecodedAccessToken() {
return jwtDecode(this.accessToken);
}

/**
* This method gets all user permission details using jwt-decode
* @returns
*/
async getPermissionDetailsUsingJwtDecode() {
const tokenInfo : JwtPayload | any = await this.getDecodedAccessToken();
this.permissions = tokenInfo[this.SAST_PERMISSION];
}

/**
* This method validates user have permission or not
* @returns
*/
async validateUserPermission(permissionName : string){
return this.permissions.includes(permissionName);
}

/**
* This methos executed single sign on using authorization code
* @param authSSODetails AuthSSODetails object contains details about SSO login
Expand Down Expand Up @@ -196,6 +236,10 @@ export class HttpClient {
if(this.certificate){
newRequest.ca(this.certificate);
}
if(this.origin && this.version)
{
newRequest.set({ 'User-Agent': this.getUserAgentValue() });
}
return newRequest.send({
grant_type: APIConstants.AUTHORIZATION_CODE,
client_id: authSSODetails.clientId,
Expand Down Expand Up @@ -263,6 +307,10 @@ export class HttpClient {
if(this.certificate){
newRequest.ca(this.certificate);
}
if(this.origin && this.version)
{
newRequest.set({ 'User-Agent': this.getUserAgentValue() });
}
return newRequest.send({
grant_type: APIConstants.REFRESH_TOKEN,
client_id: authSSODetails.clientId,
Expand Down Expand Up @@ -334,26 +382,32 @@ export class HttpClient {
}

getRequest(relativePath: string, options?: RequestOptions): Promise<any> {
const internalOptions: InternalRequestOptions = { retry: true, method: 'get', blob: false, customHeaders:{} };
const internalOptions: InternalRequestOptions = { retry: true, method: 'get', blob: false, customHeaders:this.getUserAgentHeader() };
return this.sendRequest(relativePath, Object.assign(internalOptions, options));
}

patchRequest(relativePath: string, data: object): Promise<any> {
return this.sendRequest(relativePath, { singlePostData: data, retry: true, method: 'patch', blob: false, customHeaders:{} });
return this.sendRequest(relativePath, { singlePostData: data, retry: true, method: 'patch', blob: false, customHeaders:this.getUserAgentHeader() });
}

postRequest(relativePath: string, data: object): Promise<any> {
return this.sendRequest(relativePath, { singlePostData: data, retry: true, method: 'post', blob: false, customHeaders:{} });
return this.sendRequest(relativePath, { singlePostData: data, retry: true, method: 'post', blob: false, customHeaders:this.getUserAgentHeader() });
}

putRequest(relativePath: string, data: object): Promise<any> {
return this.sendRequest(relativePath, { singlePostData: data, retry: true, method: 'put', blob: false, customHeaders:{} });
return this.sendRequest(relativePath, { singlePostData: data, retry: true, method: 'put', blob: false, customHeaders:this.getUserAgentHeader() });
}

postRequestWithAuthHeader(relativePath: string, data: object,additionalHeaders: {}): Promise<any> {
const customHeaders = { customHeaders:this.getUserAgentHeader() };
return this.sendRequest(relativePath, { singlePostData: data, retry: true, method: 'post', blob: false, customHeaders:Object.assign(additionalHeaders, customHeaders) });
}

postMultipartRequest(relativePath: string,
fields: { [fieldName: string]: any },
attachments: { [fieldName: string]: string } ,
additionalHeaders: {}) {
const customHeaders = { customHeaders:this.getUserAgentHeader() };
return this.sendRequest(relativePath, {
method: 'post',
multipartPostData: {
Expand All @@ -362,10 +416,18 @@ export class HttpClient {
},
retry: true,
blob: false,
customHeaders: additionalHeaders
customHeaders: Object.assign(additionalHeaders, customHeaders)
});
}

private getUserAgentValue() : string | undefined {
return 'plugin_name=' + this.origin + ';plugin_version=' + this.version;

}
private getUserAgentHeader(): {} | undefined {
return this.origin && this.version ? { 'User-Agent': this.getUserAgentValue() } : {};
}

private isObject(obj:object) { return Object(obj) === obj; }

private sendRequest(relativePath: string, options: InternalRequestOptions): Promise<any> {
Expand Down Expand Up @@ -496,6 +558,10 @@ export class HttpClient {
if(this.certificate){
newRequest.ca(this.certificate);
}
if(this.origin && this.version)
{
newRequest.set({ 'User-Agent': this.getUserAgentValue()});
}
return newRequest.send({
userName: this.username,
password: this.password,
Expand Down Expand Up @@ -537,6 +603,10 @@ export class HttpClient {
if(this.certificate){
newRequest.ca(this.certificate);
}
if(this.origin && this.version)
{
newRequest.set({ 'User-Agent': this.getUserAgentValue() });
}
// Pass tenant name in a custom header. This will allow to get token from on-premise access control server
// and then use this token for SCA authentication in cloud.
return newRequest.set(ScaClient.TENANT_HEADER_NAME, settings.tenant)
Expand Down

0 comments on commit 8863782

Please sign in to comment.