Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion config/facs/auth.config.json.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"a0": {
"superAdmin": "test@localhost",
"ttl": 86400,
"ttl": 900,
"jwtSecret": "REPLACE_WITH_LONG_RANDOM_HEX_SECRET",
"saltRounds": 10,
"superAdminPerms": [
"miner:rw",
Expand Down
25 changes: 7 additions & 18 deletions tests/unit/lib/auth.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,7 @@ test('AuthLib - getTokenPerms with super admin', async (t) => {
test('AuthLib - getTokenPerms with regular user', async (t) => {
const mockAuth = {
getTokenPerms: function (token) {
return { superadmin: false, perms: ['actions:r', 'miner:r'] }
},
tokenHasPerms: async (token, perm) => {
return perm === 'actions:w'
return { superadmin: false, perms: ['actions:rw', 'miner:r'] }
},
conf: {
superAdminPerms: []
Expand Down Expand Up @@ -262,7 +259,6 @@ test('AuthLib - tokenHasPerms with super admin', async (t) => {
getTokenPerms: function () {
return { superadmin: true, perms: [] }
},
tokenHasPerms: async () => false,
conf: {
superAdminPerms: []
}
Expand All @@ -274,7 +270,7 @@ test('AuthLib - tokenHasPerms with super admin', async (t) => {
auth: mockAuth
})

const result = await authLib.tokenHasPerms('token', true, ['perm1', 'perm2'])
const result = await authLib.tokenHasPerms('token', true, ['perm1:r', 'perm2:r'])

t.is(result, true, 'should return true for super admin')

Expand All @@ -286,7 +282,6 @@ test('AuthLib - tokenHasPerms without write permission', async (t) => {
getTokenPerms: function () {
return { superadmin: false, perms: [] }
},
tokenHasPerms: async () => false,
conf: {
superAdminPerms: []
}
Expand All @@ -298,7 +293,7 @@ test('AuthLib - tokenHasPerms without write permission', async (t) => {
auth: mockAuth
})

const result = await authLib.tokenHasPerms('token', true, ['perm1'])
const result = await authLib.tokenHasPerms('token', true, ['perm1:r'])

t.is(result, false, 'should return false when write required but not available')

Expand All @@ -308,10 +303,7 @@ test('AuthLib - tokenHasPerms without write permission', async (t) => {
test('AuthLib - tokenHasPerms with matchAll=true', async (t) => {
const mockAuth = {
getTokenPerms: function () {
return { superadmin: false, perms: [] }
},
tokenHasPerms: async (token, perm) => {
return perm === 'perm1'
return { superadmin: false, perms: ['perm1:r'] }
},
conf: {
superAdminPerms: []
Expand All @@ -324,7 +316,7 @@ test('AuthLib - tokenHasPerms with matchAll=true', async (t) => {
auth: mockAuth
})

const result = await authLib.tokenHasPerms('token', false, ['perm1', 'perm2'], true)
const result = await authLib.tokenHasPerms('token', false, ['perm1:r', 'perm2:r'], true)

t.is(result, false, 'should return false when matchAll and not all perms match')

Expand All @@ -334,10 +326,7 @@ test('AuthLib - tokenHasPerms with matchAll=true', async (t) => {
test('AuthLib - tokenHasPerms with matchAll=false', async (t) => {
const mockAuth = {
getTokenPerms: function () {
return { superadmin: false, perms: [] }
},
tokenHasPerms: async (token, perm) => {
return perm === 'perm1'
return { superadmin: false, perms: ['perm1:r'] }
},
conf: {
superAdminPerms: []
Expand All @@ -350,7 +339,7 @@ test('AuthLib - tokenHasPerms with matchAll=false', async (t) => {
auth: mockAuth
})

const result = await authLib.tokenHasPerms('token', false, ['perm1', 'perm2'], false)
const result = await authLib.tokenHasPerms('token', false, ['perm1:r', 'perm2:r'], false)

t.is(result, true, 'should return true when matchAll=false and at least one perm matches')

Expand Down
10 changes: 8 additions & 2 deletions workers/lib/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ class AuthLib {
this._auth = auth
}

_permsMatch (perms, perm) {
const [key, required] = perm.split(':')
const av = perms.find(p => p.startsWith(`${key}:`))?.split(':')[1] ?? ''
return [...required].every(c => av.includes(c))
}

async migrateUsers (httpdAuth) {
const users = await this._auth.listUsers()
if (users.length > 1) {
Expand Down Expand Up @@ -64,7 +70,7 @@ class AuthLib {

async getTokenPerms (token) {
const { superadmin: superAdmin, perms = [] } = this._auth.getTokenPerms(token)
const write = superAdmin || (await this._auth.tokenHasPerms(token, 'actions:w'))
const write = superAdmin || this._permsMatch(perms, 'actions:w')
const applicablePerms = superAdmin ? (this._auth.conf.superAdminPerms ?? []) : perms
const caps = applicablePerms.map(perm => perm.split(':')[0])

Expand All @@ -81,7 +87,7 @@ class AuthLib {
return false
}

const resolved = await Promise.all(requestedPerms.map(perm => this._auth.tokenHasPerms(token, perm)))
const resolved = requestedPerms.map(perm => this._permsMatch(perms.permissions, perm))

return matchAll
? resolved.every(res => res)
Expand Down
Loading