Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When a global gh_token is configured, always use it #1118

Merged
merged 7 commits into from
Oct 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions doc/self-hosting.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,11 @@ then you will need to replace `localhost` with the IP address of that virtual
machine.

[shields.example.env]: ../shields.example.env


Server secrets
--------------

You can add your own server secrets in `private/secret.json`. If you specify a
`gh_token` for Github, it will be used in place of the Shields token rotation
logic.
23 changes: 14 additions & 9 deletions lib/github-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ const log = require('./log');
const queryString = require('query-string');
const request = require('request');
const autosave = require('json-autosave');
let serverSecrets;
const baseUrl = process.env.BASE_URL || 'https://img.shields.io';
try {
// Everything that cannot be checked in but is useful server-side
// is stored in this JSON data.
serverSecrets = require('../private/secret.json');
} catch(e) {}
const serverSecrets = require('./server-secrets');

// 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
Expand Down Expand Up @@ -44,6 +38,8 @@ function cancelAutosaving() {
}

function setRoutes(server) {
const baseUrl = process.env.BASE_URL || 'https://shields.io';

server.route(/^\/github-auth$/, function(data, match, end, ask) {
if (!(serverSecrets && serverSecrets.gh_client_id)) {
return end('This server is missing GitHub client secrets.');
Expand Down Expand Up @@ -229,6 +225,13 @@ function rmGithubToken(token) {
}
}

// When a global gh_token is configured, use that in place of our shields.io
// token-cycling logic. This produces more predictable behavior when a token
// is provided, and more predictable failures if that token is exhausted.
//
// You can manage your personal GitHub token at https://github.com/settings/tokens
const globalToken = (serverSecrets || {}).gh_token;

// Act like request(), but tweak headers and query to avoid hitting a rate
// limit.
function githubRequest(request, url, query, cb) {
Expand All @@ -239,7 +242,8 @@ function githubRequest(request, url, query, cb) {
'User-Agent': 'Shields.io',
'Accept': 'application/vnd.github.v3+json',
};
const githubToken = getReqRemainingToken();

const githubToken = globalToken === null ? getReqRemainingToken() : globalToken;

if (githubToken != null) {
// Typically, GitHub user tokens grants us 12500 req/hour.
Expand All @@ -253,8 +257,9 @@ function githubRequest(request, url, query, cb) {

const qs = queryString.stringify(query);
if (qs) { url += '?' + qs; }

request(url, {headers: headers}, function(err, res, buffer) {
if (githubToken != null && err === null) {
if (globalToken !== null && githubToken !== null && err === null) {
if (res.statusCode === 401) { // Unauthorized.
rmGithubToken(githubToken);
} else {
Expand Down