Skip to content
This repository was archived by the owner on Nov 15, 2024. It is now read-only.

Commit 5c41437

Browse files
committed
jira server and github enterprise support in progress
1 parent 045226e commit 5c41437

25 files changed

Lines changed: 317 additions & 56 deletions

File tree

api_server/bin/api_server.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ const SlackConfig = require(ConfigDirectory + '/slack');
2121
const MSTeamsConfig = require(ConfigDirectory + '/msteams');
2222
const GlipConfig = require(ConfigDirectory + '/glip');
2323
const GithubConfig = require(ConfigDirectory + '/github');
24+
const GithubEnterpriseConfig = require(ConfigDirectory + '/github_enterprise');
2425
const AsanaConfig = require(ConfigDirectory + '/asana');
2526
const TrelloConfig = require(ConfigDirectory + '/trello');
2627
const JiraConfig = require(ConfigDirectory + '/jira');
28+
const JiraServerConfig = require(ConfigDirectory + '/jiraserver');
2729
const BitbucketConfig = require(ConfigDirectory + '/bitbucket');
2830
const GitlabConfig = require(ConfigDirectory + '/gitlab');
2931
const YouTrackConfig = require(ConfigDirectory + '/youtrack');
@@ -91,9 +93,11 @@ const MyAPICluster = new ClusterWrapper(
9193
msteams: MSTeamsConfig,
9294
glip: GlipConfig,
9395
github: GithubConfig,
96+
github_enterprise: GithubEnterpriseConfig,
9497
asana: AsanaConfig,
9598
trello: TrelloConfig,
9699
jira: JiraConfig,
100+
jiraserver: JiraServerConfig,
97101
bitbucket: BitbucketConfig,
98102
gitlab: GitlabConfig,
99103
youtrack: YouTrackConfig,

api_server/config/api.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ ApiCfg.thirdPartyProviders = [
6666
'azuredevops',
6767
'bitbucket',
6868
'github',
69+
'github_enterprise',
6970
'gitlab',
7071
'jira',
72+
'jiraserver',
7173
'slack',
7274
'trello',
7375
'youtrack'
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// github enterprise integration configuration
2+
3+
'use strict';
4+
5+
module.exports = {};

api_server/config/jiraserver.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module.exports = {
2+
appConsumerKey: 'OauthKey',
3+
appClientSecret: `
4+
-----BEGIN PRIVATE KEY-----
5+
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANrGdJ4wo3DPRL7B
6+
hmWZmUBXox3X4Lt8MElcnPj7/IZmg242chWASt4+caSnru21M/Ok7qvWYOo9BgW0
7+
cNCGdAkbjuBvoo1aqkvVVxtTz3vaYPdUNmmz/tVHdcbZcQ2y/aNHVUhdVsLY6Gjg
8+
7dqlP+U8JMw2GfPRR9TANZLp2L4xAgMBAAECgYAWS7lg0cYmXgk8g46F1jSHGSdX
9+
iEOv98UYBOc+fLfMnq/wUH4p8MwwgB6m0CwEr73eq8VjH9L6rENr22rP5ZP3lWfx
10+
N4UfK65PjwutasfWvUzeT+vFuxO65AtHay+uYQfQAd6d/6tOvA/xNRGs15KF6oWn
11+
8CcgvKBHBaqz5BMQAQJBAPC2BccBX6XinlzfzBE92VUaoaJ0jtxAuak1feop0BMj
12+
hwGRMkDjPUx3B67Y/VZ9Q/YPoTFyin3C/bpew1zQcTECQQDoq8FYArMZVkp9vxUP
13+
FUZ8tD01zDeRC81b285+ZTFBUzqaX2ahLFQ+Q5DqOA3Sov1geDFZjORVb0/91sBE
14+
Id0BAkEA6eAxZNYU1NyG+b4ITIhHbcTeXzXYyG+q9Jkgqi/OF4phVkh5B0rC+FR+
15+
hogWPb6gFafB+oVLwj1+wWHpd3ifQQJAHcTD4v/NbGN2+mm1Rw3Ay/m/jx+GyH8L
16+
EkKoQ9GsoKAGcnPcTKjASosYgm8Tjaye4HXgUoXNPQUV5fNQ/CadAQJBALVnjYOP
17+
Gi5McQmiqEAHKViyRxaWSp8Z+s/HSS+2N0FPDWIGPxIP5r/q+OpBrxkgPrkZIB04
18+
f32eMhXFO3YroZE=
19+
-----END PRIVATE KEY-----
20+
`
21+
};
Lines changed: 84 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
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

55
const APIServerModule = require(process.env.CS_API_TOP + '/lib/api_server/api_server_module.js');
66
const fetch = require('node-fetch');
77
const FormData = require('form-data');
88
const 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;

api_server/modules/asana_auth/asana_auth.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
'use strict';
44

5-
const OAuth2Module = require(process.env.CS_API_TOP + '/lib/oauth2/oauth2_module.js');
5+
const OAuthModule = require(process.env.CS_API_TOP + '/lib/oauth/oauth_module.js');
66

77
const OAUTH_CONFIG = {
88
provider: 'asana',
@@ -16,7 +16,7 @@ const OAUTH_CONFIG = {
1616
hasIssues: true
1717
};
1818

19-
class AsanaAuth extends OAuth2Module {
19+
class AsanaAuth extends OAuthModule {
2020

2121
constructor (config) {
2222
super(config);

api_server/modules/azure_devops_auth/azure_devops_auth.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
'use strict';
44

5-
const OAuth2Module = require(process.env.CS_API_TOP + '/lib/oauth2/oauth2_module.js');
5+
const OAuthModule = require(process.env.CS_API_TOP + '/lib/oauth/oauth_module.js');
66

77
const OAUTH_CONFIG = {
88
provider: 'azuredevops',
@@ -31,7 +31,7 @@ const OAUTH_CONFIG = {
3131
needsConfigure: true
3232
};
3333

34-
class AzureDevOpsAuth extends OAuth2Module {
34+
class AzureDevOpsAuth extends OAuthModule {
3535

3636
constructor (config) {
3737
super(config);

api_server/modules/bitbucket_auth/bitbucket_auth.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
'use strict';
44

5-
const OAuth2Module = require(process.env.CS_API_TOP + '/lib/oauth2/oauth2_module.js');
5+
const OAuthModule = require(process.env.CS_API_TOP + '/lib/oauth/oauth_module.js');
66

77
const OAUTH_CONFIG = {
88
provider: 'bitbucket',
@@ -18,7 +18,7 @@ const OAUTH_CONFIG = {
1818
hasIssues: true
1919
};
2020

21-
class BitbucketAuth extends OAuth2Module {
21+
class BitbucketAuth extends OAuthModule {
2222

2323
constructor (config) {
2424
super(config);

api_server/modules/github_auth/github_auth.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
'use strict';
44

5-
const OAuth2Module = require(process.env.CS_API_TOP + '/lib/oauth2/oauth2_module.js');
5+
const OAuthModule = require(process.env.CS_API_TOP + '/lib/oauth/oauth_module.js');
66

77
const OAUTH_CONFIG = {
88
provider: 'github',
@@ -16,7 +16,7 @@ const OAUTH_CONFIG = {
1616
hasIssues: true
1717
};
1818

19-
class GithubAuth extends OAuth2Module {
19+
class GithubAuth extends OAuthModule {
2020

2121
constructor (config) {
2222
super(config);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// provide service to handle GitHub Enterprise credential authorization
2+
3+
'use strict';
4+
5+
const OAuthModule = require(process.env.CS_API_TOP + '/lib/oauth/oauth_module.js');
6+
7+
const OAUTH_CONFIG = {
8+
provider: 'github_enterprise',
9+
host: 'github.com/enterprise',
10+
authPath: 'login/oauth/authorize',
11+
tokenPath: 'login/oauth/access_token',
12+
exchangeFormat: 'query',
13+
scopes: 'repo,user',
14+
noGrantType: true,
15+
hasIssues: true,
16+
forEnterprise: true
17+
};
18+
19+
class GithubEnterpriseAuth extends OAuthModule {
20+
21+
constructor (config) {
22+
super(config);
23+
this.oauthConfig = OAUTH_CONFIG;
24+
}
25+
}
26+
27+
module.exports = GithubEnterpriseAuth;

0 commit comments

Comments
 (0)