authority

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2023 License: MIT Imports: 3 Imported by: 8

README

Authority

Build Status Test Status Go Report Card GoDoc Coverage Status

Role Based Access Control (RBAC) Go package with database persistence

Features

  • Database Transactions
  • Create Roles
  • Create Permissions
  • Assign Permissions to Roles
  • Supports Assigning Multiple Roles to Users
  • Check if a user have a given roles
  • Check if a user have a given permission
  • Check if a role have a given permission
  • Revoke User's Roles
  • Revoke Role's permissions
  • List all roles assigned to a given user
  • List all roles in the database
  • List all permissions assigned to a given role
  • List all Permissions in the database
  • Delete a given role
  • Delete a given permission

Install

  1. Go get the package
go get github.com/harranali/authority
  1. Authority uses the orm gorm to communicate with the database. gorm needs a database driver in order to work properly. you can install the database driver by runnig a command from the list below, for example if you are using mysql database, simply run go get gorm.io/driver/mysql and so.
# mysql 
go get gorm.io/driver/mysql 
# or postgres
go get gorm.io/driver/postgres
# or sqlite
go get gorm.io/driver/sqlite
# or sqlserver
go get gorm.io/driver/sqlserver
# or clickhouse
go get gorm.io/driver/clickhouse

Usage

To initiate authority you need to pass two variables the first one is the the database table names prefix, the second is an instance of gorm

// initiate the database (using mysql)
dsn := "dbuser:dbpassword@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})

// initiate authority
auth := authority.New(authority.Options{
    TablesPrefix: "authority_",
    DB:           db,
})

// create role
err = auth.CreateRole(authority.Role{
	Name: "Role 1",
	Slug: "role-1",
})

// create permissions
err = auth.CreatePermission(authority.Permission{
	Name: "Permission 1",
	Slug: "permission-1",
})
err = auth.CreatePermission(authority.Permission{
	Name: "Permission 2",
	Slug: "permission-2",
})
err = auth.CreatePermission(authority.Permission{
	Name: "Permission 3",
	Slug: "permission-3",
})

// assign the permissions to the role
err = auth.AssignPermissionsToRole("role-1", []string{
	"permission-1",
	"permission-2",
	"permission-3",
})

// assign a role to user (user id = 1)
err = auth.AssignRoleToUser(1, "role-1")

// check if the user have a given role
ok, err := auth.CheckUserRole(1, "role-a")
if ok {
	fmt.Println("yes, user has the role assigned")
}

// check if a user have a given permission
ok, err = auth.CheckUserPermission(1, "permission-d")
if ok {
	fmt.Println("yes, user has the permission assigned")
}

// check if a role have a given permission
ok, err = auth.CheckRolePermission("role-a", "permission-a")
if ok {
	fmt.Println("yes, role has the permission assigned")
}

Docs

func New(opts Options) *Authority

New initiates authority

dsn := "dbuser:dbpassword@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})

auth := authority.New(authority.Options{
    TablesPrefix: "authority_",
    DB:           db,
})
func Resolve() *Authority

Resolve returns the initiated instance

auth := authority.Resolve()
func (a *Authority) CreateRole(r authority.Role) error

Add a new role to the database it accepts the Role struct as a parameter it returns an error in case of any it returns an error if the role is already exists

// create role
err = auth.CreateRole(authority.Role{
	Name: "Role 1",
	Slug: "role-1",
})
func (a *Authority) CreatePermission(p authority.Permission) error

Add a new permission to the database it accepts the Permission struct as a parameter it returns an error in case of any it returns an error if the permission is already exists

// create a permission
err = auth.CreatePermission(authority.Permission{
	Name: "Permission 1",
	Slug: "permission-1",
})
func (a *Authority) AssignPermissionsToRole(roleSlug string, permSlugs []string) error

Assigns a group of permissions to a given role it accepts the the role slug as the first parameter the second parameter is a slice of permission slugs (strings) to be assigned to the role it returns an error in case of any it returns an error in case the role does not exists it returns an error in case any of the permissions does not exists it returns an error in case any of the permissions is already assigned

// assign the permissions to the role
err := auth.AssignPermissions("role-1", []string{
    "permission-1",
    "permission-2",
    "permission-3",
})
func (a *Authority) AssignRoleToUser(userID interface{}, roleSlug string) error

Assigns a role to a given user it accepts the user id as the first parameter the second parameter the role slug it returns an error in case of any it returns an error in case the role does not exists it returns an error in case the role is already assigned

// assign a role to user (user id) 
err = auth.AssignRoleToUser(1, "role-a")
func (a *Authority) CheckUserRole(userID interface{}, roleSlug string) (bool, error)

Checks if a role is assigned to a user it accepts the user id as the first parameter the second parameter the role slug it returns two parameters the first parameter of the return is a boolean represents whether the role is assigned or not the second is an error in case of any in case the role does not exists, an error is returned

// check if the user have a given role
ok, err := auth.CheckUserRole(1, "role-a")
func (a *Authority) CheckUserPermission(userID interface{}, permSlug string) (bool, error)

