authorization

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 8, 2022 License: GPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package authorization handles gRPC calls authorization via metadata, similary to the `Authorization` header (https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Authorization) in HTTP.

Index

Examples

Constants

View Source
const (
	// MetadataName is the name of the metadata that holds the authorization credential.
	MetadataName = "authorization"
)

Variables

View Source
var (
	// ErrInvalidOptionValue is returned when using an invalid option value
	ErrInvalidOptionValue = errors.New("invalid option value")
	// ErrUnchecked is returned when no Authorization interceptor are in use
	ErrUnchecked = errors.New("authorization metadata is unchecked")
	// ErrMissing is returned when request was made without authorization metadata
	ErrMissing = errors.New("request has no authorization credentials")
	// ErrInvalid is returned when request was made with an invalid authorization metadata
	ErrInvalid = errors.New("authorization credentials are invalid")
	// ErrType is returned when trying to get authorization result as the wrong type
	ErrType = errors.New("authorization has the wrong type")
	// ErrInvalidMethod is returned when trying to use an invalid authorization method
	ErrInvalidMethod = errors.New("invalid authorization method")
)

Functions

func AppendToOutgoingContext

func AppendToOutgoingContext(ctx context.Context, method, credential string) (context.Context, error)

AppendToOutgoingContext will return a new context with authentification metadata for a given method appended to the outgoing context. `method` must be a non empty string with lowercase alphanumeric characters, not containing whitespaces. If context's outgoing metadata already contains a credential, it is replaced,

func GetFromContext

func GetFromContext(ctx context.Context, dest interface{}) error

GetFromContext gets the authorization value, if request has been made with a valid metadata and passed throught interceptor and sets ir into `dest`. If not, can return ErrUnchecked, ErrMissing, ErrInvalid or ErrType

Example

ExampleGetFromContext show how to get the `CredentialValidator` result in a gRPC method handler

package main

import (
	"context"
	"errors"

	"github.com/jucrouzet/grpcutils/pkg/authorization"
)

func main() {
	var usr *User
	err := authorization.GetFromContext(ctx, &usr)

	if errors.Is(err, authorization.ErrMissing) {
		// No authorization was sent from client
	}
	if errors.Is(err, authorization.ErrInvalid) {
		// Authorization sent from client is invalid
	}
	if err != nil {
		// Another error (like wrong type or interceptor not used)
	}
	// usr is now the result of CredentialValidator is it returned a *User

}

var ctx context.Context

type User struct {
}
Output:

Types

type Authorization

type Authorization struct {
	// contains filtered or unexported fields
}

Authorization handles authorization of methods via metadata

func New

func New(opts ...Options) (*Authorization, error)

New creates a new instance of Authorization with specified options

Example

ExampleNew creates a new gRPC server that checks authorization with the `basic` method

package main

import (
	"context"

	"google.golang.org/grpc"

	"github.com/jucrouzet/grpcutils/internal/pkg/foobar"
	"github.com/jucrouzet/grpcutils/pkg/authorization"
)

func main() {
	// checkToken is a function that parses token, see the `WithMethodFunction` example
	a, err := authorization.New(
		authorization.WithMethodFunction("basic", checkToken),
	)
	if err != nil {
		panic(err)
	}
	server := grpc.NewServer(
		grpc.UnaryInterceptor(a.UnaryInterceptor()),
		grpc.StreamInterceptor(a.StreamInterceptor()),
	)
	foobar.RegisterDummyServiceServer(server, &foobar.UnimplementedDummyServiceServer{})
}

func checkToken(ctx context.Context, token string) (any, error) {
	return "", nil
}
Output:

func (*Authorization) StreamInterceptor

func (a *Authorization) StreamInterceptor() grpc.StreamServerInterceptor

StreamInterceptor returns a gRPC server stream interceptor that sets logger in stream context

func (*Authorization) UnaryInterceptor

func (a *Authorization) UnaryInterceptor() grpc.UnaryServerInterceptor

UnaryInterceptor returns a gRPC server unary interceptor that sets logger in call context

type CredentialValidator

type CredentialValidator func(ctx context.Context, credential string) (any, error)

CredentialValidator is the function type for functions that validates credentials. The context passed is the unary or stream context, credential is the value/token provided by the caller. The value returned will be stored in the context and available in methods implementations by calling GetFromContext. The returned value type if correct must be the same as the one used in GetFromContext.

type Options

type Options func(*Authorization) error

Options is the Authorization option functions type

func WithMethodFunction

func WithMethodFunction(method string, fn CredentialValidator) Options

WithMethodFunction specifies a credential validation function to be used for a given authorization method. `method` must be a non empty string with lowercase alphanumeric characters, not containing whitespaces.

Example

ExampleWithMethodFunction show how to define a `CredentialValidator` function that parses credentials

package main

import (
	"context"

	"github.com/jucrouzet/grpcutils/pkg/authorization"
)

func main() {
	var credentialValidator authorization.CredentialValidator

	credentialValidator = func(ctx context.Context, credential string) (any, error) {
		userID, err := parseJWT(credential)
		if err != nil {
			return nil, err
		}
		user, err := getUserInDB(userID)
		if err != nil {
			return nil, err
		}
		return user, nil
	}
	// auth'd user can later be get (if valid token) with :
	// var usr *User
	// err := authorization.GetFromContext(ctx, &usr)
	authorization.New(
		authorization.WithMethodFunction("bearer", credentialValidator),
	)
}

func parseJWT(tok string) (string, error) {
	return "", nil
}

func getUserInDB(userID string) (*User, error) {
	return nil, nil
}

type User struct {
}
Output:

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL