@@ -12,7 +12,6 @@ import (
1212 "github.com/gotify/server/v3/mode"
1313 "github.com/gotify/server/v3/model"
1414 "github.com/gotify/server/v3/test/testdb"
15- jmespath "github.com/jmespath-community/go-jmespath/pkg/api"
1615 "github.com/stretchr/testify/assert"
1716 "github.com/stretchr/testify/suite"
1817 "github.com/zitadel/oidc/v3/pkg/oidc"
@@ -231,7 +230,9 @@ func (s *OIDCSuite) Test_ResolveUser_CustomClaim() {
231230 assert .NotNil (s .T (), user .OIDCID )
232231}
233232
234- func (s * OIDCSuite ) Test_ResolveUser_NoRoleExpression () {
233+ func (s * OIDCSuite ) Test_ResolveUser_NoRBACResolver () {
234+ s .a .GroupsClaim = "roles"
235+
235236 info := & oidc.UserInfo {Subject : "sub-1" , Claims : map [string ]any {"preferred_username" : "test-user" , "roles" : []string {"tester" }}}
236237 user , status , err := s .a .resolveUser (testIssuer , info )
237238
@@ -242,10 +243,23 @@ func (s *OIDCSuite) Test_ResolveUser_NoRoleExpression() {
242243 assert .NotNil (s .T (), user .OIDCID )
243244}
244245
245- func (s * OIDCSuite ) Test_ResolveUser_AdminRoleExpression () {
246- role , err := jmespath .Compile ("contains(roles[*], 'admin') && 'Admin' || 'User'" )
246+ func (s * OIDCSuite ) Test_ResolveUser_NoRBACClaim () {
247+ // canary to proof that this resolver is never actually used
248+ s .a .RBACResolver = NewStaticRBACResolver (model .RoleAdmin )
249+
250+ info := & oidc.UserInfo {Subject : "sub-1" , Claims : map [string ]any {"preferred_username" : "test-user" , "roles" : []string {"tester" }}}
251+ user , status , err := s .a .resolveUser (testIssuer , info )
252+
247253 assert .NoError (s .T (), err )
248- s .a .RoleExpression = role
254+ assert .Equal (s .T (), 0 , status )
255+ assert .Equal (s .T (), "test-user" , user .Name )
256+ assert .Equal (s .T (), false , user .Admin )
257+ assert .NotNil (s .T (), user .OIDCID )
258+ }
259+
260+ func (s * OIDCSuite ) Test_ResolveUser_AdminRBACResolver () {
261+ s .a .GroupsClaim = "roles"
262+ s .a .RBACResolver = NewSimpleAdminRBACResolver ("admin" )
249263
250264 info := & oidc.UserInfo {Subject : "sub-1" , Claims : map [string ]any {"preferred_username" : "admin-user" , "roles" : []string {"admin" }}}
251265 user , status , err := s .a .resolveUser (testIssuer , info )
@@ -257,10 +271,9 @@ func (s *OIDCSuite) Test_ResolveUser_AdminRoleExpression() {
257271 assert .NotNil (s .T (), user .OIDCID )
258272}
259273
260- func (s * OIDCSuite ) Test_ResolveUser_UserRoleExpression () {
261- role , err := jmespath .Compile ("contains(roles[*], 'admin') && 'Admin' || 'User'" )
262- assert .NoError (s .T (), err )
263- s .a .RoleExpression = role
274+ func (s * OIDCSuite ) Test_ResolveUser_UserRBACResolver () {
275+ s .a .GroupsClaim = "roles"
276+ s .a .RBACResolver = NewSimpleAdminRBACResolver ("admin" )
264277
265278 info := & oidc.UserInfo {Subject : "sub-1" , Claims : map [string ]any {"preferred_username" : "test-user" , "roles" : []string {"tester" }}}
266279 user , status , err := s .a .resolveUser (testIssuer , info )
@@ -272,10 +285,9 @@ func (s *OIDCSuite) Test_ResolveUser_UserRoleExpression() {
272285 assert .NotNil (s .T (), user .OIDCID )
273286}
274287
275- func (s * OIDCSuite ) Test_ResolveUser_ForbiddenRoleExpression () {
276- role , err := jmespath .Compile ("contains(roles[*], 'gotify') && 'User' || 'None'" )
277- assert .NoError (s .T (), err )
278- s .a .RoleExpression = role
288+ func (s * OIDCSuite ) Test_ResolveUser_ForbiddenRBACResolver () {
289+ s .a .GroupsClaim = "roles"
290+ s .a .RBACResolver = NewSimpleUserRBACResolver ("users" )
279291
280292 info := & oidc.UserInfo {Subject : "sub-1" , Claims : map [string ]any {"preferred_username" : "test-user" , "roles" : []string {"tester" }}}
281293 _ , status , err := s .a .resolveUser (testIssuer , info )
@@ -284,34 +296,31 @@ func (s *OIDCSuite) Test_ResolveUser_ForbiddenRoleExpression() {
284296 assert .Equal (s .T (), 403 , status )
285297}
286298
287- func (s * OIDCSuite ) Test_ResolveUser_InvalidRoleExpression () {
288- role , err := jmespath .Compile ("contains(roles[*], 'gotify') && 'User' || 'FooBar'" )
289- assert .NoError (s .T (), err )
290- s .a .RoleExpression = role
299+ func (s * OIDCSuite ) Test_ResolveUser_GroupsClaimMissing () {
300+ s .a .GroupsClaim = "roles"
301+ s .a .RBACResolver = NewSimpleUserRBACResolver ("users" )
291302
292- info := & oidc.UserInfo {Subject : "sub-1" , Claims : map [string ]any {"preferred_username" : "test-user" , "roles" : [] string { "tester" } }}
303+ info := & oidc.UserInfo {Subject : "sub-1" , Claims : map [string ]any {"preferred_username" : "test-user" }}
293304 _ , status , err := s .a .resolveUser (testIssuer , info )
294305
295- assert .EqualError (s .T (), err , `role claim mapping error: invalid role "FooBar" ` )
306+ assert .EqualError (s .T (), err , `role claim mapping error: groups claim "roles" is missing ` )
296307 assert .Equal (s .T (), 500 , status )
297308}
298309
299- func (s * OIDCSuite ) Test_ResolveUser_MalformedRoleExpression () {
300- role , err := jmespath .Compile ("contains(roles[*], 'gotify')" )
301- assert .NoError (s .T (), err )
302- s .a .RoleExpression = role
310+ func (s * OIDCSuite ) Test_ResolveUser_MalformedRBACResolver () {
311+ s .a .GroupsClaim = "admin"
312+ s .a .RBACResolver = NewSimpleUserRBACResolver ("users" )
303313
304- info := & oidc.UserInfo {Subject : "sub-1" , Claims : map [string ]any {"preferred_username" : "test-user" , "roles " : [] string { "tester" } }}
314+ info := & oidc.UserInfo {Subject : "sub-1" , Claims : map [string ]any {"preferred_username" : "test-user" , "admin " : true }}
305315 _ , status , err := s .a .resolveUser (testIssuer , info )
306316
307- assert .EqualError (s .T (), err , `role claim mapping error: role claim expression expected string , got bool` )
317+ assert .EqualError (s .T (), err , `role claim mapping error: RBAC resolver expected strings , got bool` )
308318 assert .Equal (s .T (), 500 , status )
309319}
310320
311- func (s * OIDCSuite ) Test_ResolveUser_PromoteRoleExpression () {
312- role , err := jmespath .Compile ("contains(roles[*], 'admin') && 'Admin' || 'User'" )
313- assert .NoError (s .T (), err )
314- s .a .RoleExpression = role
321+ func (s * OIDCSuite ) Test_ResolveUser_PromoteRBACResolver () {
322+ s .a .GroupsClaim = "roles"
323+ s .a .RBACResolver = NewSimpleAdminRBACResolver ("admin" )
315324
316325 oidcID := testIssuer + "#sub-1"
317326 s .db .CreateUser (& model.User {ID : 1 , Name : "alice" , OIDCID : & oidcID })
@@ -328,10 +337,9 @@ func (s *OIDCSuite) Test_ResolveUser_PromoteRoleExpression() {
328337 assert .False (s .T (), s .notified )
329338}
330339
331- func (s * OIDCSuite ) Test_ResolveUser_DemoteRoleExpression () {
332- role , err := jmespath .Compile ("contains(roles[*], 'admin') && 'Admin' || 'User'" )
333- assert .NoError (s .T (), err )
334- s .a .RoleExpression = role
340+ func (s * OIDCSuite ) Test_ResolveUser_DemoteRBACResolver () {
341+ s .a .GroupsClaim = "roles"
342+ s .a .RBACResolver = NewSimpleAdminRBACResolver ("admin" )
335343
336344 oidcID := testIssuer + "#sub-1"
337345 s .db .CreateUser (& model.User {ID : 1 , Name : "alice" , Admin : true , OIDCID : & oidcID })
0 commit comments