diff --git a/services/bots/src/cla-sign/cla-sign.controller.ts b/services/bots/src/cla-sign/cla-sign.controller.ts index b329459..979f2c2 100644 --- a/services/bots/src/cla-sign/cla-sign.controller.ts +++ b/services/bots/src/cla-sign/cla-sign.controller.ts @@ -5,6 +5,22 @@ import { ClaSignService, ServiceRequestError } from './cla-sign.service'; export class ClaSignController { constructor(private readonly claSignService: ClaSignService) {} + @Post('/authorize') + async authorize(@Body() payload: { code: string }): Promise { + if (!payload.code) { + throw new HttpException('Missing required data in payload', 400); + } + try { + return await this.claSignService.handleClaAuthorize(payload.code); + } catch (e) { + console.error(e); + if (e instanceof ServiceRequestError) { + throw new HttpException(e.message, 400); + } + throw e; + } + } + @Post() async webhook( @Headers() headers: Record, diff --git a/services/bots/src/cla-sign/cla-sign.service.ts b/services/bots/src/cla-sign/cla-sign.service.ts index b1c59b0..7f3ac4d 100644 --- a/services/bots/src/cla-sign/cla-sign.service.ts +++ b/services/bots/src/cla-sign/cla-sign.service.ts @@ -4,6 +4,7 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { createAppAuth } from '@octokit/auth-app'; import { DynamoDB } from 'aws-sdk'; +import fetch from 'node-fetch'; import { GithubClient } from '../github-webhook/github-webhook.model'; export class ServiceRequestError extends ServiceError {} @@ -14,6 +15,8 @@ export class ClaSignService { private ddbClient: DynamoDB; private signersTableName: string; private pendingSignersTableName: string; + private claSignId: string; + private claSignSecret: string; constructor(configService: ConfigService) { this.githubApiClient = new GithubClient({ @@ -29,6 +32,8 @@ export class ClaSignService { this.signersTableName = configService.get('dynamodb.cla.signersTable'); this.pendingSignersTableName = configService.get('dynamodb.cla.pendingSignersTable'); + this.claSignId = configService.get('github.claSignId'); + this.claSignSecret = configService.get('github.claSignSecret'); } async handleClaSignature( @@ -114,4 +119,27 @@ export class ClaSignService { labels: [ClaIssueLabel.CLA_RECHECK], }); } + + async handleClaAuthorize(code: string): Promise { + const params = new URLSearchParams({ + code, + client_id: this.claSignId, + client_secret: this.claSignSecret, + }); + + const resp = await fetch(`https://github.com/login/oauth/access_token?${params.toString()}`, { + method: 'POST', + headers: { + Accept: 'application/json', + }, + }); + const data = await resp.json(); + if (!resp.ok || 'error' in data) { + throw new ServiceError(data?.error_description || 'Could not authorize', { + data: { data }, + service: 'cla-sign-authorize', + }); + } + return data; + } } diff --git a/services/bots/src/config.ts b/services/bots/src/config.ts index 9a30501..46f13c7 100644 --- a/services/bots/src/config.ts +++ b/services/bots/src/config.ts @@ -40,6 +40,16 @@ const conf = convict({ env: 'GITHUB_WEBHOOK_SECRET', format: String, }, + claSignId: { + default: '', + env: 'GITHUB_CLA_SIGN_APP_ID', + format: String, + }, + claSignSecret: { + default: '', + env: 'GITHUB_CLA_SIGN_APP_SECRET', + format: String, + }, }, discord: { token: {