feat: Users API, ownership transfer and removal of the legacy role string
This commit is contained in:
1 parent
094df63a7f
commit
80f7037d3a
124 files changed
+4644
-824
No files matched your search
@@ -60,57 +60,59 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
ActionLogin = "auth.login"
|
||||
ActionLoginFailed = "auth.login_failed"
|
||||
ActionLogout = "auth.logout"
|
||||
ActionPasswordResetRequest = "auth.password_reset_requested"
|
||||
ActionPasswordResetDone = "auth.password_reset_completed"
|
||||
ActionAPIKeyCreate = "api_key.create"
|
||||
ActionAPIKeyRevoke = "api_key.revoke"
|
||||
ActionRetentionChanged = "system.activity_retention_changed"
|
||||
ActionCleanup = "system.activity_cleanup"
|
||||
ActionArticleCreate = "article.create"
|
||||
ActionArticleEdit = "article.edit"
|
||||
ActionArticlePublish = "article.publish"
|
||||
ActionArticleUnpublish = "article.unpublish"
|
||||
ActionArticleDelete = "article.delete"
|
||||
ActionSiteCreate = "site.create"
|
||||
ActionSiteEdit = "site.edit"
|
||||
ActionSiteSetDefault = "site.set_default"
|
||||
ActionSiteDelete = "site.delete"
|
||||
ActionAuthorCreate = "author.create"
|
||||
ActionAuthorEdit = "author.edit"
|
||||
ActionAuthorDelete = "author.delete"
|
||||
ActionRoleCreate = "role.create"
|
||||
ActionRoleEdit = "role.edit"
|
||||
ActionRoleDelete = "role.delete"
|
||||
ActionRoleReassign = "role.reassign"
|
||||
ActionMediaUpload = "media.upload"
|
||||
ActionMediaRename = "media.rename"
|
||||
ActionMediaDelete = "media.delete"
|
||||
ActionMediaMerge = "media.merge"
|
||||
ActionMediaPurge = "media.purge"
|
||||
ActionVariantCreate = "media.variant_create"
|
||||
ActionVariantUpdate = "media.variant_update"
|
||||
ActionVariantDelete = "media.variant_delete"
|
||||
ActionVariantEnable = "media.variant_enable"
|
||||
ActionVariantDisable = "media.variant_disable"
|
||||
ActionVariantPurge = "media.variant_purge"
|
||||
ActionVariantGenerateAll = "media.variant_generate_all"
|
||||
ActionVariantPurgeImage = "media.variant_purge_image"
|
||||
ActionVariantPurgeAll = "media.variant_purge_all"
|
||||
ActionVariantPurgeUnused = "media.variant_purge_unused"
|
||||
ActionUserRegister = "user.register"
|
||||
ActionUserVerify = "user.verify"
|
||||
ActionUserUpdateProfile = "user.update_profile"
|
||||
ActionInviteCreate = "invite.create"
|
||||
ActionInviteCancel = "invite.cancel"
|
||||
ActionInviteRenew = "invite.renew"
|
||||
ActionInviteAccept = "invite.accept"
|
||||
ActionMediaPurgeScheduled = "system.media_purge"
|
||||
ActionUpdateChecked = "system.update_checked"
|
||||
ActionUpdateDownloaded = "system.update_downloaded"
|
||||
ActionRestartRequested = "system.restart_requested"
|
||||
ActionLogin = "auth.login"
|
||||
ActionLoginFailed = "auth.login_failed"
|
||||
ActionLogout = "auth.logout"
|
||||
ActionPasswordResetRequest = "auth.password_reset_requested"
|
||||
ActionPasswordResetDone = "auth.password_reset_completed"
|
||||
ActionAPIKeyCreate = "api_key.create"
|
||||
ActionAPIKeyRevoke = "api_key.revoke"
|
||||
ActionRetentionChanged = "system.activity_retention_changed"
|
||||
ActionCleanup = "system.activity_cleanup"
|
||||
ActionArticleCreate = "article.create"
|
||||
ActionArticleEdit = "article.edit"
|
||||
ActionArticlePublish = "article.publish"
|
||||
ActionArticleUnpublish = "article.unpublish"
|
||||
ActionArticleDelete = "article.delete"
|
||||
ActionSiteCreate = "site.create"
|
||||
ActionSiteEdit = "site.edit"
|
||||
ActionSiteSetDefault = "site.set_default"
|
||||
ActionSiteDelete = "site.delete"
|
||||
ActionAuthorCreate = "author.create"
|
||||
ActionAuthorEdit = "author.edit"
|
||||
ActionAuthorDelete = "author.delete"
|
||||
ActionRoleCreate = "role.create"
|
||||
ActionRoleEdit = "role.edit"
|
||||
ActionRoleDelete = "role.delete"
|
||||
ActionRoleReassign = "role.reassign"
|
||||
ActionMediaUpload = "media.upload"
|
||||
ActionMediaRename = "media.rename"
|
||||
ActionMediaDelete = "media.delete"
|
||||
ActionMediaMerge = "media.merge"
|
||||
ActionMediaPurge = "media.purge"
|
||||
ActionVariantCreate = "media.variant_create"
|
||||
ActionVariantUpdate = "media.variant_update"
|
||||
ActionVariantDelete = "media.variant_delete"
|
||||
ActionVariantEnable = "media.variant_enable"
|
||||
ActionVariantDisable = "media.variant_disable"
|
||||
ActionVariantPurge = "media.variant_purge"
|
||||
ActionVariantGenerateAll = "media.variant_generate_all"
|
||||
ActionVariantPurgeImage = "media.variant_purge_image"
|
||||
ActionVariantPurgeAll = "media.variant_purge_all"
|
||||
ActionVariantPurgeUnused = "media.variant_purge_unused"
|
||||
ActionUserRegister = "user.register"
|
||||
ActionUserVerify = "user.verify"
|
||||
ActionUserUpdateProfile = "user.update_profile"
|
||||
ActionUserChangeRole = "user.change_role"
|
||||
ActionUserTransferOwnership = "user.transfer_ownership"
|
||||
ActionInviteCreate = "invite.create"
|
||||
ActionInviteCancel = "invite.cancel"
|
||||
ActionInviteRenew = "invite.renew"
|
||||
ActionInviteAccept = "invite.accept"
|
||||
ActionMediaPurgeScheduled = "system.media_purge"
|
||||
ActionUpdateChecked = "system.update_checked"
|
||||
ActionUpdateDownloaded = "system.update_downloaded"
|
||||
ActionRestartRequested = "system.restart_requested"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -157,7 +159,10 @@ const (
|
||||
ParamChanged = "changed"
|
||||
ParamMembers = "members"
|
||||
ParamMoved = "moved"
|
||||
ParamRole = "role"
|
||||
ParamRoleID = "role_id"
|
||||
FieldTitle = "title"
|
||||
FieldRole = "role"
|
||||
FieldOnline = "online"
|
||||
FieldBody = "body"
|
||||
FieldFilename = "filename"
|
||||
|
||||
@@ -3,7 +3,6 @@ package builtintype
|
||||
import (
|
||||
"RenewCMS/internal/domain/article"
|
||||
"RenewCMS/internal/domain/contenttype"
|
||||
"RenewCMS/internal/domain/user"
|
||||
"errors"
|
||||
)
|
||||
|
||||
@@ -136,6 +135,6 @@ func userFields() []contenttype.Field {
|
||||
text("username", "Username").required(),
|
||||
text("display_name", "Display name"),
|
||||
text("email", "Email").required(),
|
||||
of("role", "Role", contenttype.TypeSelect).required().options(string(user.RoleOwner), string(user.RoleAdmin)),
|
||||
text("role", "Role"),
|
||||
)
|
||||
}
|
||||
@@ -31,6 +31,7 @@ type Invite struct {
|
||||
HashedCode string `json:"hashed_code"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
InvitedBy uint32 `json:"invited_by"`
|
||||
RoleID uint32 `json:"role_id"`
|
||||
AcceptedAt *time.Time `json:"accepted_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ var (
|
||||
ErrNotBuiltIn = errors.New("role is not built in")
|
||||
ErrInvalidReassign = errors.New("invalid reassign target")
|
||||
ErrEscalation = errors.New("grants more than the caller holds")
|
||||
ErrUnknownRole = errors.New("unknown role")
|
||||
)
|
||||
|
||||
type Scope string
|
||||
|
||||
@@ -9,4 +9,5 @@ type Repository interface {
|
||||
Delete(id uint32) error
|
||||
ReassignMembers(from uint32, to uint32) (int, error)
|
||||
RemoveTypedGrants(typeKey string) (int, error)
|
||||
MemberCounts() (map[uint32]int, error)
|
||||
}
|
||||
@@ -19,6 +19,9 @@ var ErrUsernameTaken = errors.New("username taken")
|
||||
var ErrInvalidLookup = errors.New("invalid user lookup")
|
||||
var ErrVerificationEmailNotSent = errors.New("verification email not sent")
|
||||
var ErrPasswordTooLong = errors.New("password too long")
|
||||
var ErrRoleChanged = errors.New("user role changed concurrently")
|
||||
var ErrInvalidTransfer = errors.New("invalid ownership transfer")
|
||||
var ErrConfirmationMismatch = errors.New("confirmation email does not match")
|
||||
|
||||
const MaxLookupIDs = 100
|
||||
|
||||
@@ -31,13 +34,6 @@ func ValidatePassword(password string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Role string
|
||||
|
||||
const (
|
||||
RoleOwner Role = "owner"
|
||||
RoleAdmin Role = "admin"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID uint32 `json:"id"`
|
||||
Username string `json:"username"`
|
||||
@@ -46,7 +42,6 @@ type User struct {
|
||||
Email string `json:"email"`
|
||||
DisplayName string `json:"display_name"`
|
||||
IsVerified bool `json:"is_verified"`
|
||||
Role Role `json:"role"`
|
||||
RoleID uint32 `json:"role_id"`
|
||||
VerificationCode string `json:"verification_code"`
|
||||
VerificationExpiration time.Time `json:"verification_expiration"`
|
||||
|
||||
@@ -16,4 +16,6 @@ type Repository interface {
|
||||
ClearVerificationCode(userId uint32) (User, error)
|
||||
ResetPassword(userId uint32, hashedPassword string) (User, error)
|
||||
UpdateDisplayName(userId uint32, displayName string) (User, error)
|
||||
UpdateRole(id uint32, from uint32, to uint32) (User, error)
|
||||
TransferOwnership(from uint32, to uint32, ownerRoleID uint32, formerRoleID uint32) error
|
||||
}
|
||||
Reference in new issue
Block a user