micro/auth/auth.go

144 lines
4.2 KiB
Go
Raw Permalink Normal View History

2019-11-25 12:30:26 +03:00
// Package auth provides authentication and authorization capability
package auth
2019-11-25 12:33:30 +03:00
import (
2020-03-04 12:54:52 +03:00
"context"
"errors"
2019-11-25 12:33:30 +03:00
"time"
"github.com/unistack-org/micro/v3/metadata"
2019-11-25 12:33:30 +03:00
)
2020-05-22 13:37:12 +03:00
const (
// BearerScheme used for Authorization header
BearerScheme = "Bearer "
// ScopePublic is the scope applied to a rule to allow access to the public
ScopePublic = ""
// ScopeAccount is the scope applied to a rule to limit to users with any valid account
ScopeAccount = "*"
)
2020-05-20 13:59:01 +03:00
var (
// DefaultAuth holds default auth implementation
DefaultAuth Auth = NewAuth()
2020-05-20 13:59:01 +03:00
// ErrInvalidToken is when the token provided is not valid
ErrInvalidToken = errors.New("invalid token provided")
2020-05-21 16:56:17 +03:00
// ErrForbidden is when a user does not have the necessary scope to access a resource
ErrForbidden = errors.New("resource forbidden")
)
2020-05-21 18:41:55 +03:00
// Auth provides authentication and authorization
2019-11-25 12:30:26 +03:00
type Auth interface {
// Init the auth
Init(opts ...Option)
// Options set for auth
Options() Options
// Generate a new account
2020-04-01 19:20:02 +03:00
Generate(id string, opts ...GenerateOption) (*Account, error)
2020-05-20 13:59:01 +03:00
// Verify an account has access to a resource using the rules
2020-05-20 18:49:52 +03:00
Verify(acc *Account, res *Resource, opts ...VerifyOption) error
// Inspect a token
Inspect(token string) (*Account, error)
2020-05-20 13:59:01 +03:00
// Token generated using refresh token or credentials
2020-04-01 16:25:00 +03:00
Token(opts ...TokenOption) (*Token, error)
2020-05-20 13:59:01 +03:00
// Grant access to a resource
Grant(rule *Rule) error
// Revoke access to a resource
Revoke(rule *Rule) error
// Rules returns all the rules used to verify requests
2020-05-26 17:52:21 +03:00
Rules(...RulesOption) ([]*Rule, error)
// String returns the name of the implementation
2020-02-16 22:36:45 +03:00
String() string
2019-12-18 00:27:05 +03:00
}
// Account provided by an auth provider
type Account struct {
2020-03-31 19:01:51 +03:00
// ID of the account e.g. email
ID string `json:"id"`
// Type of the account, e.g. service
Type string `json:"type"`
2020-05-21 18:41:55 +03:00
// Issuer of the account
Issuer string `json:"issuer"`
// Any other associated metadata
Metadata metadata.Metadata `json:"metadata"`
// Scopes the account has access to
Scopes []string `json:"scopes"`
2020-03-31 20:17:01 +03:00
// Secret for the account, e.g. the password
Secret string `json:"secret"`
}
// Token can be short or long lived
type Token struct {
2020-04-01 16:25:00 +03:00
// The token to be used for accessing resources
AccessToken string `json:"access_token"`
// RefreshToken to be used to generate a new token
RefreshToken string `json:"refresh_token"`
// Time of token creation
2019-11-25 12:30:26 +03:00
Created time.Time `json:"created"`
// Time of token expiry
2019-11-25 12:30:26 +03:00
Expiry time.Time `json:"expiry"`
}
2020-03-04 12:54:52 +03:00
2020-05-20 13:59:01 +03:00
// Expired returns a boolean indicating if the token needs to be refreshed
func (t *Token) Expired() bool {
return t.Expiry.Unix() < time.Now().Unix()
}
// Resource is an entity such as a user or
type Resource struct {
// Name of the resource, e.g. go.micro.service.notes
Name string `json:"name"`
// Type of resource, e.g. service
Type string `json:"type"`
// Endpoint resource e.g NotesService.Create
Endpoint string `json:"endpoint"`
}
// Access defines the type of access a rule grants
type Access int
2020-03-04 12:54:52 +03:00
const (
2020-05-20 13:59:01 +03:00
// AccessGranted to a resource
AccessGranted Access = iota
// AccessDenied to a resource
AccessDenied
2020-03-04 12:54:52 +03:00
)
2020-05-20 13:59:01 +03:00
// Rule is used to verify access to a resource
type Rule struct {
// ID of the rule, e.g. "public"
ID string
2020-05-21 16:56:17 +03:00
// Scope the rule requires, a blank scope indicates open to the public and * indicates the rule
2020-05-20 13:59:01 +03:00
// applies to any valid account
2020-05-21 16:56:17 +03:00
Scope string
2020-05-20 13:59:01 +03:00
// Resource the rule applies to
Resource *Resource
// Access determines if the rule grants or denies access to the resource
Access Access
// Priority the rule should take when verifying a request, the higher the value the sooner the
// rule will be applied
Priority int32
}
type accountKey struct{}
2020-03-04 12:54:52 +03:00
// AccountFromContext gets the account from the context, which
// is set by the auth wrapper at the start of a call. If the account
// is not set, a nil account will be returned. The error is only returned
// when there was a problem retrieving an account
func AccountFromContext(ctx context.Context) (*Account, bool) {
if ctx == nil {
return nil, false
}
acc, ok := ctx.Value(accountKey{}).(*Account)
return acc, ok
2020-03-04 12:54:52 +03:00
}
// ContextWithAccount sets the account in the context
func ContextWithAccount(ctx context.Context, account *Account) context.Context {
if ctx == nil {
ctx = context.Background()
}
return context.WithValue(ctx, accountKey{}, account)
2020-03-04 12:54:52 +03:00
}