github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/facades/client/usermanager/register.go (about) 1 // Copyright 2022 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package usermanager 5 6 import ( 7 "reflect" 8 9 "github.com/juju/errors" 10 "github.com/juju/names/v5" 11 12 "github.com/juju/juju/apiserver/authentication" 13 "github.com/juju/juju/apiserver/common" 14 apiservererrors "github.com/juju/juju/apiserver/errors" 15 "github.com/juju/juju/apiserver/facade" 16 "github.com/juju/juju/core/permission" 17 ) 18 19 // Register is called to expose a package of facades onto a given registry. 20 func Register(registry facade.FacadeRegistry) { 21 registry.MustRegister("UserManager", 3, func(ctx facade.Context) (facade.Facade, error) { 22 return newUserManagerAPI(ctx) // Adds ModelUserInfo 23 }, reflect.TypeOf((*UserManagerAPI)(nil))) 24 } 25 26 // newUserManagerAPI provides the signature required for facade registration. 27 func newUserManagerAPI(ctx facade.Context) (*UserManagerAPI, error) { 28 authorizer := ctx.Auth() 29 if !authorizer.AuthClient() { 30 return nil, apiservererrors.ErrPerm 31 } 32 33 // Since we know this is a user tag (because AuthClient is true), 34 // we just do the type assertion to the UserTag. 35 apiUser, _ := authorizer.GetAuthTag().(names.UserTag) 36 // Pretty much all of the user manager methods have special casing for admin 37 // users, so look once when we start and remember if the user is an admin. 38 st := ctx.State() 39 err := authorizer.HasPermission(permission.SuperuserAccess, st.ControllerTag()) 40 if err != nil && !errors.Is(err, authentication.ErrorEntityMissingPermission) { 41 return nil, errors.Trace(err) 42 } 43 isAdmin := err == nil 44 45 return &UserManagerAPI{ 46 state: st, 47 pool: ctx.StatePool(), 48 authorizer: authorizer, 49 check: common.NewBlockChecker(st), 50 apiUser: apiUser, 51 isAdmin: isAdmin, 52 }, nil 53 }