mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-13 04:41:36 +00:00
Add configurable OIDC group-to-role mapping
Currently OIDC group-based role assignment only recognizes groups named 'admin', 'user', or 'guest' (case-insensitive), and denies login when a user's groups match none of them. This makes group-based roles unusable with identity providers whose group names differ, and offers no way to admit such users with a default role. Add two optional server settings: - authOpenIDAdminGroups: comma-separated group names mapped to the admin role, in addition to the built-in names. - authOpenIDGroupDefaultRole: role assigned when no group matches, instead of denying login. Both default to empty, preserving current behavior. Includes the auth settings UI fields, en-us strings, and unit tests for setUserGroup.
This commit is contained in:
parent
cbda0360aa
commit
d6cfdd3bec
5 changed files with 108 additions and 2 deletions
78
test/server/auth/OidcAuthStrategy.test.js
Normal file
78
test/server/auth/OidcAuthStrategy.test.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
const { expect } = require('chai')
|
||||
const sinon = require('sinon')
|
||||
|
||||
const Database = require('../../../server/Database')
|
||||
const Logger = require('../../../server/Logger')
|
||||
const OidcAuthStrategy = require('../../../server/auth/OidcAuthStrategy')
|
||||
|
||||
describe('OidcAuthStrategy', () => {
|
||||
let strategy
|
||||
let originalServerSettings
|
||||
|
||||
beforeEach(() => {
|
||||
strategy = new OidcAuthStrategy()
|
||||
originalServerSettings = Database.serverSettings
|
||||
sinon.stub(Logger, 'info')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
Database.serverSettings = originalServerSettings
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
const fakeUser = (type) => ({ type, username: 'tester', save: sinon.stub().resolves() })
|
||||
|
||||
describe('setUserGroup', () => {
|
||||
it('maps a configured admin group to the admin role', async () => {
|
||||
Database.serverSettings = { authOpenIDGroupClaim: 'groups', authOpenIDAdminGroups: 'syncloud', authOpenIDGroupDefaultRole: null }
|
||||
const user = fakeUser('user')
|
||||
|
||||
await strategy.setUserGroup(user, { groups: ['syncloud'] })
|
||||
|
||||
expect(user.type).to.equal('admin')
|
||||
expect(user.save.calledOnce).to.be.true
|
||||
})
|
||||
|
||||
it('still maps built-in role names when admin groups are configured', async () => {
|
||||
Database.serverSettings = { authOpenIDGroupClaim: 'groups', authOpenIDAdminGroups: 'syncloud', authOpenIDGroupDefaultRole: null }
|
||||
const user = fakeUser('guest')
|
||||
|
||||
await strategy.setUserGroup(user, { groups: ['User'] })
|
||||
|
||||
expect(user.type).to.equal('user')
|
||||
})
|
||||
|
||||
it('falls back to the default role when no group matches', async () => {
|
||||
Database.serverSettings = { authOpenIDGroupClaim: 'groups', authOpenIDAdminGroups: '', authOpenIDGroupDefaultRole: 'user' }
|
||||
const user = fakeUser('guest')
|
||||
|
||||
await strategy.setUserGroup(user, { groups: ['some-unrelated-group'] })
|
||||
|
||||
expect(user.type).to.equal('user')
|
||||
})
|
||||
|
||||
it('denies login when no group matches and no default role is set', async () => {
|
||||
Database.serverSettings = { authOpenIDGroupClaim: 'groups', authOpenIDAdminGroups: '', authOpenIDGroupDefaultRole: null }
|
||||
const user = fakeUser('user')
|
||||
|
||||
let error
|
||||
try {
|
||||
await strategy.setUserGroup(user, { groups: ['some-unrelated-group'] })
|
||||
} catch (e) {
|
||||
error = e
|
||||
}
|
||||
|
||||
expect(error).to.be.an('error')
|
||||
})
|
||||
|
||||
it('does nothing when no group claim is configured', async () => {
|
||||
Database.serverSettings = { authOpenIDGroupClaim: '' }
|
||||
const user = fakeUser('user')
|
||||
|
||||
await strategy.setUserGroup(user, { groups: ['syncloud'] })
|
||||
|
||||
expect(user.type).to.equal('user')
|
||||
expect(user.save.called).to.be.false
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue