micro/auth/auth.go

137 lines
3.8 KiB
Go
Raw 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"
)
var (
// ErrNotFound is returned when a resouce cannot be found
ErrNotFound = errors.New("not found")
// ErrEncodingToken is returned when the service encounters an error during encoding
ErrEncodingToken = errors.New("error encoding the token")
// ErrInvalidToken is returned when the token provided is not valid
ErrInvalidToken = errors.New("invalid token provided")
// ErrInvalidRole is returned when the role provided was invalid
ErrInvalidRole = errors.New("invalid role")
// ErrForbidden is returned when a user does not have the necessary roles to access a resource
ErrForbidden = errors.New("resource forbidden")
)
2019-11-25 12:30:26 +03:00
// Auth providers authentication and authorization
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)
// Grant access to a resource
Grant(role string, res *Resource) error
// Revoke access to a resource
Revoke(role string, res *Resource) error
// Verify an account has access to a resource
Verify(acc *Account, res *Resource) error
// Inspect a token
Inspect(token string) (*Account, error)
2020-03-31 19:01:51 +03:00
// Token generated using refresh token
2020-04-01 16:25:00 +03:00
Token(opts ...TokenOption) (*Token, 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
}
// Resource is an entity such as a user or
type Resource struct {
2019-12-18 00:27:05 +03:00
// Name of the resource
Name string `json:"name"`
// Type of resource, e.g.
Type string `json:"type"`
// Endpoint resource e.g NotesService.Create
Endpoint string `json:"endpoint"`
}
// 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"`
// Provider who issued the account
Provider string `json:"provider"`
// Roles associated with the Account
Roles []string `json:"roles"`
// Any other associated metadata
Metadata map[string]string `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"`
}
// HasScope returns a boolean indicating if the account has the given scope
func (a *Account) HasScope(scope string) bool {
if a.Scopes == nil {
return false
}
for _, s := range a.Scopes {
if s == scope {
return true
}
}
return false
}
2020-05-11 13:34:22 +03:00
// HasRole returns a boolean indicating if the account has the given role
func (a *Account) HasRole(role string) bool {
if a.Roles == nil {
return false
}
for _, r := range a.Roles {
if r == role {
return true
}
}
return false
}
// 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
const (
// TokenCookieName is the name of the cookie which stores the auth token
TokenCookieName = "micro-token"
// BearerScheme used for Authorization header
BearerScheme = "Bearer "
2020-03-04 12:54:52 +03:00
)
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) {
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 {
return context.WithValue(ctx, accountKey{}, account)
2020-03-04 12:54:52 +03:00
}