github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/auth/auth.go (about)

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