oidc: make clients more dynamic

This commit is contained in:
Johannes Zellner
2023-03-14 14:58:09 +01:00
parent cef34bfbb7
commit b792fb97d6
2 changed files with 54 additions and 15 deletions
+50 -15
View File
@@ -2,6 +2,7 @@
exports = module.exports = {
getProvider,
upsertClient,
routes: {
renderInteractionPage,
interactionLogin,
@@ -23,6 +24,10 @@ const assert = require('assert'),
safe = require('safetydance'),
settings = require('./settings.js');
// currently non-persistent client store instead of .json file
// FIXME this has to go to our db
const gClients = {};
class CloudronAdapter {
/**
@@ -38,18 +43,24 @@ class CloudronAdapter {
*/
constructor(name) {
this.name = name;
this.fileStorePath = path.join(paths.OIDC_STORE_DIR, `${name}.json`);
debug(`Creating adapter for ${name} backed by ${this.fileStorePath}`);
if (name === 'Client') {
this.store = gClients;
this.fileStorePath = null;
} else {
this.fileStorePath = path.join(paths.OIDC_STORE_DIR, `${name}.json`);
let data = {};
try {
data = JSON.parse(fs.readFileSync(this.fileStorePath), 'utf8');
} catch (e) {
debug(`filestore for adapter ${name} not found, start with new one`);
debug(`Creating adapter for ${name} backed by ${this.fileStorePath}`);
let data = {};
try {
data = JSON.parse(fs.readFileSync(this.fileStorePath), 'utf8');
} catch (e) {
debug(`filestore for adapter ${name} not found, start with new one`);
}
this.store = data;
}
this.store = data;
}
/**
@@ -68,7 +79,7 @@ class CloudronAdapter {
debug(`[${this.name}] upsert id:${id} expiresIn:${expiresIn}`, payload);
this.store[id] = { id, expiresIn, payload, consumed: false };
fs.writeFileSync(this.fileStorePath, JSON.stringify(this.store), 'utf8');
if (this.fileStorePath) fs.writeFileSync(this.fileStorePath, JSON.stringify(this.store), 'utf8');
}
/**
@@ -86,6 +97,8 @@ class CloudronAdapter {
if (!this.store[id]) return false;
debug(`[${this.name}] find id:${id}`, this.store[id]);
return this.store[id].payload;
}
@@ -139,6 +152,8 @@ class CloudronAdapter {
debug(`[${this.name}] consume id:${id}`);
if (this.store[id]) this.store[id].consumed = true;
if (this.fileStorePath) fs.writeFileSync(this.fileStorePath, JSON.stringify(this.store), 'utf8');
}
/**
@@ -155,6 +170,8 @@ class CloudronAdapter {
debug(`[${this.name}] destroy id:${id}`);
delete this.store[id];
if (this.fileStorePath) fs.writeFileSync(this.fileStorePath, JSON.stringify(this.store), 'utf8');
}
/**
@@ -179,6 +196,24 @@ class CloudronAdapter {
}
}
async function upsertClient(provider, clientId, clientSecret, redirectUri) {
assert.strictEqual(typeof provider, 'object');
assert.strictEqual(typeof clientId, 'string');
assert.strictEqual(typeof clientSecret, 'string');
assert.strictEqual(typeof redirectUri, 'string');
debug(`upsertClient clientId:${clientId} clientSecret:${clientSecret} redirectUri:${redirectUri}`);
const payload = {
client_id: clientId,
client_secret: clientSecret,
redirect_uris: [ redirectUri ],
response_types: [ 'code id_token', 'code', 'id_token', 'none' ]
}
gClients[clientId] = { id: clientId, expiresIn: 0, payload, consumed: false };
}
function renderInteractionPage(routePrefix, provider) {
assert.strictEqual(typeof routePrefix, 'string');
assert.strictEqual(typeof provider, 'object');
@@ -411,11 +446,11 @@ async function getProvider(routePrefix) {
features: {
devInteractions: { enabled: false }
},
clients: [{
client_id: 'foo',
client_secret: 'bar',
redirect_uris: ['https://openidconnect.net/callback'],
}],
clients: [],
cookies: {
// FIXME https://github.com/panva/node-oidc-provider/blob/b1c1a9318036c2d3793cc9e668f99937c5c36bc6/lib/helpers/defaults.js#L770
keys: [ 'cookiesecret1', 'cookiesecret2' ]
},
pkce: {
required: function pkceRequired(ctx, client) {
return false;