forked from badges/shields
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgithub-constellation.js
More file actions
131 lines (113 loc) · 3.35 KB
/
Copy pathgithub-constellation.js
File metadata and controls
131 lines (113 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { AuthHelper } from '../../core/base-service/auth-helper.js'
import RedisTokenPersistence from '../../core/token-pooling/redis-token-persistence.js'
import log from '../../core/server/log.js'
import GithubApiProvider from './github-api-provider.js'
import { setRoutes as setAdminRoutes } from './auth/admin.js'
import { setRoutes as setAcceptorRoutes } from './auth/acceptor.js'
// Convenience class with all the stuff related to the Github API and its
// authorization tokens, to simplify server initialization.
class GithubConstellation {
static _createOauthHelper(config) {
return new AuthHelper(
{
userKey: 'gh_client_id',
passKey: 'gh_client_secret',
authorizedOrigins: ['https://api.github.com'],
isRequired: true,
},
config
)
}
constructor(config) {
this._debugEnabled = config.service.debug.enabled
this._debugIntervalSeconds = config.service.debug.intervalSeconds
this.shieldsSecret = config.private.shields_secret
const { redis_url: redisUrl, gh_token: globalToken } = config.private
if (redisUrl) {
log.log('Token persistence configured with redisUrl')
this.persistence = new RedisTokenPersistence({
url: redisUrl,
key: 'githubUserTokens',
})
}
this.apiProvider = new GithubApiProvider({
baseUrl: process.env.GITHUB_URL || 'https://api.github.com',
globalToken,
withPooling: !globalToken,
onTokenInvalidated: tokenString => this.onTokenInvalidated(tokenString),
})
this.oauthHelper = this.constructor._createOauthHelper(config)
}
scheduleDebugLogging() {
if (this._debugEnabled) {
this.debugInterval = setInterval(() => {
log.log(this.apiProvider.getTokenDebugInfo())
}, 1000 * this._debugIntervalSeconds)
}
}
async initialize(server) {
if (!this.apiProvider.withPooling) {
return
}
this.scheduleDebugLogging()
if (!this.persistence) {
return
}
let tokens = []
try {
tokens = await this.persistence.initialize()
} catch (e) {
log.error(e)
}
tokens.forEach(tokenString => {
this.apiProvider.addToken(tokenString)
})
const { shieldsSecret, apiProvider } = this
setAdminRoutes({ shieldsSecret }, { apiProvider, server })
if (this.oauthHelper.isConfigured) {
setAcceptorRoutes({
server,
authHelper: this.oauthHelper,
onTokenAccepted: tokenString => this.onTokenAdded(tokenString),
})
}
}
onTokenAdded(tokenString) {
if (!this.persistence) {
throw Error('Token persistence is not configured')
}
this.apiProvider.addToken(tokenString)
process.nextTick(async () => {
try {
await this.persistence.noteTokenAdded(tokenString)
} catch (e) {
log.error(e)
}
})
}
onTokenInvalidated(tokenString) {
if (this.persistence) {
process.nextTick(async () => {
try {
await this.persistence.noteTokenRemoved(tokenString)
} catch (e) {
log.error(e)
}
})
}
}
async stop() {
if (this.debugInterval) {
clearInterval(this.debugInterval)
this.debugInterval = undefined
}
if (this.persistence) {
try {
await this.persistence.stop()
} catch (e) {
log.error(e)
}
}
}
}
export default GithubConstellation