1- // provide service to handle OAuth2 based authorization
1+ // provide service to handle OAuth based authorization (either 1.0 or 2.0)
22
33'use strict' ;
44
55const APIServerModule = require ( process . env . CS_API_TOP + '/lib/api_server/api_server_module.js' ) ;
66const fetch = require ( 'node-fetch' ) ;
77const FormData = require ( 'form-data' ) ;
88const Base64 = require ( 'base-64' ) ;
9+ const OAuth = require ( 'oauth' ) . OAuth ;
910
10- class OAuth2Module extends APIServerModule {
11+ class OAuthModule extends APIServerModule {
1112
1213 services ( ) {
1314 const { provider } = this . oauthConfig ;
@@ -79,10 +80,21 @@ class OAuth2Module extends APIServerModule {
7980 return {
8081 host : host || this . oauthConfig . host ,
8182 clientId : clientInfo . appClientId ,
82- clientSecret : clientInfo . appClientSecret
83+ clientSecret : clientInfo . appClientSecret ,
84+ clientConsumerKey : clientInfo . appConsumerKey
8385 } ;
8486 }
8587
88+ // does this module use OAuth 1.0 (OAuth 2.0 is the default)
89+ usesOauth1 ( ) {
90+ return this . oauthConfig . usesOauth1 ;
91+ }
92+
93+ // return the path to use for the authorize step of OAuth 1.0
94+ getAuthorizePath ( ) {
95+ return this . oauthConfig . authorizePath ;
96+ }
97+
8698 // is an auth code for access token exchange required for this provider?
8799 exchangeRequired ( ) {
88100 return ! this . oauthConfig . noExchange ;
@@ -369,42 +381,39 @@ class OAuth2Module extends APIServerModule {
369381
370382 // get standard and enterprise instances linked to this third-party provider
371383 getInstances ( ) {
372- // get the standard instance, if configured
373- const standardInstances = [ ] ;
374- const standardInstance = this . getStandardInstance ( this . teams ) ;
375- if ( standardInstance ) {
376- standardInstances . push ( standardInstance ) ;
377- }
384+ // get the standard instances, if configured
385+ const standardInstance = this . getStandardInstance ( ) ;
378386
379387 // get any instances of enterprise hosts given by configuration
380- const enterpriseInstances = this . addInstancesByConfig ( this . enterpriseConfig ) ;
388+ const instances = this . addInstancesByConfig ( this . enterpriseConfig ) ;
381389
382- return [ ...standardInstances , ...enterpriseInstances ] ;
390+ if ( standardInstance ) {
391+ instances . push ( standardInstance ) ;
392+ }
393+ return instances ;
383394 }
384395
385396 // get the standard in-cloud instance of the third-party provider, if configured
386- getStandardInstance ( teams ) {
397+ getStandardInstance ( ) {
387398 const {
388399 host,
389400 provider,
390401 apiHost,
391402 hasIssues,
392- enterpriseOnly ,
403+ forEnterprise ,
393404 needsConfigure,
394405 disabled,
395406 acceptsUserDefinedToken
396407 } = this . oauthConfig ;
397- const integrationDisabled = disabled && ! ( teams || [ ] ) . find ( team => {
398- return ( team . get ( 'allowedDisabledIntegrations' ) || [ ] ) . includes ( provider ) ;
399- } ) ;
400- const { appClientId, apiKey } = this . apiConfig ;
401- if ( ! integrationDisabled && host && ( acceptsUserDefinedToken || enterpriseOnly || appClientId || apiKey ) ) {
408+ const { appClientId, appConsumerKey, apiKey } = this . apiConfig ;
409+ const hasKey = appClientId || appConsumerKey || apiKey ;
410+ if ( ! disabled && host && ( acceptsUserDefinedToken || forEnterprise || hasKey ) ) {
402411 const starredHost = host . toLowerCase ( ) . replace ( / \. / g, '*' ) ;
403412 return {
404413 id : starredHost ,
405414 name : provider ,
406415 isEnterprise : false ,
407- enterpriseOnly ,
416+ forEnterprise ,
408417 needsConfigure,
409418 host : host . toLowerCase ( ) ,
410419 apiHost : apiHost ? apiHost . toLowerCase ( ) : undefined ,
@@ -429,6 +438,61 @@ class OAuth2Module extends APIServerModule {
429438 } ) ;
430439 return instances ;
431440 }
441+
442+ // fetch a request token for modules using OAuth 1.0
443+ getRequestToken ( options ) {
444+ this . initOauth1AsNeeded ( options ) ;
445+ return new Promise ( ( resolve , reject ) => {
446+ this . oauth1Consumer . getOAuthRequestToken (
447+ ( error , oauthToken , oauthTokenSecret ) => {
448+ if ( error ) {
449+ reject ( error ) ;
450+ }
451+ else {
452+ resolve ( { oauthToken, oauthTokenSecret } ) ;
453+ }
454+ }
455+ ) ;
456+ } ) ;
457+ }
458+
459+ // fetch an access token for modules using OAuth 1.0, given an OAuth token obtained
460+ // from the provider-auth request
461+ async getOauth1AccessToken ( options ) {
462+ this . initOauth1AsNeeded ( options ) ;
463+ return new Promise ( ( resolve , reject ) => {
464+ this . oauth1Consumer . getOAuthAccessToken (
465+ options . oauthToken ,
466+ options . oauthTokenSecret ,
467+ null ,
468+ ( error , accessToken ) => {
469+ if ( error ) {
470+ reject ( error ) ;
471+ }
472+ else {
473+ resolve ( { accessToken } ) ;
474+ }
475+ }
476+ ) ;
477+ } ) ;
478+ }
479+
480+ // init an OAuth 1.0 client for the given client options, as needed
481+ initOauth1AsNeeded ( options ) {
482+ if ( this . oauth1Consumer ) { return ; }
483+ const clientInfo = this . getClientInfo ( options ) ;
484+ this . oauth1Consumer = new OAuth (
485+ `http://${ clientInfo . host } /${ this . oauthConfig . requestTokenPath } ` ,
486+ `http://${ clientInfo . host } /${ this . oauthConfig . accessTokenPath } ` ,
487+ clientInfo . clientConsumerKey ,
488+ clientInfo . clientSecret ,
489+ '1.0' ,
490+ null ,
491+ 'RSA-SHA1' ,
492+ null ,
493+ null
494+ ) ;
495+ }
432496}
433497
434- module . exports = OAuth2Module ;
498+ module . exports = OAuthModule ;
0 commit comments