roles

package
v0.0.7 Latest Latest
Warning

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

Go to latest
Published: Dec 17, 2021 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package roles manages user's permissions depending on its roles. Roles are organized hierarchically and are implicitely or explicitely inherited.

From implicit inheritance a user receives the union of all capabilities of transitively inherited roles. This inheritance is transparent to both the user's current active role and code that does checks upon a possibly inherited role to allow/prohibid an action that requires authorization.

From explicit inheritance a user does not transparently inherit any capabilities. The are only signalers to which role a user might switch to receive those (and implicitely) inherited capabilities.

Some syntactic sugar for gin.Context is provided to allow simple authorization checks like

roles.CanActIn(ctx, roles.RoleTeacher)

roles.CanActFor(ctx, instanceID)

and permanent switching to another role

roles.SwitchTo(ctx, roles.RoleInstanceAdmin)
Example (SuccessfulCheck)

Demonstrates the parsing of the current instance and user's role and a successful authorization check.

package main

import (
	"fmt"
	"net/http/httptest"

	"github.com/gin-gonic/gin"
	"github.com/smartnuance/saas-kit/pkg/lib/roles"
)

func main() {
	// Create dummy context
	r := httptest.NewRecorder()
	ctx, _ := gin.CreateTestContext(r)
	ctx.Set("user", "user-guid")
	ctx.Set("role", "teacher")
	ctx.Set("instance", "instance-guid")

	// Check permission to revoke token for potentially different user
	if !(roles.CanActFor(ctx, "instance-guid") && roles.CanActIn(ctx, roles.RoleTeacher)) {
		fmt.Println("unauthorized")
		return
	}

	// Do something a teacher can do
	fmt.Println("authorized")

}
Output:

authorized
Example (SwitchRole)

Demonstrates the parsing of the current instance and user's role and a successful authorization check.

package main

import (
	"fmt"
	"net/http/httptest"

	"github.com/gin-gonic/gin"
	"github.com/smartnuance/saas-kit/pkg/lib/roles"
)

func main() {
	// Create dummy context
	r := httptest.NewRecorder()
	ctx, _ := gin.CreateTestContext(r)
	ctx.Set("user", "user-guid")
	ctx.Set("role", "super admin")
	ctx.Set("instance", "instance-guid")

	// Check permission to revoke token for potentially different user
	if !roles.CanActFor(ctx, "instance-guid") {
		fmt.Println("instance unauthorized")
		return
	}

	if !roles.CanActIn(ctx, roles.RoleTeacher) {
		fmt.Println("unauthorized to act as teacher")
	}

	err := roles.SwitchTo(ctx, roles.RoleInstanceAdmin)
	if err != nil {
		fmt.Print(err)
		return
	}

	fmt.Println("switched to instance admin")

	if !roles.CanActIn(ctx, roles.RoleTeacher) {
		fmt.Println("still unauthorized to act as teacher")
		return
	}

	// Do something a teacher can do
	fmt.Println("authorized")

}
Output:

unauthorized to act as teacher
switched to instance admin
authorized

Index

Examples

Constants

View Source
const (
	RoleHeader     = "role"
	InstanceHeader = "instance"

	UserKey     = "user"
	RoleKey     = "role"
	InstanceKey = "instance"
)
View Source
const (
	RoleSuperAdmin     = "super admin"
	RoleInstanceAdmin  = "instance admin"
	RoleEventOrganizer = "event organizer"
	RoleTeacher        = "teacher"
	NoRole             = ""
)

Variables

View Source
var (
	ErrMissingUser      = errors.New("missing user")
	ErrInvalidRole      = errors.New("invalid role provided")
	ErrMissingInstance  = errors.New("missing instance")
	ErrSwitchNotAllowed = errors.New("role switch not allowed")
	ErrUnauthorized     = errors.New("role insufficient to act on desired instance")
)

Functions

func CanActAs

func CanActAs(ctx *gin.Context, targetUserID string) bool

CanActAs checks if the user can act as a desired user.

func CanActFor

func CanActFor(ctx *gin.Context, instanceID string) bool

CanActFor checks if the user can act for the desired instance.

func CanActIn

func CanActIn(ctx *gin.Context, targetRole string) bool

CanActIn checks if the user can act in the desired targetRole without switching to that role.

func CanSwitchTo

func CanSwitchTo(userRole string, targetRole string) bool

CanSwitchTo checks if the user's role can switch to a targetRole acquiring those role's permissions. Switching is allowed when there is an implicit path from userRole to role or userrole directly, explicitly inherits targetRole.

func InheritedRoles

func InheritedRoles(userRole string) []string

InheritedRoles returns an unordered list of roles a given user role can act in, without switching. The returned list is a copy and can be safely modified.

func Instance

func Instance(ctx *gin.Context) (string, error)

Instance retrieves the instance to act for from context. There is no default instance. An invalid instance results in ErrMissingInstance.

func Role

func Role(ctx *gin.Context) (string, error)

Role retrieves the role from context. The default role is NoRole. An invalid role results in ErrInvalidRole.

func RolesSpec

func RolesSpec(userRole string) (spec rolesSpec)

RolesSpec returns a RolesSpec for the given user role.

func SwitchTo

func SwitchTo(ctx *gin.Context, targetRole string) error

SwitchTo attempts to switch to a temporary targetRole. The user's role defined in context is checked against the rules defining if switching is allowed. The temporary role is set on the context under the "role" key, overwriting the original role.

func User

func User(ctx *gin.Context) (string, error)

User retrieves the user from context. There is no default user. When no user is registerd in context, this results in ErrMissingUser.

Types

This section is empty.

Jump to

Keyboard shortcuts

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