Checks if a permission is assigned to a user it accepts in the user id as the first parameter the second parameter the role slug it returns two parameters the first parameter of the return is a boolean represents whether the role is assigned or not the second is an error in case of any in case the role does not exists, an error is returned

// check if a user have a given permission 
ok, err := auth.CheckUserPermission(1, "permission-d")
func (a *Authority) CheckRolePermission(roleSlug string, permSlug string) (bool, error)

Checks if a permission is assigned to a role it accepts in the role slug as the first parameter the second parameter the permission slug it returns two parameters the first parameter of the return is a boolean represents whether the permission is assigned or not the second is an error in case of any in case the role does not exists, an error is returned in case the permission does not exists, an error is returned

// check if a role have a given permission
ok, err := auth.CheckRolePermission("role-a", "permission-a")
func (a *Authority) RevokeUserRole(userID interface{}, roleSlug string) error

Revokes a user's role it returns a error in case of any in case the role does not exists, an error is returned

err = auth.RevokeUserRole(1, "role-a")
func (a *Authority) RevokeRolePermission(roleSlug string, permSlug string) error

Revokes a roles's permission it returns a error in case of any in case the role does not exists, an error is returned in case the permission does not exists, an error is returned

err = auth.RevokeRolePermission("role-a", "permission-a")
func (a *Authority) GetAllRoles() ([]Role, error)

Returns all stored roles it returns an error in case of any

roles, err := auth.GetAllRoles()
func (a *Authority) GetUserRoles(userID interface{}) ([]Role, error)

Returns all user assigned roles it returns an error in case of any

roles, err := auth.GetUserRoles(1)
func (a *Authority) GetRolePermissions(roleSlug string) ([]Permission, error)

Returns all role assigned permissions it returns an error in case of any

permissions, err := auth.GetRolePermissions("role-a")
func (a *Authority) GetAllPermissions() ([]Permission, error)

Returns all stored permissions it returns an error in case of any

permissions, err := auth.GetAllPermissions()
func (a *Authority) DeleteRole(roleSlug string) error

Deletes a given role even if it's has assigned permissions it first deassign the permissions and then proceed with deleting the role it accepts the role slug as a parameter it returns an error in case of any if the role is assigned to a user it returns an error

err := auth.DeleteRole("role-b")
func (a *Authority) DeletePermission(permSlug string) error

Deletes a given permission it accepts the permission slug as a parameter it returns an error in case of any if the permission is assigned to a role it returns an error

err := auth.DeletePermission("permission-c")
Transactions

authority supports database transactions by implementing 3 methods BeginTX(), Rollback(), and Commit() here is an example of how to use transactions


// begin a transaction session
tx := auth.BeginTX()
// create role
err = tx.CreateRole(authority.Role{
	Name: "Role 1",
	Slug: "role-1",
})
if err != nil {
    tx.Rollback() // transaction rollback incase of error
    fmt.Println("error creating role", err)
}

// create permissions
err = tx.CreatePermission(authority.Permission{
	Name: "Permission 1",
	Slug: "permission-1",
})
if err != nil {
    tx.Rollback() // transaction rollback incase of error
    fmt.Println("error creating permission", err)
}

// assign the permissions to the role
err = tx.AssignPermissionsToRole("role-1", []string{
	"permission-1",
	"permission-2",
	"permission-3",
})

if err != nil {
    tx.Rollback() // transaction rollback incase of error
    fmt.Println("error assigning permission to role", err)
}
// assign a role to user (user id = 1)
err = tx.AssignRoleToUser(1, "role-1")
if err != nil {
    tx.Rollback() // transaction rollback incase of error
    fmt.Println("error assigning role to user", err)
}

// commit the operations to the database
tx.Commit()

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrPermissionInUse    = errors.New("cannot delete assigned permission")
	ErrPermissionNotFound = errors.New("permission not found")
	ErrRoleInUse          = errors.New("cannot delete assigned role")
	ErrRoleNotFound       = errors.New("role not found")
)

Functions

This section is empty.

Types

type Authority

type Authority struct {
	TablesPrefix string
	DB           *gorm.DB
}

Authority helps deal with permissions

func New

func New(opts Options) *Authority

New initiates authority

func Resolve

func Resolve() *Authority

Resolve returns the initiated instance

func (*Authority) AssignPermissionsToRole added in v1.2.0

func (a *Authority) AssignPermissionsToRole(roleSlug string, permSlugs []string) error

Assigns a group of permissions to a given role it accepts the the role slug as the first parameter the second parameter is a slice of permission slugs (strings) to be assigned to the role it returns an error in case of any it returns an error in case the role does not exists it returns an error in case any of the permissions does not exists it returns an error in case any of the permissions is already assigned

func (*Authority) AssignRoleToUser added in v1.2.0

func (a *Authority) AssignRoleToUser(userID interface{}, roleSlug string) error

Assigns a role to a given user it accepts the user id as the first parameter the second parameter the role slug it returns an error in case of any it returns an error in case the role does not exists it returns an error in case the role is already assigned

