From b130b8ae4f3afdd939379230749a6ebfe21bf556 Mon Sep 17 00:00:00 2001 From: ale Date: Sun, 9 Jun 2019 23:20:29 +0100 Subject: [PATCH] Add a new privileged user update API Currently only usable to set the user status. Currently the status changes are not propagated to owned resources. --- API.md | 13 ++++++++++++- actions_user.go | 30 ++++++++++++++++++++++++++++++ server/server.go | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/API.md b/API.md index b36e9fd..8133942 100644 --- a/API.md +++ b/API.md @@ -416,11 +416,22 @@ Non-authentication request attributes are all optional. Request parameters: -* `username` - user to fetch +* `username` - user to modify * `sso` - SSO ticket * `lang` - set the preferred language for this user * `u2f_registrations` - set the list of U2F registrations +### `/api/user/admin_update` + +A privileged version of the above (admin-only), that allows updates to +user status and other privileged internal attributes. + +Request parameters: + +* `username` - user to modify +* `sso` - SSO ticket +* `status` - if not empty, new user status + ### `/api/user/create` Create a new user (admin-only). Will also create all the resources diff --git a/actions_user.go b/actions_user.go index 6f2bd9f..3aae3ca 100644 --- a/actions_user.go +++ b/actions_user.go @@ -416,5 +416,35 @@ func (r *UpdateUserRequest) Serve(rctx *RequestContext) (interface{}, error) { rctx.User.Lang = r.Lang } + // TODO: check if setU2FRegistration calls tx.UpdateUser, this is a bug otherwise. return nil, rctx.User.setU2FRegistrations(rctx.Context, rctx.TX, r.U2FRegistrations) } + +// AdminUpdateUserRequest is the privileged version of UpdateUser and +// allows to update many more attributes. It is a catch-all function +// for very simple changes that don't justify their own specialized +// method. +type AdminUpdateUserRequest struct { + AdminUserRequestBase + Lang string `json:"lang,omitempty"` + Status string `json:"status"` +} + +// Validate the request. +func (r *AdminUpdateUserRequest) Validate(rctx *RequestContext) error { + switch r.Status { + case "", ResourceStatusActive, ResourceStatusInactive: + default: + return errors.New("invalid or unknown status") + } + return nil +} + +// Serve the request. +func (r *AdminUpdateUserRequest) Serve(rctx *RequestContext) (interface{}, error) { + if r.Status != "" { + rctx.User.Status = r.Status + } + + return nil, rctx.TX.UpdateUser(rctx.Context, &rctx.User.User) +} diff --git a/server/server.go b/server/server.go index cf4a72f..15f2047 100644 --- a/server/server.go +++ b/server/server.go @@ -51,6 +51,7 @@ func New(service *as.AccountService, backend as.Backend) *APIServer { s.Register("/api/user/search", &as.SearchUserRequest{}) s.Register("/api/user/create", &as.CreateUserRequest{}) s.Register("/api/user/update", &as.UpdateUserRequest{}) + s.Register("/api/user/admin_update", &as.AdminUpdateUserRequest{}) s.Register("/api/user/change_password", &as.ChangeUserPasswordRequest{}) s.Register("/api/user/set_account_recovery_hint", &as.SetAccountRecoveryHintRequest{}) s.Register("/api/user/enable_otp", &as.EnableOTPRequest{}) -- GitLab