Per-host SSO: data model + normalization (#57)

Add Host fields sso_enabled / sso_allow_users / sso_allow_groups (empty
allow-lists = any authenticated user) and normalize them (parseAllowList). SSO
reuses conf.oidc and is OR'd with basic auth. Enforcement (session cookie + Lua
+ nginx auth location) lands separately. Unit tests included.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 12:01:54 -04:00
parent 42a00dd3bf
commit 653c79f099
3 changed files with 57 additions and 0 deletions
+23
View File
@@ -8,6 +8,7 @@ const {
parseBasicAuthLines,
sanitizeBasicAuthObject,
sanitizeRealm,
parseAllowList,
normalizeHostFeatures,
} = require('../../utils/host_features');
@@ -75,3 +76,25 @@ describe('normalizeHostFeatures (basic auth)', () => {
assert.deepStrictEqual(body.basicauth_users, {alice: 'secret'});
});
});
describe('SSO allow-lists (#57)', () => {
test('parseAllowList splits on commas/whitespace/newlines and dedupes', () => {
assert.deepStrictEqual(
parseAllowList('alice@x.com, bob@x.com\ncarol@x.com alice@x.com'),
['alice@x.com', 'bob@x.com', 'carol@x.com']
);
assert.deepStrictEqual(parseAllowList(['a', 'a', ' b ', '']), ['a', 'b']);
assert.deepStrictEqual(parseAllowList(''), []);
});
test('normalizeHostFeatures coerces sso_enabled and parses allow-lists', () => {
let body = {
sso_enabled: 'true',
sso_allow_users: 'alice@x.com\nbob@x.com',
sso_allow_groups: 'dns-team, admins',
};
normalizeHostFeatures(body);
assert.strictEqual(body.sso_enabled, true);
assert.deepStrictEqual(body.sso_allow_users, ['alice@x.com', 'bob@x.com']);
assert.deepStrictEqual(body.sso_allow_groups, ['dns-team', 'admins']);
});
});