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 string) bool
- func CanSwitchTo(userRole string, targetRole string) bool
- func InheritedRoles(userRole string) []string
- func Instance(ctx *gin.Context) (string, error)
- func Role(ctx *gin.Context) (string, error)
- func RolesSpec(userRole string) (spec rolesSpec)
- func SwitchTo(ctx *gin.Context, targetRole string) error
- func User(ctx *gin.Context) (string, error)
Examples ¶
Constants ¶
const ( RoleHeader = "role" InstanceHeader = "instance" UserKey = "user" RoleKey = "role" InstanceKey = "instance" )
const ( RoleSuperAdmin = "super admin" RoleInstanceAdmin = "instance admin" RoleEventOrganizer = "event organizer" RoleTeacher = "teacher" NoRole = "" )
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 = []string{ 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 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.
func Instance ¶
Instance retrieves the instance to act for from context. There is no default instance. An invalid instance results in ErrMissingInstance.
func Role ¶
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.
Types ¶
This section is empty.