From f3842881838bb00fefdbcb6648fe878697b106f4 Mon Sep 17 00:00:00 2001 From: Eric Leijonmarck Date: Tue, 5 Oct 2021 13:07:16 +0100 Subject: [PATCH] AccessControl: Add displayname field to Role (#39904) * feat: add displayname * refactor: marshal role for fallback displayname * refactor: moved to private heuristic function for displaynames * refactor: display name trimspace and remove prefix * refactor: renaming of fallbackFunction * refactor: moved methods below struct types --- pkg/services/accesscontrol/models.go | 62 +++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/pkg/services/accesscontrol/models.go b/pkg/services/accesscontrol/models.go index ab6bc8cbba7..b882375a085 100644 --- a/pkg/services/accesscontrol/models.go +++ b/pkg/services/accesscontrol/models.go @@ -2,6 +2,7 @@ package accesscontrol import ( "encoding/json" + "strings" "time" ) @@ -19,16 +20,46 @@ type Role struct { Version int64 `json:"version"` UID string `xorm:"uid" json:"uid"` Name string `json:"name"` + DisplayName string `json:"displayName"` Description string `json:"description"` Updated time.Time `json:"updated"` Created time.Time `json:"created"` } +func (r Role) Global() bool { + return r.OrgID == GlobalOrgID +} + +func (r Role) IsFixed() bool { + return strings.HasPrefix(r.Name, FixedRolePrefix) +} + +func (r Role) GetDisplayName() string { + if r.IsFixed() && r.DisplayName == "" { + r.DisplayName = fallbackDisplayName(r.Name) + } + return r.DisplayName +} + +func (r Role) MarshalJSON() ([]byte, error) { + type Alias Role + + r.DisplayName = r.GetDisplayName() + return json.Marshal(&struct { + Alias + Global bool `json:"global" xorm:"-"` + }{ + Alias: (Alias)(r), + Global: r.Global(), + }) +} + type RoleDTO struct { Version int64 `json:"version"` UID string `xorm:"uid" json:"uid"` Name string `json:"name"` + DisplayName string `json:"displayName"` Description string `json:"description"` Permissions []Permission `json:"permissions,omitempty"` @@ -45,6 +76,7 @@ func (r RoleDTO) Role() Role { OrgID: r.OrgID, UID: r.UID, Name: r.Name, + DisplayName: r.DisplayName, Description: r.Description, Updated: r.Updated, Created: r.Created, @@ -55,12 +87,20 @@ func (r RoleDTO) Global() bool { return r.OrgID == GlobalOrgID } -func (r Role) Global() bool { - return r.OrgID == GlobalOrgID +func (r RoleDTO) IsFixed() bool { + return strings.HasPrefix(r.Name, FixedRolePrefix) +} + +func (r RoleDTO) GetDisplayName() string { + if r.IsFixed() && r.DisplayName == "" { + r.DisplayName = fallbackDisplayName(r.Name) + } + return r.DisplayName } func (r RoleDTO) MarshalJSON() ([]byte, error) { type Alias RoleDTO + return json.Marshal(&struct { Alias Global bool `json:"global" xorm:"-"` @@ -70,15 +110,15 @@ func (r RoleDTO) MarshalJSON() ([]byte, error) { }) } -func (r Role) MarshalJSON() ([]byte, error) { - type Alias Role - return json.Marshal(&struct { - Alias - Global bool `json:"global" xorm:"-"` - }{ - Alias: (Alias)(r), - Global: r.Global(), - }) +// fallbackDisplayName provides a fallback name for role +// that can be displayed in the ui for better readability +// example: currently this would give: +// fixed:datasources:name -> datasources name +// datasources:admin -> datasources admin +func fallbackDisplayName(rName string) string { + // removing prefix for fixed roles + rNameWithoutPrefix := strings.Replace(rName, FixedRolePrefix, "", 1) + return strings.TrimSpace(strings.Replace(rNameWithoutPrefix, ":", " ", -1)) } // Permission is the model for access control permissions.