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  }