Refactor and test [github] token persistence (#1863)

Ref #1848 #1205
This commit is contained in:
Paul Melnikow
2018-08-11 20:13:40 -04:00
committed by GitHub
parent 39d393028d
commit 9007658fd0
10 changed files with 212 additions and 59 deletions

View File

@@ -5,40 +5,21 @@ const log = require('./log')
const secretIsValid = require('./sys/secret-is-valid')
const queryString = require('query-string')
const request = require('request')
const autosave = require('json-autosave')
const serverSecrets = require('./server-secrets')
const mapKeys = require('lodash.mapkeys')
// This is an initial value which makes the code work while the initial data
// is loaded. In the then() callback of scheduleAutosaving(), it's reassigned
// with a JsonSave object.
let githubUserTokens = { data: [] }
const userTokenRateLimit = 12500
function scheduleAutosaving(githubUserTokensFile) {
autosave(githubUserTokensFile, { data: [] })
.then(save => {
githubUserTokens = save
for (let i = 0; i < githubUserTokens.data.length; i++) {
addGithubToken(githubUserTokens.data[i])
}
// Personal tokens allow access to GitHub private repositories.
// You can manage your personal GitHub token at
// <https://github.com/settings/tokens>.
if (serverSecrets && serverSecrets.gh_token) {
addGithubToken(serverSecrets.gh_token)
}
})
.catch(e => {
console.error('Could not create ' + githubUserTokensFile)
})
}
let githubUserTokens = []
// Ideally, we would want priority queues here.
const reqRemaining = new Map() // From token to requests remaining.
const reqReset = new Map() // From token to timestamp.
function cancelAutosaving() {
if (githubUserTokens.stop) {
githubUserTokens.stop()
githubUserTokens.save()
githubUserTokens = { data: [] }
}
// Personal tokens allow access to GitHub private repositories.
// You can manage your personal GitHub token at
// <https://github.com/settings/tokens>.
if (serverSecrets && serverSecrets.gh_token) {
addGithubToken(serverSecrets.gh_token)
}
function setRoutes(server) {
@@ -166,12 +147,6 @@ function sendTokenToAllServers(token) {
)
}
// Track rate limit requests remaining.
// Ideally, we would want priority queues here.
const reqRemaining = new Map() // From token to requests remaining.
const reqReset = new Map() // From token to timestamp.
// token: client token as a string.
// reqs: number of requests remaining.
// reset: timestamp when the number of remaining requests is reset.
@@ -189,8 +164,6 @@ function utcEpochSeconds() {
return (Date.now() / 1000) >>> 0
}
const userTokenRateLimit = 12500
// Return false if the token cannot reasonably be expected to perform
// a GitHub request.
function isTokenUsable(token, now) {
@@ -206,7 +179,7 @@ function isTokenUsable(token, now) {
// with a reasonable chance that the request will succeed.
function usableTokens() {
const now = utcEpochSeconds()
return githubUserTokens.data.filter(function(token) {
return githubUserTokens.filter(function(token) {
return isTokenUsable(token, now)
})
}
@@ -235,17 +208,17 @@ function addGithubToken(token) {
// A reset date of 0 has to be in the past.
setReqRemaining(token, userTokenRateLimit, 0)
// Insert it only if it is not registered yet.
if (githubUserTokens.data.indexOf(token) === -1) {
githubUserTokens.data.push(token)
if (githubUserTokens.indexOf(token) === -1) {
githubUserTokens.push(token)
}
}
function rmGithubToken(token) {
rmReqRemaining(token)
// Remove it only if it is in there.
const idx = githubUserTokens.data.indexOf(token)
const idx = githubUserTokens.indexOf(token)
if (idx >= 0) {
githubUserTokens.data.splice(idx, 1)
githubUserTokens.splice(idx, 1)
}
}
@@ -266,12 +239,20 @@ function sha(str) {
.digest('hex')
}
function getAllTokenIds() {
return githubUserTokens.slice()
}
function removeAllTokens() {
githubUserTokens = []
}
function serializeDebugInfo(options) {
// Apply defaults.
const { sanitize } = Object.assign({ sanitize: true }, options)
const unsanitized = {
tokens: githubUserTokens.data,
tokens: githubUserTokens,
reqRemaining: mapToObject(reqRemaining),
reqReset: mapToObject(reqReset),
utcEpochSeconds: utcEpochSeconds(),
@@ -347,9 +328,10 @@ function githubRequest(request, url, query, cb) {
}
module.exports = {
scheduleAutosaving,
cancelAutosaving,
request: githubRequest,
setRoutes,
serializeDebugInfo,
addGithubToken,
getAllTokenIds,
removeAllTokens,
}