Add support for token "NOT_NEEDED" for standalone plugins (#83)

This commit is contained in:
Simon Lecoq
2021-01-30 13:51:54 +01:00
committed by GitHub
parent 682e43e10b
commit b74f88a0ee
11 changed files with 42 additions and 11 deletions

View File

@@ -14,7 +14,7 @@
const info = (left, right, {token = false} = {}) => console.log(`${`${left}`.padEnd(56 + 9*(/0m$/.test(left)))}${
Array.isArray(right) ? right.join(", ") || "(none)" :
right === undefined ? "(default)" :
token ? /^MOCKED/.test(right) ? "(MOCKED TOKEN)" : (right ? "(provided)" : "(missing)") :
token ? /^MOCKED/.test(right) ? "(MOCKED TOKEN)" : /^NOT_NEEDED$/.test(right) ? "(NOT NEEDED)" : (right ? "(provided)" : "(missing)") :
typeof right === "object" ? JSON.stringify(right) :
right
}`)
@@ -62,7 +62,7 @@
//Docker image
if (_image)
info("Using prebuilt image", image)
info("Using prebuilt image", _image)
//Debug mode and flags
info("Debug mode", debug)
@@ -76,6 +76,7 @@
info("GitHub token", token, {token:true})
if (!token)
throw new Error("You must provide a valid GitHub token to gather your metrics")
conf.settings.token = token
const api = {}
api.graphql = octokit.graphql.defaults({headers:{authorization: `token ${token}`}})
info("Github GraphQL API", "ok")
@@ -179,7 +180,7 @@
//Register user inputs
if (enabled) {
info.break()
info.group({metadata, name, inputs:enabled ? inputs : {}})
info.group({metadata, name, inputs})
q[name] = true
for (const [key, value] of Object.entries(inputs)) {
//Store token in plugin configuration

View File

@@ -193,6 +193,9 @@
//Load metadata (plugins)
conf.metadata = await metadata({log})
//Set no token property
Object.defineProperty(conf.settings, "notoken", {get() { return conf.settings.token === "NOT_NEEDED" }})
//Conf
logger(`metrics/setup > setup > success`)
return {Templates, Plugins, conf}

View File

@@ -3,7 +3,7 @@
//Tested url
const tested = url.match(/&url=(?<tested>.*?)(?:&|$)/)?.groups?.tested ?? faker.internet.url()
//Pagespeed api
if (/^https:..www.googleapis.com.pagespeedonline.v5/.test(url)) {
if (/^https:..www.googleapis.com.pagespeedonline.v5.*$/.test(url)) {
//Pagespeed result
if (/v5.runPagespeed.*&key=MOCKED_TOKEN/.test(url)) {
console.debug(`metrics/compute/mocks > mocking pagespeed api result > ${url}`)

View File

@@ -1,7 +1,7 @@
/** Mocked data */
export default function ({faker, url, options, login = faker.internet.userName()}) {
//Spotify api
if (/^https:..api.spotify.com/.test(url)) {
if (/^https:..api.spotify.com.*$/.test(url)) {
//Get recently played tracks
if (/me.player.recently-played/.test(url)&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN_ACCESS")) {
console.debug(`metrics/compute/mocks > mocking spotify api result > ${url}`)

View File

@@ -1,7 +1,7 @@
/** Mocked data */
export default function ({faker, url, options, login = faker.internet.userName()}) {
//Twitter api
if (/^https:..api.twitter.com/.test(url)) {
if (/^https:..api.twitter.com.*$/.test(url)) {
//Get user profile
if ((/users.by.username/.test(url))&&(options?.headers?.Authorization === "Bearer MOCKED_TOKEN")) {
console.debug(`metrics/compute/mocks > mocking twitter api result > ${url}`)

View File

@@ -1,6 +1,6 @@
/** Mocked data */
export default function ({faker, url, body, login = faker.internet.userName()}) {
if (/^https:..graphql.anilist.co/.test(url)) {
if (/^https:..graphql.anilist.co.*$/.test(url)) {
//Initialization and media generator
const query = body.query
const media = ({type}) => ({

View File

@@ -3,7 +3,7 @@
/** Mocked data */
export default function ({faker, url, body, login = faker.internet.userName()}) {
if (/^https:..accounts.spotify.com.api.token/.test(url)) {
if (/^https:..accounts.spotify.com.api.token.*$/.test(url)) {
//Access token generator
const params = new urls.URLSearchParams(body)
if ((params.get("grant_type") === "refresh_token")&&(params.get("client_id") === "MOCKED_CLIENT_ID")&&(params.get("client_secret") === "MOCKED_CLIENT_SECRET")&&(params.get("refresh_token") === "MOCKED_REFRESH_TOKEN")) {

View File

@@ -72,8 +72,11 @@
const enabled = Object.entries(metadata).map(([name]) => ({name, enabled:plugins[name]?.enabled ?? false}))
const templates = Object.entries(Templates).map(([name]) => ({name, enabled:(conf.settings.templates.enabled.length ? conf.settings.templates.enabled.includes(name) : true) ?? false}))
const actions = {flush:new Map()}
let requests = (await rest.rateLimit.get()).data.rate
setInterval(async () => requests = (await rest.rateLimit.get()).data.rate, 30*1000)
let requests = {limit:0, used:0, remaining:0, reset:NaN}
if (!conf.settings.notoken) {
requests = (await rest.rateLimit.get()).data.rate
setInterval(async () => requests = (await rest.rateLimit.get()).data.rate, 30*1000)
}
//Web
app.get("/", limiter, (req, res) => res.sendFile(`${conf.paths.statics}/index.html`))
app.get("/index.html", limiter, (req, res) => res.sendFile(`${conf.paths.statics}/index.html`))

View File

@@ -9,6 +9,10 @@
console.debug(`metrics/compute/${login}/base > started`)
let {repositories, repositories_forks:forks} = imports.metadata.plugins.base.inputs({data, q, account:"bypass"}, {repositories:conf.settings.repositories ?? 100})
//Skip initial data gathering if not needed
if (conf.settings.notoken)
return (postprocess.skip({login, data}), {})
//Base parts (legacy handling for web instance)
const defaulted = ("base" in q) ? !!q.base : true
for (const part of conf.settings.plugins.base.parts)
@@ -85,5 +89,23 @@
issueComments:{totalCount:0},
organizations:{totalCount:0},
})
},
//Skip base content query and instantiate an empty user instance
skip({login, data}) {
data.user = {}
for (const account of ["user", "organization"])
postprocess?.[account]({login, data})
data.account = "bypass"
Object.assign(data.user, {
databaseId:0,
name:login,
login,
createdAt:new Date(),
avatarUrl:`https://github.com/${login}.png`,
websiteUrl:null,
twitterUsername:login,
repositories:{totalCount:0, totalDiskUsage:0, nodes:[]},
packages:{totalCount:0},
})
}
}

View File

@@ -90,7 +90,7 @@
computed.avatar = await avatar || "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
//Token scopes
computed.token.scopes = (await rest.request("HEAD /")).headers["x-oauth-scopes"].split(", ")
computed.token.scopes = conf.settings.notoken ? [] : (await rest.request("HEAD /")).headers["x-oauth-scopes"].split(", ")
//Meta
data.meta = {version:conf.package.version, author:conf.package.author}

View File

@@ -9,6 +9,8 @@ inputs:
# User account personal token
# No additional scopes are needed unless you want to include private repositories metrics
# Some plugins may also require additional scopes
# ────────────────────────────────────────────────────────────────
# If you're only using plugins which don't really require a GitHub token, you may pass "NOT_NEEDED" as value
token:
description: GitHub Personal Token
type: token