From 39f5cf92d829469a31aefce63226229e439c2632 Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Tue, 16 Jun 2020 15:50:17 +0200 Subject: [PATCH 1/2] Gitlab OAuth2 support --- .../GitlabOAuth2Api.credentials.ts | 53 +++++++++++++++++ .../nodes/Gitlab/GenericFunctions.ts | 42 +++++++++---- .../nodes-base/nodes/Gitlab/Gitlab.node.ts | 59 +++++++++++++++++-- .../nodes/Gitlab/GitlabTrigger.node.ts | 37 +++++++++++- packages/nodes-base/package.json | 1 + 5 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 packages/nodes-base/credentials/GitlabOAuth2Api.credentials.ts diff --git a/packages/nodes-base/credentials/GitlabOAuth2Api.credentials.ts b/packages/nodes-base/credentials/GitlabOAuth2Api.credentials.ts new file mode 100644 index 0000000000..60cc091836 --- /dev/null +++ b/packages/nodes-base/credentials/GitlabOAuth2Api.credentials.ts @@ -0,0 +1,53 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + + +export class GitlabOAuth2Api implements ICredentialType { + name = 'gitlabOAuth2Api'; + extends = [ + 'oAuth2Api', + ]; + displayName = 'Gitlab OAuth2 API'; + properties = [ + { + displayName: 'Gitlab Server', + name: 'server', + type: 'string' as NodePropertyTypes, + default: 'https://gitlab.com' + }, + { + displayName: 'Authorization URL', + name: 'authUrl', + type: 'hidden' as NodePropertyTypes, + default: 'https://gitlab.com/oauth/authorize', + required: true, + }, + { + displayName: 'Access Token URL', + name: 'accessTokenUrl', + type: 'hidden' as NodePropertyTypes, + default: 'https://gitlab.com/oauth/token', + required: true, + }, + { + displayName: 'Scope', + name: 'scope', + type: 'string' as NodePropertyTypes, + default: 'api', + }, + { + displayName: 'Auth URI Query Parameters', + name: 'authQueryParameters', + type: 'hidden' as NodePropertyTypes, + default: '', + }, + { + displayName: 'Authentication', + name: 'authentication', + type: 'hidden' as NodePropertyTypes, + default: 'body', + }, + ]; +} diff --git a/packages/nodes-base/nodes/Gitlab/GenericFunctions.ts b/packages/nodes-base/nodes/Gitlab/GenericFunctions.ts index 8f1811b8c7..4b91358b28 100644 --- a/packages/nodes-base/nodes/Gitlab/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Gitlab/GenericFunctions.ts @@ -6,6 +6,7 @@ import { import { IDataObject, } from 'n8n-workflow'; +import { OptionsWithUri } from 'request'; /** * Make an API request to Gitlab @@ -17,24 +18,43 @@ import { * @returns {Promise} */ export async function gitlabApiRequest(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: object, query?: object): Promise { // tslint:disable-line:no-any - const credentials = this.getCredentials('gitlabApi'); - if (credentials === undefined) { - throw new Error('No credentials got returned!'); - } - - const options = { + const options : OptionsWithUri = { method, - headers: { - 'Private-Token': `${credentials.accessToken}`, - }, + headers: {}, body, qs: query, - uri: `${(credentials.server as string).replace(/\/$/, '')}/api/v4${endpoint}`, + uri: '', json: true }; + if (query === undefined) { + delete options.qs; + } + + const authenticationMethod = this.getNodeParameter('authentication', 0); + try { - return await this.helpers.request(options); + if (authenticationMethod === 'accessToken') { + const credentials = this.getCredentials('gitlabApi'); + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + + options.headers!['Private-Token'] = `${credentials.accessToken}`; + + options.uri = `${(credentials.server as string).replace(/\/$/, '')}/api/v4${endpoint}`; + + return await this.helpers.request(options); + } else { + const credentials = this.getCredentials('gitlabOAuth2Api'); + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + + options.uri = `${(credentials.server as string).replace(/\/$/, '')}/api/v4${endpoint}`; + + return await this.helpers.requestOAuth2!.call(this, 'gitlabOAuth2Api', options); + } } catch (error) { if (error.statusCode === 401) { // Return a clear error diff --git a/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts b/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts index 39d71ae3da..920a2867ec 100644 --- a/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts +++ b/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts @@ -33,9 +33,44 @@ export class Gitlab implements INodeType { { name: 'gitlabApi', required: true, - } + displayOptions: { + show: { + authentication: [ + 'accessToken', + ], + }, + }, + }, + { + name: 'gitlabOAuth2Api', + required: true, + displayOptions: { + show: { + authentication: [ + 'oAuth2', + ], + }, + }, + }, ], properties: [ + { + displayName: 'Authentication', + name: 'authentication', + type: 'options', + options: [ + { + name: 'Access Token', + value: 'accessToken', + }, + { + name: 'OAuth2', + value: 'oAuth2', + }, + ], + default: 'accessToken', + description: 'The resource to operate on.', + }, { displayName: 'Resource', name: 'resource', @@ -793,10 +828,26 @@ export class Gitlab implements INodeType { const items = this.getInputData(); const returnData: IDataObject[] = []; - const credentials = this.getCredentials('gitlabApi'); + let credentials; - if (credentials === undefined) { - throw new Error('No credentials got returned!'); + const authenticationMethod = this.getNodeParameter('authentication', 0); + + try { + if (authenticationMethod === 'accessToken') { + credentials = this.getCredentials('gitlabApi'); + + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + } else { + credentials = this.getCredentials('gitlabOAuth2Api'); + + if (credentials === undefined) { + throw new Error('No credentials got returned!'); + } + } + } catch (error) { + throw new Error(error); } // Operations which overwrite the returned data diff --git a/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts b/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts index 28987c2458..a3e9b9ee2a 100644 --- a/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts +++ b/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts @@ -34,7 +34,25 @@ export class GitlabTrigger implements INodeType { { name: 'gitlabApi', required: true, - } + displayOptions: { + show: { + authentication: [ + 'accessToken', + ], + }, + }, + }, + { + name: 'gitlabOAuth2Api', + required: true, + displayOptions: { + show: { + authentication: [ + 'oAuth2', + ], + }, + }, + }, ], webhooks: [ { @@ -45,6 +63,23 @@ export class GitlabTrigger implements INodeType { }, ], properties: [ + { + displayName: 'Authentication', + name: 'authentication', + type: 'options', + options: [ + { + name: 'Access Token', + value: 'accessToken', + }, + { + name: 'OAuth2', + value: 'oAuth2', + }, + ], + default: 'accessToken', + description: 'The resource to operate on.', + }, { displayName: 'Repository Owner', name: 'owner', diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index dcfaeb2269..989cb0f055 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -56,6 +56,7 @@ "dist/credentials/GithubApi.credentials.js", "dist/credentials/GithubOAuth2Api.credentials.js", "dist/credentials/GitlabApi.credentials.js", + "dist/credentials/GitlabOAuth2Api.credentials.js", "dist/credentials/GoogleApi.credentials.js", "dist/credentials/GoogleCalendarOAuth2Api.credentials.js", "dist/credentials/GoogleDriveOAuth2Api.credentials.js", From 138a4d75189470859131fcd46d6db9f1d4ae057e Mon Sep 17 00:00:00 2001 From: ricardo Date: Thu, 23 Jul 2020 14:53:31 -0400 Subject: [PATCH 2/2] :zap: Small improvements --- packages/nodes-base/credentials/GitlabOAuth2Api.credentials.ts | 2 +- packages/nodes-base/nodes/Gitlab/Gitlab.node.ts | 1 - packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/nodes-base/credentials/GitlabOAuth2Api.credentials.ts b/packages/nodes-base/credentials/GitlabOAuth2Api.credentials.ts index 60cc091836..bfd7f5afbc 100644 --- a/packages/nodes-base/credentials/GitlabOAuth2Api.credentials.ts +++ b/packages/nodes-base/credentials/GitlabOAuth2Api.credentials.ts @@ -34,7 +34,7 @@ export class GitlabOAuth2Api implements ICredentialType { { displayName: 'Scope', name: 'scope', - type: 'string' as NodePropertyTypes, + type: 'hidden' as NodePropertyTypes, default: 'api', }, { diff --git a/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts b/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts index 920a2867ec..fa485e452a 100644 --- a/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts +++ b/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts @@ -13,7 +13,6 @@ import { gitlabApiRequest, } from './GenericFunctions'; - export class Gitlab implements INodeType { description: INodeTypeDescription = { displayName: 'Gitlab', diff --git a/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts b/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts index a3e9b9ee2a..fbb4c261e9 100644 --- a/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts +++ b/packages/nodes-base/nodes/Gitlab/GitlabTrigger.node.ts @@ -14,7 +14,6 @@ import { gitlabApiRequest, } from './GenericFunctions'; - export class GitlabTrigger implements INodeType { description: INodeTypeDescription = { displayName: 'Gitlab Trigger',