mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-26 15:23:33 -06:00
[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
This commit is contained in:
parent
2f7d654380
commit
fd837776e2
12 changed files with 765 additions and 209 deletions
|
|
@ -100,13 +100,13 @@ func (c *Converter) UserToAPIUser(ctx context.Context, u *gtsmodel.User) *apimod
|
|||
return user
|
||||
}
|
||||
|
||||
// AppToAPIAppSensitive takes a db model application as a param, and returns a populated apitype application, or an error
|
||||
// AccountToAPIAccountSensitive takes a db model application as a param, and returns a populated apitype application, or an error
|
||||
// if something goes wrong. The returned application should be ready to serialize on an API level, and may have sensitive fields
|
||||
// (such as client id and client secret), so serve it only to an authorized user who should have permission to see it.
|
||||
func (c *Converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) {
|
||||
// We can build this sensitive account model
|
||||
// by first getting the public account, and
|
||||
// then adding the Source object to it.
|
||||
// then adding the Source object and role permissions bitmap to it.
|
||||
apiAccount, err := c.AccountToAPIAccountPublic(ctx, a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -122,6 +122,13 @@ func (c *Converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmode
|
|||
}
|
||||
}
|
||||
|
||||
// Populate the account's role permissions bitmap and highlightedness from its public role.
|
||||
if len(apiAccount.Roles) > 0 {
|
||||
apiAccount.Role = c.APIAccountDisplayRoleToAPIAccountRoleSensitive(&apiAccount.Roles[0])
|
||||
} else {
|
||||
apiAccount.Role = c.APIAccountDisplayRoleToAPIAccountRoleSensitive(nil)
|
||||
}
|
||||
|
||||
statusContentType := string(apimodel.StatusContentTypeDefault)
|
||||
if a.Settings.StatusContentType != "" {
|
||||
statusContentType = a.Settings.StatusContentType
|
||||
|
|
@ -299,7 +306,7 @@ func (c *Converter) accountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
|||
|
||||
var (
|
||||
acct string
|
||||
role *apimodel.AccountRole
|
||||
roles []apimodel.AccountDisplayRole
|
||||
enableRSS bool
|
||||
theme string
|
||||
customCSS string
|
||||
|
|
@ -324,14 +331,8 @@ func (c *Converter) accountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
|||
if err != nil {
|
||||
return nil, gtserror.Newf("error getting user from database for account id %s: %w", a.ID, err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case *user.Admin:
|
||||
role = &apimodel.AccountRole{Name: apimodel.AccountRoleAdmin}
|
||||
case *user.Moderator:
|
||||
role = &apimodel.AccountRole{Name: apimodel.AccountRoleModerator}
|
||||
default:
|
||||
role = &apimodel.AccountRole{Name: apimodel.AccountRoleUser}
|
||||
if role := c.UserToAPIAccountDisplayRole(user); role != nil {
|
||||
roles = append(roles, *role)
|
||||
}
|
||||
|
||||
enableRSS = *a.Settings.EnableRSS
|
||||
|
|
@ -380,7 +381,7 @@ func (c *Converter) accountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
|||
CustomCSS: customCSS,
|
||||
EnableRSS: enableRSS,
|
||||
HideCollections: hideCollections,
|
||||
Role: role,
|
||||
Roles: roles,
|
||||
}
|
||||
|
||||
// Bodge default avatar + header in,
|
||||
|
|
@ -391,6 +392,56 @@ func (c *Converter) accountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
|||
return accountFrontend, nil
|
||||
}
|
||||
|
||||
// UserToAPIAccountDisplayRole returns the API representation of a user's display role.
|
||||
// This will accept a nil user but does not always return a value:
|
||||
// the default "user" role is considered uninteresting and not returned.
|
||||
func (c *Converter) UserToAPIAccountDisplayRole(user *gtsmodel.User) *apimodel.AccountDisplayRole {
|
||||
switch {
|
||||
case user == nil:
|
||||
return nil
|
||||
case *user.Admin:
|
||||
return &apimodel.AccountDisplayRole{
|
||||
ID: string(apimodel.AccountRoleAdmin),
|
||||
Name: apimodel.AccountRoleAdmin,
|
||||
}
|
||||
case *user.Moderator:
|
||||
return &apimodel.AccountDisplayRole{
|
||||
ID: string(apimodel.AccountRoleModerator),
|
||||
Name: apimodel.AccountRoleModerator,
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// APIAccountDisplayRoleToAPIAccountRoleSensitive returns the API representation of a user's role,
|
||||
// with permission bitmap. This will accept a nil display role and always returns a value.
|
||||
func (c *Converter) APIAccountDisplayRoleToAPIAccountRoleSensitive(display *apimodel.AccountDisplayRole) *apimodel.AccountRole {
|
||||
// Default to user role.
|
||||
role := &apimodel.AccountRole{
|
||||
AccountDisplayRole: apimodel.AccountDisplayRole{
|
||||
ID: string(apimodel.AccountRoleUser),
|
||||
Name: apimodel.AccountRoleUser,
|
||||
},
|
||||
Permissions: apimodel.AccountRolePermissionsNone,
|
||||
Highlighted: false,
|
||||
}
|
||||
|
||||
// If there's a display role, use that instead.
|
||||
if display != nil {
|
||||
role.AccountDisplayRole = *display
|
||||
role.Highlighted = true
|
||||
switch display.Name {
|
||||
case apimodel.AccountRoleAdmin:
|
||||
role.Permissions = apimodel.AccountRolePermissionsForAdminRole
|
||||
case apimodel.AccountRoleModerator:
|
||||
role.Permissions = apimodel.AccountRolePermissionsForModeratorRole
|
||||
}
|
||||
}
|
||||
|
||||
return role
|
||||
}
|
||||
|
||||
func (c *Converter) fieldsToAPIFields(f []*gtsmodel.Field) []apimodel.Field {
|
||||
fields := make([]apimodel.Field, len(f))
|
||||
|
||||
|
|
@ -416,8 +467,8 @@ func (c *Converter) fieldsToAPIFields(f []*gtsmodel.Field) []apimodel.Field {
|
|||
// when someone wants to view an account they've blocked.
|
||||
func (c *Converter) AccountToAPIAccountBlocked(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) {
|
||||
var (
|
||||
acct string
|
||||
role *apimodel.AccountRole
|
||||
acct string
|
||||
roles []apimodel.AccountDisplayRole
|
||||
)
|
||||
|
||||
if a.IsRemote() {
|
||||
|
|
@ -438,14 +489,8 @@ func (c *Converter) AccountToAPIAccountBlocked(ctx context.Context, a *gtsmodel.
|
|||
if err != nil {
|
||||
return nil, gtserror.Newf("error getting user from database for account id %s: %w", a.ID, err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case *user.Admin:
|
||||
role = &apimodel.AccountRole{Name: apimodel.AccountRoleAdmin}
|
||||
case *user.Moderator:
|
||||
role = &apimodel.AccountRole{Name: apimodel.AccountRoleModerator}
|
||||
default:
|
||||
role = &apimodel.AccountRole{Name: apimodel.AccountRoleUser}
|
||||
if role := c.UserToAPIAccountDisplayRole(user); role != nil {
|
||||
roles = append(roles, *role)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -464,7 +509,7 @@ func (c *Converter) AccountToAPIAccountBlocked(ctx context.Context, a *gtsmodel.
|
|||
// Empty array (not nillable).
|
||||
Fields: make([]apimodel.Field, 0),
|
||||
Suspended: !a.SuspendedAt.IsZero(),
|
||||
Role: role,
|
||||
Roles: roles,
|
||||
}
|
||||
|
||||
// Don't show the account's actual
|
||||
|
|
@ -487,7 +532,7 @@ func (c *Converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Ac
|
|||
inviteRequest *string
|
||||
approved bool
|
||||
disabled bool
|
||||
role = apimodel.AccountRole{Name: apimodel.AccountRoleUser} // assume user by default
|
||||
role = *c.APIAccountDisplayRoleToAPIAccountRoleSensitive(nil)
|
||||
createdByApplicationID string
|
||||
)
|
||||
|
||||
|
|
@ -527,11 +572,9 @@ func (c *Converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Ac
|
|||
inviteRequest = &user.Reason
|
||||
}
|
||||
|
||||
if *user.Admin {
|
||||
role.Name = apimodel.AccountRoleAdmin
|
||||
} else if *user.Moderator {
|
||||
role.Name = apimodel.AccountRoleModerator
|
||||
}
|
||||
role = *c.APIAccountDisplayRoleToAPIAccountRoleSensitive(
|
||||
c.UserToAPIAccountDisplayRole(user),
|
||||
)
|
||||
|
||||
confirmed = !user.ConfirmedAt.IsZero()
|
||||
approved = *user.Approved
|
||||
|
|
|
|||
|
|
@ -68,10 +68,7 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontend() {
|
|||
"last_status_at": "2024-01-10T09:24:00.000Z",
|
||||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"enable_rss": true
|
||||
}`, string(b))
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +132,11 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendAliasedAndMoved()
|
|||
},
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
"id": "user",
|
||||
"name": "user",
|
||||
"color": "",
|
||||
"permissions": "0",
|
||||
"highlighted": false
|
||||
},
|
||||
"moved": {
|
||||
"id": "01F8MH5NBDF2MV7CTC4Q5128HF",
|
||||
|
|
@ -169,10 +170,7 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendAliasedAndMoved()
|
|||
"verified_at": null
|
||||
}
|
||||
],
|
||||
"hide_collections": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"hide_collections": true
|
||||
}
|
||||
}`, string(b))
|
||||
}
|
||||
|
|
@ -222,10 +220,7 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendWithEmojiStruct()
|
|||
}
|
||||
],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"enable_rss": true
|
||||
}`, string(b))
|
||||
}
|
||||
|
||||
|
|
@ -272,10 +267,7 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendWithEmojiIDs() {
|
|||
}
|
||||
],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"enable_rss": true
|
||||
}`, string(b))
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +313,11 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendSensitive() {
|
|||
},
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
"id": "user",
|
||||
"name": "user",
|
||||
"color": "",
|
||||
"permissions": "0",
|
||||
"highlighted": false
|
||||
}
|
||||
}`, string(b))
|
||||
}
|
||||
|
|
@ -494,9 +490,13 @@ func (suite *InternalToFrontendTestSuite) TestStatusToFrontend() {
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"media_attachments": [
|
||||
{
|
||||
|
|
@ -667,9 +667,13 @@ func (suite *InternalToFrontendTestSuite) TestWarnFilteredStatusToFrontend() {
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"media_attachments": [
|
||||
{
|
||||
|
|
@ -849,10 +853,7 @@ func (suite *InternalToFrontendTestSuite) TestWarnFilteredBoostToFrontend() {
|
|||
"last_status_at": "2024-01-10T09:24:00.000Z",
|
||||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"enable_rss": true
|
||||
},
|
||||
"media_attachments": [
|
||||
{
|
||||
|
|
@ -980,9 +981,13 @@ func (suite *InternalToFrontendTestSuite) TestWarnFilteredBoostToFrontend() {
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"media_attachments": [],
|
||||
"mentions": [],
|
||||
|
|
@ -1518,9 +1523,13 @@ func (suite *InternalToFrontendTestSuite) TestStatusToFrontendUnknownLanguage()
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"media_attachments": [
|
||||
{
|
||||
|
|
@ -1657,10 +1666,7 @@ func (suite *InternalToFrontendTestSuite) TestStatusToFrontendPartialInteraction
|
|||
"last_status_at": "2024-01-10T09:24:00.000Z",
|
||||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"enable_rss": true
|
||||
},
|
||||
"media_attachments": [],
|
||||
"mentions": [],
|
||||
|
|
@ -1853,9 +1859,13 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV1ToFrontend() {
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"max_toot_chars": 5000,
|
||||
"rules": [],
|
||||
|
|
@ -1989,9 +1999,13 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV2ToFrontend() {
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"rules": [],
|
||||
|
|
@ -2158,10 +2172,7 @@ func (suite *InternalToFrontendTestSuite) TestReportToFrontend2() {
|
|||
"verified_at": null
|
||||
}
|
||||
],
|
||||
"hide_collections": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"hide_collections": true
|
||||
}
|
||||
}`, string(b))
|
||||
}
|
||||
|
|
@ -2194,7 +2205,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
|
|||
"locale": "",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "user"
|
||||
"id": "user",
|
||||
"name": "user",
|
||||
"color": "",
|
||||
"permissions": "0",
|
||||
"highlighted": false
|
||||
},
|
||||
"confirmed": false,
|
||||
"approved": false,
|
||||
|
|
@ -2235,7 +2250,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
|
|||
"locale": "en",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "user"
|
||||
"id": "user",
|
||||
"name": "user",
|
||||
"color": "",
|
||||
"permissions": "0",
|
||||
"highlighted": false
|
||||
},
|
||||
"confirmed": true,
|
||||
"approved": true,
|
||||
|
|
@ -2274,10 +2293,7 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
|
|||
"verified_at": null
|
||||
}
|
||||
],
|
||||
"hide_collections": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"hide_collections": true
|
||||
},
|
||||
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
|
||||
},
|
||||
|
|
@ -2292,7 +2308,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
|
|||
"locale": "en",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": "",
|
||||
"permissions": "546033",
|
||||
"highlighted": true
|
||||
},
|
||||
"confirmed": true,
|
||||
"approved": true,
|
||||
|
|
@ -2321,9 +2341,13 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
|
||||
},
|
||||
|
|
@ -2338,7 +2362,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
|
|||
"locale": "en",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": "",
|
||||
"permissions": "546033",
|
||||
"highlighted": true
|
||||
},
|
||||
"confirmed": true,
|
||||
"approved": true,
|
||||
|
|
@ -2367,9 +2395,13 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
|
||||
},
|
||||
|
|
@ -2407,7 +2439,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend2() {
|
|||
"locale": "en",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "user"
|
||||
"id": "user",
|
||||
"name": "user",
|
||||
"color": "",
|
||||
"permissions": "0",
|
||||
"highlighted": false
|
||||
},
|
||||
"confirmed": true,
|
||||
"approved": true,
|
||||
|
|
@ -2446,10 +2482,7 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend2() {
|
|||
"verified_at": null
|
||||
}
|
||||
],
|
||||
"hide_collections": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"hide_collections": true
|
||||
},
|
||||
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
|
||||
},
|
||||
|
|
@ -2464,7 +2497,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend2() {
|
|||
"locale": "",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "user"
|
||||
"id": "user",
|
||||
"name": "user",
|
||||
"color": "",
|
||||
"permissions": "0",
|
||||
"highlighted": false
|
||||
},
|
||||
"confirmed": false,
|
||||
"approved": false,
|
||||
|
|
@ -2665,7 +2702,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
|
|||
"locale": "",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "user"
|
||||
"id": "user",
|
||||
"name": "user",
|
||||
"color": "",
|
||||
"permissions": "0",
|
||||
"highlighted": false
|
||||
},
|
||||
"confirmed": false,
|
||||
"approved": false,
|
||||
|
|
@ -2706,7 +2747,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
|
|||
"locale": "",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "user"
|
||||
"id": "user",
|
||||
"name": "user",
|
||||
"color": "",
|
||||
"permissions": "0",
|
||||
"highlighted": false
|
||||
},
|
||||
"confirmed": true,
|
||||
"approved": true,
|
||||
|
|
@ -2735,10 +2780,7 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"suspended": true,
|
||||
"hide_collections": true,
|
||||
"role": {
|
||||
"name": "user"
|
||||
}
|
||||
"hide_collections": true
|
||||
}
|
||||
},
|
||||
"assigned_account": {
|
||||
|
|
@ -2752,7 +2794,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
|
|||
"locale": "en",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": "",
|
||||
"permissions": "546033",
|
||||
"highlighted": true
|
||||
},
|
||||
"confirmed": true,
|
||||
"approved": true,
|
||||
|
|
@ -2781,9 +2827,13 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
|
||||
},
|
||||
|
|
@ -2798,7 +2848,11 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
|
|||
"locale": "en",
|
||||
"invite_request": null,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": "",
|
||||
"permissions": "546033",
|
||||
"highlighted": true
|
||||
},
|
||||
"confirmed": true,
|
||||
"approved": true,
|
||||
|
|
@ -2827,9 +2881,13 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
|
|||
"emojis": [],
|
||||
"fields": [],
|
||||
"enable_rss": true,
|
||||
"role": {
|
||||
"name": "admin"
|
||||
}
|
||||
"roles": [
|
||||
{
|
||||
"id": "admin",
|
||||
"name": "admin",
|
||||
"color": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue