root: migrate docker images to netlify proxy (#1603)
* migrate to netlify proxy Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * relative forward to func Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * custom logic for go paths Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix const Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * missing break Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add default for new repos Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
75
website/netlify/functions/oci-proxy.js
Normal file
75
website/netlify/functions/oci-proxy.js
Normal file
@ -0,0 +1,75 @@
|
||||
const config = {
|
||||
namespace: "goauthentik/",
|
||||
// Settings for GHCR
|
||||
registryTokenEndpoint: "https://ghcr.io/token",
|
||||
registryService: "ghcr.io",
|
||||
// Settings for Harbor
|
||||
// registryTokenEndpoint: "https://docker.beryju.org/service/token",
|
||||
// registryService: "harbor-registry",
|
||||
};
|
||||
|
||||
async function getToken(event) {
|
||||
const fetch = await import('node-fetch');
|
||||
const querystring = await import('querystring');
|
||||
let scope = event.queryStringParameters["scope"];
|
||||
let tokenParams = {
|
||||
service: config.registryService,
|
||||
};
|
||||
delete event.headers.host;
|
||||
let forwardHeaders = event.headers;
|
||||
if (scope && scope.includes(":")) {
|
||||
const repo = scope.split(":")[1];
|
||||
console.debug(`oci-proxy[token]: original scope: ${scope}`);
|
||||
scope = `repository:${config.namespace}${repo}:pull`;
|
||||
console.debug(`oci-proxy[token]: rewritten scope: ${scope}`);
|
||||
tokenParams["scope"] = scope;
|
||||
// We only need to forward headers for authentication requests
|
||||
forwardHeaders = {};
|
||||
} else {
|
||||
console.debug(`oci-proxy[token]: no scope`);
|
||||
// For non-scoped requests, we need to forward some URL parameters
|
||||
["account", "client_id", "offline_token", "token"].forEach(param => {
|
||||
tokenParams[param] = event.queryStringParameters[param]
|
||||
});
|
||||
}
|
||||
const tokenUrl = `${config.registryTokenEndpoint}?${querystring.stringify(tokenParams)}`
|
||||
console.debug(`oci-proxy[token]: final URL to fetch: ${tokenUrl}`)
|
||||
const tokenRes = await fetch.default(tokenUrl, {
|
||||
headers: forwardHeaders,
|
||||
});
|
||||
const tokenResult = await tokenRes.text();
|
||||
console.debug(`oci-proxy[token]: Status ${tokenRes.status} body '${tokenResult}'`)
|
||||
return {
|
||||
statusCode: tokenRes.status,
|
||||
body: tokenResult,
|
||||
};
|
||||
}
|
||||
|
||||
exports.handler = async function (event, context) {
|
||||
console.debug(`oci-proxy: URL ${event.httpMethod} ${event.rawUrl}`);
|
||||
if (event.queryStringParameters.hasOwnProperty("token")) {
|
||||
console.debug("oci-proxy: handler=token proxy");
|
||||
return await getToken(event);
|
||||
}
|
||||
if (event.headers.authorization && event.headers.authorization.startsWith("Bearer ")) {
|
||||
console.debug("oci-proxy: authenticated root handler, returning 200");
|
||||
return {
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
"Docker-Distribution-API-Version": "registry/2.0",
|
||||
"content-type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
}
|
||||
}
|
||||
console.debug("oci-proxy: root handler, returning 401 with www-authenticate");
|
||||
return {
|
||||
statusCode: 401,
|
||||
headers: {
|
||||
"www-authenticate": `Bearer realm="https://${event.headers.host}/v2?token",service="${event.headers.host}",scope="repository:user/image:pull"`,
|
||||
"Docker-Distribution-API-Version": "registry/2.0",
|
||||
"content-type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({}),
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user