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 ¶
- Constants
- Variables
- func CanActAs(ctx *gin.Context, targetUserID string) bool
- func CanActFor(ctx *gin.Context, instanceID string) bool
- func CanActIn(ctx *gin.Context, targetRole Role) bool
- func CanSwitchTo(userRole Role, targetRole Role) bool
- func Instance(ctx *gin.Context) (string, error)
- func RolesSpec(userRole Role) (spec rolesSpec)
- func SwitchTo(ctx *gin.Context, targetRole Role) error
- func User(ctx *gin.Context) (string, error)
- type Role
Examples ¶
Constants ¶
const ( RoleHeader = "role" InstanceHeader = "instance" UserKey = "user" RoleKey = "role" InstanceKey = "instance" )
Variables ¶
var ( ErrMissingUser = errors.New("missing user") ErrInvalidRole = errors.New("invalid role provided") ErrMissingInstance = errors.New("missing instance") ErrSwitchNotAllowed = errors.New("role switch not allowed") )
var Roles = []Role{ RoleSuperAdmin, RoleInstanceAdmin, RoleEventOrganizer, RoleTeacher, NoRole, }
Functions ¶
func CanActIn ¶
CanActIn checks if the user can act in the desired targetRole without switching to that role.
func CanSwitchTo ¶
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 Instance ¶
Instance retrieves the instance to act for from context. There is no default instance. An invalid instance results in ErrMissingInstance.
func RolesSpec ¶
func RolesSpec(userRole Role) (spec rolesSpec)
RolesSpec returns a RolesSpec for the given user role.
Types ¶
type Role ¶
type Role string
func FromContext ¶
FromContext retrieves the role from context. The default role is NoRole. An invalid role results in ErrInvalidRole.
func InheritedRoles ¶
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.