mirror of
https://github.com/photoprism/photoprism.git
synced 2026-01-23 02:24:24 +00:00
Auth: Fix client role lookup in auth_session.go
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
b988ba046c
commit
1408e99135
2 changed files with 75 additions and 10 deletions
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize/english"
|
||||
|
|
@ -276,17 +277,25 @@ func (m *Session) GetClient() *Client {
|
|||
return &Client{}
|
||||
} else if m.client != nil {
|
||||
return m.client
|
||||
} else if c := FindClientByUID(m.ClientUID); c != nil {
|
||||
}
|
||||
|
||||
// Get client ID.
|
||||
uid := m.ClientUID
|
||||
|
||||
if c := FindClientByUID(uid); c != nil {
|
||||
m.SetClient(c)
|
||||
return m.client
|
||||
}
|
||||
|
||||
// Get client role.
|
||||
role := m.clientRole(false)
|
||||
|
||||
return &Client{
|
||||
UserUID: m.UserUID,
|
||||
UserName: m.UserName,
|
||||
ClientUID: m.ClientUID,
|
||||
ClientUID: uid,
|
||||
ClientName: m.GetClientName(),
|
||||
ClientRole: m.GetClientRole().String(),
|
||||
ClientRole: role.String(),
|
||||
AuthScope: m.Scope(),
|
||||
AuthMethod: m.AuthMethod,
|
||||
}
|
||||
|
|
@ -299,13 +308,7 @@ func (m *Session) GetClientName() string {
|
|||
|
||||
// GetClientRole returns the client ACL role.
|
||||
func (m *Session) GetClientRole() acl.Role {
|
||||
if m.HasClient() {
|
||||
return m.GetClient().AclRole()
|
||||
} else if m.IsClient() {
|
||||
return acl.RoleClient
|
||||
}
|
||||
|
||||
return acl.RoleNone
|
||||
return m.clientRole(true)
|
||||
}
|
||||
|
||||
// GetClientInfo returns the client identifier string.
|
||||
|
|
@ -338,6 +341,43 @@ func (m *Session) IsClient() bool {
|
|||
return authn.Provider(m.AuthProvider).IsClient()
|
||||
}
|
||||
|
||||
// clientRole resolves the client role for this session. When resolve is true it
|
||||
// may perform a one-time lookup via FindClientByUID; callers that already
|
||||
// depend on GetClientRole must pass resolve=false to avoid the recursive loop
|
||||
// that previously caused stack overflows between GetClient() and GetClientRole().
|
||||
func (m *Session) clientRole(resolve bool) acl.Role {
|
||||
if m == nil {
|
||||
return acl.RoleNone
|
||||
}
|
||||
|
||||
if c := m.client; c != nil {
|
||||
return c.AclRole()
|
||||
}
|
||||
|
||||
if !resolve {
|
||||
// Skip lookup to avoid recursive loop.
|
||||
} else if uid := m.ClientUID; uid != "" {
|
||||
if c := FindClientByUID(uid); c != nil {
|
||||
m.SetClient(c)
|
||||
return c.AclRole()
|
||||
}
|
||||
}
|
||||
|
||||
if m.IsClient() {
|
||||
if authn.MethodJWT.NotEqual(m.AuthMethod) {
|
||||
// Do nothing.
|
||||
} else if role, _, hasRole := strings.Cut(m.AuthIssuer, ":"); !hasRole {
|
||||
// Do nothing.
|
||||
} else if aclRole, roleFound := acl.ClientRoles[role]; roleFound {
|
||||
return aclRole
|
||||
}
|
||||
|
||||
return acl.RoleClient
|
||||
}
|
||||
|
||||
return acl.RoleNone
|
||||
}
|
||||
|
||||
// GetUser returns the related user entity.
|
||||
func (m *Session) GetUser() *User {
|
||||
if m == nil {
|
||||
|
|
|
|||
|
|
@ -349,6 +349,31 @@ func TestSession_ClientRole(t *testing.T) {
|
|||
m := &Session{}
|
||||
assert.Equal(t, acl.RoleNone, m.GetClientRole())
|
||||
})
|
||||
t.Run("MissingClientEntityPortal", func(t *testing.T) {
|
||||
m := &Session{
|
||||
ClientUID: "cs5cpu17n6gj2zzz",
|
||||
AuthProvider: authn.ProviderClient.String(),
|
||||
AuthMethod: authn.MethodJWT.String(),
|
||||
AuthIssuer: "portal:cbaa0276-07d3-43ac-b420-25e2601b0ad4",
|
||||
}
|
||||
|
||||
role := m.GetClientRole()
|
||||
assert.Equal(t, acl.RolePortal, role)
|
||||
client := m.GetClient()
|
||||
assert.Equal(t, "cs5cpu17n6gj2zzz", client.ClientUID)
|
||||
assert.Equal(t, acl.RolePortal, client.AclRole())
|
||||
})
|
||||
t.Run("MissingClientEntityDefault", func(t *testing.T) {
|
||||
m := &Session{
|
||||
ClientUID: "cs5cpu17n6gj2xxx",
|
||||
AuthProvider: authn.ProviderClient.String(),
|
||||
AuthMethod: authn.MethodJWT.String(),
|
||||
AuthIssuer: "https://example.com/oauth",
|
||||
}
|
||||
|
||||
role := m.GetClientRole()
|
||||
assert.Equal(t, acl.RoleClient, role)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSession_ClientInfo(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue