github.com/annwntech/go-micro/v2@v2.9.5/auth/auth.go (about)

     1  // Package auth provides authentication and authorization capability
     2  package auth
     3  
     4  import (
     5  	"context"
     6  	"errors"
     7  	"time"
     8  )
     9  
    10  var (
    11  	// ErrInvalidToken is when the token provided is not valid
    12  	ErrInvalidToken = errors.New("invalid token provided")
    13  	// ErrForbidden is when a user does not have the necessary scope to access a resource
    14  	ErrForbidden = errors.New("resource forbidden")
    15  )
    16  
    17  const (
    18  	// BearerScheme used for Authorization header
    19  	BearerScheme = "Bearer "
    20  	// TokenCookieName is the name of the cookie which stores the auth token
    21  	TokenCookieName = "micro-token"
    22  	// ScopePublic is the scope applied to a rule to allow access to the public
    23  	ScopePublic = ""
    24  	// ScopeAccount is the scope applied to a rule to limit to users with any valid account
    25  	ScopeAccount = "*"
    26  )
    27  
    28  // Account provided by an auth provider
    29  type Account struct {
    30  	// ID of the account e.g. UUID. Should not change
    31  	ID string `json:"id"`
    32  	// Type of the account, e.g. service
    33  	Type string `json:"type"`
    34  	// Issuer of the account
    35  	Issuer string `json:"issuer"`
    36  	// Any other associated metadata
    37  	Metadata map[string]string `json:"metadata"`
    38  	// Scopes the account has access to
    39  	Scopes []string `json:"scopes"`
    40  	// Secret for the account, e.g. the password
    41  	Secret string `json:"secret"`
    42  	// Name of the account. User friendly name that might change e.g. a username or email
    43  	Name string `json:"name"`
    44  }
    45  
    46  // AuthTokne can be short or long lived
    47  type AuthToken struct {
    48  	// The token to be used for accessing resources
    49  	AccessToken string `json:"access_token"`
    50  	// RefreshToken to be used to generate a new token
    51  	RefreshToken string `json:"refresh_token"`
    52  	// Time of token creation
    53  	Created time.Time `json:"created"`
    54  	// Time of token expiry
    55  	Expiry time.Time `json:"expiry"`
    56  }
    57  
    58  // Expired returns a boolean indicating if the token needs to be refreshed
    59  func (t *AuthToken) Expired() bool {
    60  	return t.Expiry.Unix() < time.Now().Unix()
    61  }
    62  
    63  // Resource is an entity such as a user or
    64  type Resource struct {
    65  	// Name of the resource, e.g. go.micro.service.notes
    66  	Name string `json:"name"`
    67  	// Type of resource, e.g. service
    68  	Type string `json:"type"`
    69  	// Endpoint resource e.g NotesService.Create
    70  	Endpoint string `json:"endpoint"`
    71  }
    72  
    73  // Access defines the type of access a rule grants
    74  type Access int
    75  
    76  const (
    77  	// AccessGranted to a resource
    78  	AccessGranted Access = iota
    79  	// AccessDenied to a resource
    80  	AccessDenied
    81  )
    82  
    83  // Rule is used to verify access to a resource
    84  type Rule struct {
    85  	// ID of the rule, e.g. "public"
    86  	ID string
    87  	// Scope the rule requires, a blank scope indicates open to the public and * indicates the rule
    88  	// applies to any valid account
    89  	Scope string
    90  	// Resource the rule applies to
    91  	Resource *Resource
    92  	// Access determines if the rule grants or denies access to the resource
    93  	Access Access
    94  	// Priority the rule should take when verifying a request, the higher the value the sooner the
    95  	// rule will be applied
    96  	Priority int32
    97  }
    98  
    99  // Auth provides authentication and authorization
   100  type Auth interface {
   101  	// Init the auth
   102  	Init(opts ...Option)
   103  	// Options set for auth
   104  	Options() Options
   105  	// Generate a new account
   106  	Generate(id string, opts ...GenerateOption) (*Account, error)
   107  	// Verify an account has access to a resource using the rules
   108  	Verify(acc *Account, res *Resource, opts ...VerifyOption) error
   109  	// Inspect a token
   110  	Inspect(token string) (*Account, error)
   111  	// Token generated using refresh token or credentials
   112  	Token(opts ...TokenOption) (*AuthToken, error)
   113  	// Grant access to a resource
   114  	Grant(rule *Rule) error
   115  	// Revoke access to a resource
   116  	Revoke(rule *Rule) error
   117  	// Rules returns all the rules used to verify requests
   118  	Rules(...RulesOption) ([]*Rule, error)
   119  	// String returns the name of the implementation
   120  	String() string
   121  }
   122  
   123  // Generate a new account
   124  func Generate(id string, opts ...GenerateOption) (*Account, error) {
   125  	return DefaultAuth.Generate(id, opts...)
   126  }
   127  
   128  // Verify an account has access to a resource using the rules
   129  func Verify(acc *Account, res *Resource, opts ...VerifyOption) error {
   130  	return DefaultAuth.Verify(acc, res, opts...)
   131  }
   132  
   133  // Inspect a token
   134  func Inspect(token string) (*Account, error) {
   135  	return DefaultAuth.Inspect(token)
   136  }
   137  
   138  // Token generated using refresh token or credentials
   139  func Token(opts ...TokenOption) (*AuthToken, error) {
   140  	return DefaultAuth.Token(opts...)
   141  }
   142  
   143  // Grant access to a resource
   144  func Grant(rule *Rule) error {
   145  	return DefaultAuth.Grant(rule)
   146  }
   147  
   148  // Revoke access to a resource
   149  func Revoke(rule *Rule) error {
   150  	return DefaultAuth.Revoke(rule)
   151  }
   152  
   153  // Rules returns all the rules used to verify requests
   154  func Rules(...RulesOption) ([]*Rule, error) {
   155  	return DefaultAuth.Rules()
   156  }
   157  
   158  type accountKey struct{}
   159  
   160  // AccountFromContext gets the account from the context, which
   161  // is set by the auth wrapper at the start of a call. If the account
   162  // is not set, a nil account will be returned. The error is only returned
   163  // when there was a problem retrieving an account
   164  func AccountFromContext(ctx context.Context) (*Account, bool) {
   165  	acc, ok := ctx.Value(accountKey{}).(*Account)
   166  	return acc, ok
   167  }
   168  
   169  // ContextWithAccount sets the account in the context
   170  func ContextWithAccount(ctx context.Context, account *Account) context.Context {
   171  	return context.WithValue(ctx, accountKey{}, account)
   172  }