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  }