remove [github] admin routes (#7105)

This commit is contained in:
chris48s
2021-10-05 17:17:26 +01:00
committed by GitHub
parent 0054a4c30b
commit 0ce98396d7
10 changed files with 0 additions and 247 deletions

View File

@@ -93,7 +93,6 @@ private:
obs_pass: 'OBS_PASS'
redis_url: 'REDIS_URL'
sentry_dsn: 'SENTRY_DSN'
shields_secret: 'SHIELDS_SECRET'
sl_insight_userUuid: 'SL_INSIGHT_USER_UUID'
sl_insight_apiToken: 'SL_INSIGHT_API_TOKEN'
sonarqube_token: 'SONARQUBE_TOKEN'

View File

@@ -1,18 +0,0 @@
function constEq(a, b) {
if (a.length !== b.length) {
return false
}
let zero = 0
for (let i = 0; i < a.length; i++) {
zero |= a.charCodeAt(i) ^ b.charCodeAt(i)
}
return zero === 0
}
function makeSecretIsValid(shieldsSecret) {
return function secretIsValid(secret = '') {
return shieldsSecret && constEq(secret, shieldsSecret)
}
}
export { makeSecretIsValid }

View File

@@ -177,7 +177,6 @@ const privateConfigSchema = Joi.object({
obs_pass: Joi.string(),
redis_url: Joi.string().uri({ scheme: ['redis', 'rediss'] }),
sentry_dsn: Joi.string(),
shields_secret: Joi.string(),
sl_insight_userUuid: Joi.string(),
sl_insight_apiToken: Joi.string(),
sonarqube_token: Joi.string(),

View File

@@ -328,29 +328,6 @@ class TokenPool {
this.fifoQueue.forEach(visit)
this.priorityQueue.forEach(visit)
}
allValidTokenIds() {
const result = []
this.forEach(({ id }) => result.push(id))
return result
}
serializeDebugInfo({ sanitize = true } = {}) {
const maybeSanitize = sanitize ? id => sanitizeToken(id) : id => id
const priorityQueue = []
this.priorityQueue.forEach(t =>
priorityQueue.push(t.getDebugInfo({ sanitize }))
)
return {
utcEpochSeconds: getUtcEpochSeconds(),
allValidTokenIds: this.allValidTokenIds().map(maybeSanitize),
fifoQueue: this.fifoQueue.map(t => t.getDebugInfo({ sanitize })),
priorityQueue,
sanitized: sanitize,
}
}
}
export { sanitizeToken, Token, TokenPool }

View File

@@ -19,10 +19,6 @@ describe('The token pool', function () {
ids.forEach(id => tokenPool.add(id))
})
it('allValidTokenIds() should return the full list', function () {
expect(tokenPool.allValidTokenIds()).to.deep.equal(ids)
})
it('should yield the expected tokens', function () {
ids.forEach(id =>
times(batchSize, () => expect(tokenPool.next().id).to.equal(id))
@@ -38,67 +34,6 @@ describe('The token pool', function () {
)
})
describe('serializeDebugInfo should initially return the expected', function () {
beforeEach(function () {
sinon.useFakeTimers({ now: 1544307744484 })
})
afterEach(function () {
sinon.restore()
})
context('sanitize is not specified', function () {
it('returns fully sanitized results', function () {
// This is `sha()` of '1', '2', '3', '4', '5'. These are written
// literally for avoidance of doubt as to whether sanitization is
// happening.
const sanitizedIds = [
'6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b',
'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35',
'4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce',
'4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a',
'ef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39d',
]
expect(tokenPool.serializeDebugInfo()).to.deep.equal({
allValidTokenIds: sanitizedIds,
priorityQueue: [],
fifoQueue: sanitizedIds.map(id => ({
data: '[redacted]',
id,
isFrozen: false,
isValid: true,
nextReset: Token.nextResetNever,
usesRemaining: batchSize,
})),
sanitized: true,
utcEpochSeconds: 1544307744,
})
})
})
context('with sanitize: false', function () {
it('returns unsanitized results', function () {
expect(tokenPool.serializeDebugInfo({ sanitize: false })).to.deep.equal(
{
allValidTokenIds: ids,
priorityQueue: [],
fifoQueue: ids.map(id => ({
data: undefined,
id,
isFrozen: false,
isValid: true,
nextReset: Token.nextResetNever,
usesRemaining: batchSize,
})),
sanitized: false,
utcEpochSeconds: 1544307744,
}
)
})
})
})
context('tokens are marked exhausted immediately', function () {
it('should be exhausted', function () {
ids.forEach(() => {

View File

@@ -1,19 +0,0 @@
#!/usr/bin/env fish
#
# Back up the GitHub tokens from each production server.
#
if test (count $argv) -lt 1
echo Usage: (basename (status -f)) shields_secret
end
set shields_secret $argv[1]
function do_backup
set server $argv[1]
curl --insecure -u ":$shields_secret" "https://$server.servers.shields.io/\$github-auth/tokens" > "$server""_tokens.json"
end
for server in s0 s1 s2
do_backup $server
end

View File

@@ -1,32 +0,0 @@
import { makeSecretIsValid } from '../../../core/server/secret-is-valid.js'
function setRoutes({ shieldsSecret }, { apiProvider, server }) {
const secretIsValid = makeSecretIsValid(shieldsSecret)
// Allow the admin to obtain the tokens for operational and debugging
// purposes. This could be used to:
//
// - Ensure tokens have been propagated to all servers
// - Debug GitHub badge failures
//
// The admin can authenticate with HTTP Basic Auth, with an empty/any
// username and the shields secret in the password and an empty/any
// password.
//
// e.g.
// curl --insecure -u ':very-very-secret' 'https://img.shields.io/$github-auth/tokens'
server.ajax.on('github-auth/tokens', (json, end, ask) => {
if (!secretIsValid(ask.password)) {
// An unknown entity tries to connect. Let the connection linger for a minute.
return setTimeout(() => {
ask.res.statusCode = 401
ask.res.setHeader('Cache-Control', 'private')
end('Invalid secret.')
}, 10000)
}
ask.res.setHeader('Cache-Control', 'private')
end(apiProvider.serializeDebugInfo({ sanitize: false }))
})
}
export { setRoutes }

View File

@@ -1,71 +0,0 @@
import { expect } from 'chai'
import Camp from '@shields_io/camp'
import portfinder from 'portfinder'
import got from '../../../core/got-test-client.js'
import GithubApiProvider from '../github-api-provider.js'
import { setRoutes } from './admin.js'
describe('GitHub admin route', function () {
const shieldsSecret = '7'.repeat(40)
let port, baseUrl
before(async function () {
port = await portfinder.getPortPromise()
baseUrl = `http://127.0.0.1:${port}`
})
let camp
before(async function () {
camp = Camp.start({ port, hostname: '::' })
await new Promise(resolve => camp.on('listening', () => resolve()))
})
after(async function () {
if (camp) {
await new Promise(resolve => camp.close(resolve))
camp = undefined
}
})
before(function () {
const apiProvider = new GithubApiProvider({ withPooling: true })
setRoutes({ shieldsSecret }, { apiProvider, server: camp })
})
context('the password is correct', function () {
it('returns a valid JSON response', async function () {
const { statusCode, body, headers } = await got(
`${baseUrl}/$github-auth/tokens`,
{
username: '',
password: shieldsSecret,
responseType: 'json',
}
)
expect(statusCode).to.equal(200)
expect(body).to.be.ok
expect(headers['cache-control']).to.equal('private')
})
})
// Disabled because this code isn't modified often and the test is very
// slow. To run it, run `SLOW=true npm run test:core`
//
// I wasn't able to make this work with fake timers:
// https://github.com/sinonjs/sinon/issues/1739
if (process.env.SLOW) {
context('the password is missing', function () {
it('returns the expected message', async function () {
this.timeout(11000)
const { statusCode, body, headers } = await got(
`${baseUrl}/$github-auth/tokens`,
{
throwHttpErrors: false,
}
)
expect(statusCode).to.equal(401)
expect(body).to.equal('"Invalid secret."')
expect(headers['cache-control']).to.equal('private')
})
})
}
})

View File

@@ -54,18 +54,6 @@ class GithubApiProvider {
}
}
serializeDebugInfo({ sanitize = true } = {}) {
if (this.withPooling) {
return {
standardTokens: this.standardTokens.serializeDebugInfo({ sanitize }),
searchTokens: this.searchTokens.serializeDebugInfo({ sanitize }),
graphqlTokens: this.graphqlTokens.serializeDebugInfo({ sanitize }),
}
} else {
return {}
}
}
addToken(tokenString) {
if (this.withPooling) {
this.standardTokens.add(tokenString)

View File

@@ -2,7 +2,6 @@ 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
@@ -23,7 +22,6 @@ class GithubConstellation {
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) {
@@ -74,9 +72,6 @@ class GithubConstellation {
this.apiProvider.addToken(tokenString)
})
const { shieldsSecret, apiProvider } = this
setAdminRoutes({ shieldsSecret }, { apiProvider, server })
if (this.oauthHelper.isConfigured) {
setAcceptorRoutes({
server,