func (*Authority) BeginTX added in v1.2.0

func (a *Authority) BeginTX() *Authority

Begin a transaction session

func (*Authority) CheckRolePermission

func (a *Authority) CheckRolePermission(roleSlug string, permSlug string) (bool, error)

Checks if a permission is assigned to a role it accepts in the role slug as the first parameter the second parameter the permission slug it returns two parameters the first parameter of the return is a boolean represents whether the permission is assigned or not the second is an error in case of any in case the role does not exists, an error is returned in case the permission does not exists, an error is returned

func (*Authority) CheckUserPermission added in v1.2.0

func (a *Authority) CheckUserPermission(userID interface{}, permSlug string) (bool, error)

Checks if a permission is assigned to a user it accepts in the user id as the first parameter the second parameter the role slug it returns two parameters the first parameter of the return is a boolean represents whether the role is assigned or not the second is an error in case of any in case the role does not exists, an error is returned

func (*Authority) CheckUserRole added in v1.2.0

func (a *Authority) CheckUserRole(userID interface{}, roleSlug string) (bool, error)

Checks if a role is assigned to a user it accepts the user id as the first parameter the second parameter the role slug it returns two parameters the first parameter of the return is a boolean represents whether the role is assigned or not the second is an error in case of any in case the role does not exists, an error is returned

func (*Authority) Commit added in v1.2.0

func (a *Authority) Commit() error

Commit queries to the database

func (*Authority) CreatePermission

func (a *Authority) CreatePermission(p Permission) error

Add a new permission to the database it accepts the Permission struct as a parameter it returns an error in case of any it returns an error if the permission is already exists

func (*Authority) CreateRole

func (a *Authority) CreateRole(r Role) error

Add a new role to the database it accepts the Role struct as a parameter it returns an error in case of any it returns an error if the role is already exists

func (*Authority) DeletePermission

func (a *Authority) DeletePermission(permSlug string) error

Deletes a given permission it accepts the permission slug as a parameter it returns an error in case of any if the permission is assigned to a role it returns an error

func (*Authority) DeleteRole

func (a *Authority) DeleteRole(roleSlug string) error

Deletes a given role even if it's has assigned permissions it first deassign the permissions and then proceed with deleting the role it accepts the role slug as a parameter it returns an error in case of any if the role is assigned to a user it returns an error

func (*Authority) GetAllPermissions added in v1.2.0

func (a *Authority) GetAllPermissions() ([]Permission, error)

Returns all stored permissions it returns an error in case of any

func (*Authority) GetAllRoles added in v1.2.0

func (a *Authority) GetAllRoles() ([]Role, error)

Returns all stored roles it returns an error in case of any

func (*Authority) GetRolePermissions added in v1.2.0

func (a *Authority) GetRolePermissions(roleSlug string) ([]Permission, error)

Returns all role assigned permissions it returns an error in case of any

func (*Authority) GetUserRoles added in v1.2.0

func (a *Authority) GetUserRoles(userID interface{}) ([]Role, error)

Returns all user assigned roles it returns an error in case of any

func (*Authority) RevokeRolePermission

func (a *Authority) RevokeRolePermission(roleSlug string, permSlug string) error

Revokes a roles's permission it returns a error in case of any in case the role does not exists, an error is returned in case the permission does not exists, an error is returned

func (*Authority) RevokeUserRole added in v1.2.0

func (a *Authority) RevokeUserRole(userID interface{}, roleSlug string) error

Revokes a user's role it returns a error in case of any in case the role does not exists, an error is returned

func (*Authority) Rollback added in v1.2.0

func (a *Authority) Rollback() error

Rolback previous queries

type Options

type Options struct {
	TablesPrefix string
	DB           *gorm.DB
}

Options has the options for initiating the package

type Permission

type Permission struct {
	ID   uint   // The permission id (it gets set automatically by the database)
	Name string // The permission name
	Slug string // String based unique identifier of the permission, (use hyphen seperated permission name '-', instead of space)
}

Permission represents the database model of permissions

func (Permission) TableName

func (p Permission) TableName() string

TableName sets the table name

type Role

type Role struct {
	ID   uint   // The role id (it gets set automatically by the database)
	Name string // The name of the role
	Slug string // String based unique identifier of the role, (use hyphen seperated role name '-', instead of space)
}

The database model of a role

func (Role) TableName

func (r Role) TableName() string

TableName sets the table name

type RolePermission

type RolePermission struct {
	ID           uint // Unique id (it gets set automatically by the database)
	RoleID       uint // Role id
	PermissionID uint // Permission id
}

The link between the roles and permissions

func (RolePermission) TableName

func (r RolePermission) TableName() string

TableName sets the table name

type UserRole

type UserRole struct {
	ID     uint   // Unique id (it gets set automatically by the database)
	UserID string // The user id
	RoleID uint   // The role id
}

The link between the users and roles

func (UserRole) TableName

func (u UserRole) TableName() string

TableName sets the table name

Jump to

Keyboard shortcuts

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