diff options
author | 2024-07-31 09:26:09 -0700 | |
---|---|---|
committer | 2024-07-31 09:26:09 -0700 | |
commit | fd837776e2aaf30f4ea973d65c9dfe0979988371 (patch) | |
tree | c2853d4bab55e1eccd91cbf48df4dd6279bc72d7 /internal/api/model | |
parent | [docs] Update system requirements, move things around a bit (#3157) (diff) | |
download | gotosocial-fd837776e2aaf30f4ea973d65c9dfe0979988371.tar.xz |
[feature] Implement Mastodon-compatible roles (#3136)
* Implement Mastodon-compatible roles
- `Account.role` should only be available through verify_credentials for checking current user's permissions
- `Account.role` now carries a Mastodon-compatible permissions bitmap and a marker for whether it should be shown to the public
- `Account.roles` added for *public* display roles (undocumented but stable since Mastodon 4.1)
- Web template now uses only public display roles (no user-visible change here, we already special-cased the `user` role)
* Handle verify_credentials case for default role
* Update JSON exact-match tests
* Address review comments
* Add blocks bit to admin permissions bitmap
Diffstat (limited to 'internal/api/model')
-rw-r--r-- | internal/api/model/account.go | 131 |
1 files changed, 130 insertions, 1 deletions
diff --git a/internal/api/model/account.go b/internal/api/model/account.go index c5b629db0..0eaf52734 100644 --- a/internal/api/model/account.go +++ b/internal/api/model/account.go @@ -18,8 +18,11 @@ package model import ( + "encoding/json" + "errors" "mime/multipart" "net" + "strconv" ) // Account models a fediverse account. @@ -105,8 +108,13 @@ type Account struct { // Key/value omitted if false. HideCollections bool `json:"hide_collections,omitempty"` // Role of the account on this instance. + // Only available through the `verify_credentials` API method. // Key/value omitted for remote accounts. Role *AccountRole `json:"role,omitempty"` + // Roles lists the public roles of the account on this instance. + // Unlike Role, this is always available, but never includes permissions details. + // Key/value omitted for remote accounts. + Roles []AccountDisplayRole `json:"roles,omitempty"` // If set, indicates that this account is currently inactive, and has migrated to the given account. // Key/value omitted for accounts that haven't moved, and for suspended accounts. Moved *Account `json:"moved,omitempty"` @@ -286,11 +294,35 @@ type AccountAliasRequest struct { AlsoKnownAsURIs []string `form:"also_known_as_uris" json:"also_known_as_uris" xml:"also_known_as_uris"` } +// AccountDisplayRole models a public, displayable role of an account. +// This is a subset of AccountRole. +// +// swagger:model accountDisplayRole +type AccountDisplayRole struct { + // ID of the role. + // Not used by GotoSocial, but we set it to the role name, just in case a client expects a unique ID. + ID string `json:"id"` + + // Name of the role. + Name AccountRoleName `json:"name"` + + // Color is a 6-digit CSS-style hex color code with leading `#`, or an empty string if this role has no color. + // Since GotoSocial doesn't use role colors, we leave this empty. + Color string `json:"color"` +} + // AccountRole models the role of an account. // // swagger:model accountRole type AccountRole struct { - Name AccountRoleName `json:"name"` + AccountDisplayRole + + // Permissions is a bitmap serialized as a numeric string, indicating which admin/moderation actions a user can perform. + Permissions AccountRolePermissions `json:"permissions"` + + // Highlighted indicates whether the role is publicly visible on the user profile. + // This is always true for GotoSocial's built-in admin and moderator roles, and false otherwise. + Highlighted bool `json:"highlighted"` } // AccountRoleName represent the name of the role of an account. @@ -305,6 +337,103 @@ const ( AccountRoleUnknown AccountRoleName = "" // We don't know / remote account ) +// AccountRolePermissions is a bitmap representing a set of user permissions. +// It's used for Mastodon API compatibility: internally, GotoSocial only tracks admins and moderators. +// +// swagger:type string +type AccountRolePermissions int + +// MarshalJSON serializes an AccountRolePermissions as a numeric string. +func (a *AccountRolePermissions) MarshalJSON() ([]byte, error) { + return json.Marshal(strconv.Itoa(int(*a))) +} + +// UnmarshalJSON deserializes an AccountRolePermissions from a number or numeric string. +func (a *AccountRolePermissions) UnmarshalJSON(b []byte) error { + if string(b) == "null" { + return nil + } + + i := 0 + if err := json.Unmarshal(b, &i); err != nil { + s := "" + if err := json.Unmarshal(b, &s); err != nil { + return errors.New("not a number or string") + } + + i, err = strconv.Atoi(s) + if err != nil { + return errors.New("not a numeric string") + } + } + + *a = AccountRolePermissions(i) + return nil +} + +const ( + // AccountRolePermissionsNone represents an empty set of permissions. + AccountRolePermissionsNone AccountRolePermissions = 0 + // AccountRolePermissionsAdministrator ignores all permission checks. + AccountRolePermissionsAdministrator AccountRolePermissions = 1 << (iota - 1) + // AccountRolePermissionsDevops is not used by GotoSocial. + AccountRolePermissionsDevops + // AccountRolePermissionsViewAuditLog is not used by GotoSocial. + AccountRolePermissionsViewAuditLog + // AccountRolePermissionsViewDashboard is not used by GotoSocial. + AccountRolePermissionsViewDashboard + // AccountRolePermissionsManageReports indicates that the user can view and resolve reports. + AccountRolePermissionsManageReports + // AccountRolePermissionsManageFederation indicates that the user can edit federation allows and blocks. + AccountRolePermissionsManageFederation + // AccountRolePermissionsManageSettings indicates that the user can edit instance metadata. + AccountRolePermissionsManageSettings + // AccountRolePermissionsManageBlocks indicates that the user can manage non-federation blocks, currently including HTTP header blocks. + AccountRolePermissionsManageBlocks + // AccountRolePermissionsManageTaxonomies is not used by GotoSocial. + AccountRolePermissionsManageTaxonomies + // AccountRolePermissionsManageAppeals is not used by GotoSocial. + AccountRolePermissionsManageAppeals + // AccountRolePermissionsManageUsers indicates that the user can view user details and perform user moderation actions. + AccountRolePermissionsManageUsers + // AccountRolePermissionsManageInvites is not used by GotoSocial. + AccountRolePermissionsManageInvites + // AccountRolePermissionsManageRules indicates that the user can edit instance rules. + AccountRolePermissionsManageRules + // AccountRolePermissionsManageAnnouncements is not used by GotoSocial. + AccountRolePermissionsManageAnnouncements + // AccountRolePermissionsManageCustomEmojis indicates that the user can edit custom emoji. + AccountRolePermissionsManageCustomEmojis + // AccountRolePermissionsManageWebhooks is not used by GotoSocial. + AccountRolePermissionsManageWebhooks + // AccountRolePermissionsInviteUsers is not used by GotoSocial. + AccountRolePermissionsInviteUsers + // AccountRolePermissionsManageRoles is not used by GotoSocial. + AccountRolePermissionsManageRoles + // AccountRolePermissionsManageUserAccess is not used by GotoSocial. + AccountRolePermissionsManageUserAccess + // AccountRolePermissionsDeleteUserData indicates that the user can permanently delete user data. + AccountRolePermissionsDeleteUserData + + // FUTURE: If we decide to assign our own permissions bits, + // they should start at the other end of the int to avoid conflicts with future Mastodon permissions. + + // AccountRolePermissionsForAdminRole includes all of the permissions assigned to GotoSocial's built-in administrator role. + AccountRolePermissionsForAdminRole = AccountRolePermissionsAdministrator | + AccountRolePermissionsManageReports | + AccountRolePermissionsManageFederation | + AccountRolePermissionsManageSettings | + AccountRolePermissionsManageBlocks | + AccountRolePermissionsManageUsers | + AccountRolePermissionsManageRules | + AccountRolePermissionsManageCustomEmojis | + AccountRolePermissionsDeleteUserData + + // AccountRolePermissionsForModeratorRole includes all of the permissions assigned to GotoSocial's built-in moderator role. + // (Currently, there aren't any.) + AccountRolePermissionsForModeratorRole = AccountRolePermissionsNone +) + // AccountNoteRequest models a request to update the private note for an account. // // swagger:ignore |