github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/authentication/interfaces.go (about) 1 // Copyright 2014 Canonical Ltd. All rights reserved. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package authentication 5 6 import ( 7 "context" 8 "fmt" 9 "net/http" 10 11 "github.com/go-macaroon-bakery/macaroon-bakery/v3/bakery" 12 "github.com/juju/errors" 13 "github.com/juju/names/v5" 14 "gopkg.in/macaroon.v2" 15 16 "github.com/juju/juju/core/permission" 17 "github.com/juju/juju/state" 18 ) 19 20 // AuthInfoPermissions defined a type for a helper func that can answer 21 // questions an entity and what access they have on to a specific subject tag. 22 // 23 // It is up to the creator of the AuthInfo struct to provide a suitable 24 // implementation of this func. It's is for legacy reasons we allow querying of 25 // other entities besides the one focused on in the AuthInfo struct. 26 // 27 // TODO: tlm look at ways to gradually remove the Entity portion of this function 28 // so the question can only be asked of the one focuses on in the AuthInfo struct. 29 type AuthInfoPermissions func(Entity, names.Tag) (permission.Access, error) 30 31 // AuthInfo is returned by Authenticator and RequestAuthInfo. 32 type AuthInfo struct { 33 // Delegator is the interface back to the authenticating mechanism for 34 // helping with permission questions about the authed entity. 35 Delegator PermissionDelegator 36 37 // Entity is the user/machine/unit/etc that has authenticated. 38 Entity Entity 39 40 // PermissionsFn is a function that can return the permissions associated 41 // with the current AuthInfo. PermissionsFn should not be considered 42 // concurrency safe. 43 // PermissionsFn AuthInfoPermissions 44 45 // Controller reports whether or not the authenticated 46 // entity is a controller agent. 47 Controller bool 48 } 49 50 // AuthParams holds the info used to authenticate a login request. 51 type AuthParams struct { 52 // These are used for user or agent auth. 53 AuthTag names.Tag 54 Credentials string 55 56 // Token is used for rebac based auth. 57 Token string 58 59 // None is used for agent auth. 60 Nonce string 61 62 // These are used for macaroon auth. 63 Macaroons []macaroon.Slice 64 BakeryVersion bakery.Version 65 } 66 67 // PermissionDelegator is an interface that represents a window back into the 68 // original authentication method that generated an AuthInfo struct. Specifically 69 // it allows users of AuthInfo to ask specific details about an entity's 70 // permissions that needs response aligned with the way in which they were 71 // authenticated. 72 type PermissionDelegator interface { 73 // SubjectPermissions returns the permission the entity has for the 74 // specified subject. 75 SubjectPermissions(entity Entity, subject names.Tag) (permission.Access, error) 76 77 // PermissionError is a helper implemented by the Authenticator for 78 // returning the appropriate error when an authenticated entity is missing 79 // permission for subject. 80 PermissionError(subject names.Tag, permission permission.Access) error 81 } 82 83 // EntityAuthenticator is the interface all entity authenticators need to 84 // implement to authenticate juju entities. 85 type EntityAuthenticator interface { 86 // Authenticate authenticates the given entity. 87 Authenticate(ctx context.Context, entityFinder EntityFinder, authParams AuthParams) (state.Entity, error) 88 } 89 90 // Authorizer is a function type for authorizing a request. 91 // 92 // If this returns an error, the handler should return StatusForbidden. 93 type Authorizer interface { 94 Authorize(AuthInfo) error 95 } 96 97 // Entity represents a user, machine, or unit that might be 98 // authenticated. 99 type Entity interface { 100 Tag() names.Tag 101 } 102 103 // EntityFinder finds the entity described by the tag. 104 type EntityFinder interface { 105 FindEntity(tag names.Tag) (state.Entity, error) 106 } 107 108 // HTTPAuthenticator provides an interface for authenticating a raw http request 109 // from a client. 110 type HTTPAuthenticator interface { 111 // Authenticate authenticates the given request, returning the 112 // auth info. 113 // 114 // If the request does not contain any authentication details, 115 // then an error satisfying errors.Is(err, errors.NotFound) will be 116 // returned. 117 // If this returns an error that is not composable as HTTPWritableError then 118 // the handler should return StatusUnauthorized. 119 Authenticate(*http.Request) (AuthInfo, error) 120 } 121 122 // LoginAuthenticator provides an interface for authenticating RPC login 123 // requests from a client. 124 type LoginAuthenticator interface { 125 // AuthenticateLoginRequest authenticates a LoginRequest. 126 AuthenticateLoginRequest( 127 ctx context.Context, 128 serverHost string, 129 modelUUID string, 130 authParams AuthParams, 131 ) (AuthInfo, error) 132 } 133 134 // RequestAuthenticator is an interface the combines both the 135 // HTTPAuthenticator and LoginAuthenticator into a single interface as this 136 // functionality is most likely to be implemented together. 137 type RequestAuthenticator interface { 138 HTTPAuthenticator 139 LoginAuthenticator 140 } 141 142 // SubjectPermissions is a convenience wrapper around the AuthInfo permissions 143 // delegator. errors.NotImplemented is returned if the permission delegator 144 // on this AuthInfo is nil. 145 func (a *AuthInfo) SubjectPermissions(subject names.Tag) (permission.Access, error) { 146 if a.Delegator == nil { 147 return permission.NoAccess, fmt.Errorf("permissions delegator %w", errors.NotImplemented) 148 } 149 150 return a.Delegator.SubjectPermissions(a.Entity, subject) 151 }