Open source RBAC library. Associate users with roles and permissions.

permify-gorm

Go Reference Go Report Card GitHub go.mod Go version GitHub Twitter Follow

ℹ️ This package is completely open source and works independently from Permify.

Associate users with roles and permissions

This package allows you to manage user permissions and roles in your database.

👇 Setup

Install

go get github.com/Permify/permify-gorm

Run All Tests

go test ./...

Get the database driver for gorm that you will be using

# 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

Import permify.

import permify `github.com/Permify/permify-gorm`

Initialize the new Permify.

// initialize the database. (you can use all gorm's supported databases)
db, _ := gorm.Open(mysql.Open("user:password@tcp(host:3306)/db?charset=utf8&parseTime=True&loc=Local"), &gorm.Config{})

// New initializer for Permify
// If migration is true, it generate all tables in the database if they don't exist.
permify, _ := permify.New(permify.Options{
	Migrate: true,
	DB: db,
})

🚲 Basic Usage

This package allows users to be associated with permissions and roles. Each role is associated with multiple permissions.

// CreateRole create new role.
// Name parameter is converted to guard name. example: senior $#% associate -> senior-associate.
// If a role with the same name has been created before, it will not create it again. (FirstOrCreate)
// First parameter is role name, second parameter is role description.
err := permify.CreateRole("admin", "role description")

// CreatePermission create new permission.
// Name parameter is converted to guard name. example: create $#% contact -> create-contact.
// If a permission with the same name has been created before, it will not create it again. (FirstOrCreate)
err := permify.CreatePermission("edit user details", "")

Permissions can be added to a role using AddPermissionsToRole method in different ways:

// first parameter is role id
err := permify.AddPermissionsToRole(1, "edit user details")
// or
err := permify.AddPermissionsToRole("admin", []string{"edit user details", "create contact"})
// or
err := permify.AddPermissionsToRole("admin", []uint{1, 3})

With using these methods you can remove and overwrite permissions:

// overwrites the permissions of the role according to the permission names or ids.
err := permify.ReplacePermissionsToRole("admin", []string{"edit user details", "create contact"})

// remove permissions from role according to the permission names or ids.
err := permify.RemovePermissionsFromRole("admin", []string{"edit user details"})

Basic fetch queries:

// Fetch all the roles. (with pagination option).
// If withPermissions is true, it will preload the permissions to the role.
// If pagination is nil, it returns without paging.
roles, totalCount, err := permify.GetAllRoles(options.RoleOption{
	WithPermissions: true,
	Pagination: &utils.Pagination{
		Page: 1,
		Limit: 1,
	},
})

// without paging.
roles, totalCount, err := permify.GetAllRoles(options.RoleOption{
    WithPermissions: false,
})

// The data returned is a collection of roles.
// Collections provides a fluent convenient wrapper for working with arrays of data.
fmt.Println(roles.IDs())
fmt.Println(roles.Names())
fmt.Println(roles.Permissions().Names())

// Fetch all permissions of the user that come with direct and roles.
permissions, _ := permify.GetAllPermissionsOfUser(1)

// Fetch all direct permissions of the user. (with pagination option)
permissions, totalCount, err := permify.GetDirectPermissionsOfUser(1, options.PermissionOption{
    Pagination: &utils.Pagination{
        Page: 1,
        Limit: 10,
    },
})

Controls

// does the role or any of the roles have given permission?
can, err := permify.RoleHasPermission("admin", "edit user details")

// does the role or roles have any of the given permissions?
can, err := permify.RoleHasAnyPermissions([]string{"admin", "manager"}, []string{"edit user details", "create contact"})

// does the role or roles have all the given permissions?
can, err := permify.RoleHasAllPermissions("admin", []string{"edit user details", "create contact"})

// does the user have the given permission? (including the permissions of the roles)
can, err := permify.UserHasPermission(1, "edit user details")

// does the user have the given permission? (not including the permissions of the roles)
can, err := permify.UserHasDirectPermission(1, "edit user details")

// does the user have any of the given permissions? (including the permissions of the roles)
can, err := permify.UserHasAnyPermissions(1, []uint{1, 2})

// does the user have all the given roles?
can, err := permify.UserHasAllRoles(1, []string{"admin", "manager"})

// does the user have any of the given roles?
can, err := permify.UserHasAnyRoles(1, []string{"admin", "manager"})

🚘 Using permissions via roles

Adding Role

Add roles to user according to the role names or ids:

// add one role to user
err := permify.AddRolesToUser(1, "admin")

// you can also add multiple roles at once
err := permify.AddRolesToUser(1, []string{"admin", "manager"})
// or
err := permify.AddRolesToUser(1, []uint{1,2})

Replace the roles of the user according to the role names or ids:

// remove all user roles and add admin role
err := permify.ReplaceRolesToUser(1, "admin")

// you can also replace multiple roles at once
err := permify.ReplaceRolesToUser(1, []string{"admin", "manager"})
// or
err := permify.RemoveRolesFromUser(1, []uint{1,2})

Remove the roles of the user according to the role names or ids:

// remove one role to user
err := permify.RemoveRolesFromUser(1, "admin")

// you can also remove multiple roles at once
err := permify.RemoveRolesFromUser(1, []string{"admin", "manager"})
// or
err := permify.RemoveRolesFromUser(1, []uint{1,2})

Control Roles

// does the user have the given role?
can, err := permify.UserHasRole(1, "admin")

// does the user have all the given roles?
can, err := permify.UserHasAllRoles(1, []string{"admin", "manager"})

// does the user have any of the given roles?
can, err := permify.UserHasAnyRoles(1, []string{"admin", "manager"})

Get User's Roles

roles, totalCount, err := permify.GetRolesOfUser(1, options.RoleOption{
    WithPermissions: true, // preload role's permissions
    Pagination: &utils.Pagination{
        Page: 1,
        Limit: 1,
    },
})

// the data returned is a collection of roles. 
// Collections provides a fluent convenient wrapper for working with arrays of data.
fmt.Println(roles.IDs())
fmt.Println(roles.Names())
fmt.Println(roles.Len())
fmt.Println(roles.Permissions().Names())

Add Permissions to Roles

// add one permission to role
// first parameter can be role name or id, second parameter can be permission name(s) or id(s).
err := permify.AddPermissionsToRole("admin", "edit contact details")

// you can also add multiple permissions at once
err := permify.AddPermissionsToRole("admin", []string{"edit contact details", "delete user"})
// or
err := permify.AddPermissionsToRole("admin", []uint{1, 2})

Remove Permissions from Roles

// remove one permission to role
err := permify.RemovePermissionsFromRole("admin", "edit contact details")

// you can also add multiple permissions at once
err := permify.RemovePermissionsFromRole("admin", []string{"edit contact details", "delete user"})
// or
err := permify.RemovePermissionsFromRole("admin", []uint{1, 2})

Control Role's Permissions

// does the role or any of the roles have given permission?
can, err := permify.RoleHasPermission([]string{"admin", "manager"}, "edit contact details")

// does the role or roles have all the given permissions?
can, err := permify.RoleHasAllPermissions("admin", []string{"edit contact details", "delete contact"})

// does the role or roles have any of the given permissions?
can, err := permify.RoleHasAnyPermissions(1, []string{"edit contact details", "delete contact"})

Get Role's Permissions

permissions, totalCount, err := permify.GetPermissionsOfRoles([]string{"admin", "manager"}, options.PermissionOption{
    Pagination: &utils.Pagination{
        Page: 1,
        Limit: 1,
    },
})

// the data returned is a collection of permissions. 
// Collections provides a fluent convenient wrapper for working with arrays of data.
fmt.Println(permissions.IDs())
fmt.Println(permissions.Names())
fmt.Println(permissions.Len())

🚤 Direct Permissions

Adding Direct Permissions

Add direct permission or permissions to user according to the permission names or ids.

// add one permission to user
err := permify.AddPermissionsToUser(1, "edit contact details")

// you can also add multiple permissions at once
err := permify.AddPermissionsToUser(1, []string{"edit contact details", "create contact"})
// or
err := permify.AddPermissionsToUser(1, []uint{1,2})

Remove the roles of the user according to the role names or ids:

// remove one role to user
err := permify.RemovePermissionsFromUser(1, "edit contact details")

// you can also remove multiple permissions at once
err := permify.RemovePermissionsFromUser(1, []string{"edit contact details", "create contact"})
// or
err := permify.RemovePermissionsFromUser(1, []uint{1,2})

Control Permissions

// ALL PERMISSIONS

// does the user have the given permission? (including the permissions of the roles)
can, err := permify.UserHasPermission(1, "edit contact details")

// does the user have all the given permissions? (including the permissions of the roles)
can, err := permify.UserHasAllPermissions(1, []string{"edit contact details", "delete contact"})

// does the user have any of the given permissions? (including the permissions of the roles).
can, err := permify.UserHasAnyPermissions(1, []string{"edit contact details", "delete contact"})

// DIRECT PERMISSIONS

// does the user have the given permission? (not including the permissions of the roles)
can, err := permify.UserHasDirectPermission(1, "edit contact details")

// does the user have all the given permissions? (not including the permissions of the roles)
can, err := permify.UserHasAllDirectPermissions(1, []string{"edit contact details", "delete contact"})

// does the user have any of the given permissions? (not including the permissions of the roles)
can, err := permify.UserHasAnyDirectPermissions(1, []string{"edit contact details", "delete contact"})

Get User's All Permissions

permissions, err := permify.GetAllPermissionsOfUser(1)

// the data returned is a collection of permissions. 
// Collections provides a fluent convenient wrapper for working with arrays of data.
fmt.Println(permissions.IDs())
fmt.Println(permissions.Names())
fmt.Println(permissions.Len())

Get User's Direct Permissions

permissions, totalCount, err := permify.GetDirectPermissionsOfUser(1, options.PermissionOption{
    Pagination: &utils.Pagination{
        Page:  1,
        Limit: 10,
    },
})

// the data returned is a collection of permissions.
// Collections provides a fluent convenient wrapper for working with arrays of data.
fmt.Println(permissions.IDs())
fmt.Println(permissions.Names())
fmt.Println(permissions.Len())

🚀 Using your user model

You can create the relationships between the user and the role and permissions in this manner. In this way:

  • You can manage user preloads
  • You can create foreign key between users and pivot tables (user_roles, user_permissions).
import (
    "gorm.io/gorm"
    models `github.com/Permify/permify-gorm/models`
)

type User struct {
    gorm.Model
    Name string

    // permify
    Roles       []models.Role       `gorm:"many2many:user_roles;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
    Permissions []models.Permission `gorm:"many2many:user_permissions;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
}

⁉️ Error Handling

ErrRecordNotFound

You can use error handling in the same way as gorm. for example:

// check if returns RecordNotFound error
permission, err := permify.GetPermission(1)
if errors.Is(err, gorm.ErrRecordNotFound) {
	// record not found
}

Errors

Errors List

Stargazers

Stargazers repo roster for @Permify/permify-gorm

Need More, Check Out our API

Permify API is an authorization API which you can add complex rbac and abac solutions.

❤️ Let's get connected:

guilyx | Twitter guilyx's LinkdeIN guilyx's Discord

Owner
Permify
Permify is a plug-&-play authorization API that helps dev teams create granular access control and user management systems without breaking a sweat!
Permify
Similar Resources

Generate K8s RBAC policies based on e2e test runs

rbac-audit Have you ever wondered whether your controller actually needs all the permissions it has granted to it? Wonder no more! This repo contains

Aug 2, 2021

ACL, RBAC, ABAC authorization middleware for KubeSphere

casbin-kubesphere-auth Casbin-kubesphere-auth is a plugin which apply several security authentication check on kubesphere via casbin. This plugin supp

Jun 9, 2022

Incomplete CRUD/RBAC service meant to be a practice for Go

Incomplete CRUD / RBAC Service in Go The repository name means nothing. But your task is to complete this repository on your own to be a functional CR

Nov 9, 2021

A practical RBAC implementation

RBAC This project contains a practical RBAC implementation by Golang. It's actually a demo now. With in-memory storage, no database or file storage ye

Dec 1, 2021

Authelia: an open-source authentication and authorization server providing two-factor authentication

Authelia: an open-source authentication and authorization server providing two-factor authentication

Authelia is an open-source authentication and authorization server providing two

Jan 5, 2022

Handle Web Authentication for Go apps that wish to implement a passwordless solution for users

WebAuthn Library This library is meant to handle Web Authentication for Go apps that wish to implement a passwordless solution for users. While the sp

Dec 30, 2022

Handle Web Authentication for Go apps that wish to implement a passwordless solution for users

WebAuthn Library This library is meant to handle Web Authentication for Go apps that wish to implement a passwordless solution for users. While the sp

Jan 1, 2023

Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to create powerful modern API and web authentication.

❗ Cache package has been moved to libcache repository Go-Guardian Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to

Dec 23, 2022

A simple and lightweight library for creating, formatting, manipulating, signing, and validating JSON Web Tokens in Go.

GoJWT - JSON Web Tokens in Go GoJWT is a simple and lightweight library for creating, formatting, manipulating, signing and validating Json Web Tokens

Nov 15, 2022
An authorization library that supports access control models like ACL, RBAC, ABAC in Golang
An authorization library that supports access control models like ACL, RBAC, ABAC in Golang

Casbin News: still worry about how to write the correct Casbin policy? Casbin online editor is coming to help! Try it at: https://casbin.org/editor/ C

Jan 2, 2023
An authorization library that supports access control models like ACL, RBAC, ABAC in Golang
An authorization library that supports access control models like ACL, RBAC, ABAC in Golang

Casbin News: still worry about how to write the correct Casbin policy? Casbin online editor is coming to help! Try it at: https://casbin.org/editor/ C

Jan 4, 2023
GCP Permission-to-Roles Utility

GCP Permission-to-Roles Utility Rather than sorting through Google's documentation to find a role that contains the permission you need, simply pass t

Feb 1, 2022
goRBAC provides a lightweight role-based access control (RBAC) implementation in Golang.

goRBAC goRBAC provides a lightweight role-based access control implementation in Golang. For the purposes of this package: * an identity has one or mo

Dec 29, 2022
Minimalistic RBAC package for Go applications

RBAC Overview RBAC is a package that makes it easy to implement Role Based Access Control (RBAC) models in Go applications. Download To download this

Oct 25, 2022
Go + Vue开发的管理系统脚手架, 前后端分离, 仅包含项目开发的必需部分, 基于角色的访问控制(RBAC), 分包合理, 精简易于扩展。 后端Go包含了gin、 gorm、 jwt和casbin等的使用, 前端Vue基于vue-element-admin开发
Go + Vue开发的管理系统脚手架, 前后端分离, 仅包含项目开发的必需部分, 基于角色的访问控制(RBAC), 分包合理, 精简易于扩展。 后端Go包含了gin、 gorm、 jwt和casbin等的使用, 前端Vue基于vue-element-admin开发

go-web-mini Go + Vue开发的管理系统脚手架, 前后端分离, 仅包含项目开发的必需部分, 基于角色的访问控制(RBAC), 分包合理, 精简易于扩展。 后端Go包含了gin、 gorm、 jwt和casbin等的使用, 前端Vue基于vue-element-admin开发: http

Dec 25, 2022
YSHOP-GO基于当前流行技术组合的前后端RBAC管理系统:Go1.15.x+Beego2.x+Jwt+Redis+Mysql8+Vue 的前后端分离系统,权限控制采用 RBAC,支持数据字典与数据权限管理,支持动态路由等

YSHOP-GO 后台管理系统 项目简介 YSHOP-GO基于当前流行技术组合的前后端RBAC管理系统:Go1.15.x+Beego2.x+Jwt+Redis+Mysql8+Vue 的前后端分离系统,权限控制采用 RBAC,支持数据字典与数据权限管理,支持动态路由等 体验地址: https://go

Dec 30, 2022
RBAC scaffolding based on Gin + Gorm+ Casbin + Wire
RBAC scaffolding based on Gin + Gorm+ Casbin + Wire

Gin Admin 基于 GIN + GORM + CASBIN + WIRE 实现的RBAC权限管理脚手架,目的是提供一套轻量的中后台开发框架,方便、快速的完成业务需求的开发。 特性 遵循 RESTful API 设计规范 & 基于接口的编程规范 基于 GIN 框架,提供了丰富的中间件支持(JWT

Dec 28, 2022
基于 Echo + Gorm + Casbin + Uber-FX 实现的 RBAC 权限管理脚手架,致力于提供一套尽可能轻量且优雅的中后台解决方案。
基于 Echo + Gorm + Casbin + Uber-FX 实现的 RBAC 权限管理脚手架,致力于提供一套尽可能轻量且优雅的中后台解决方案。

Echo-Admin 基于 Echo + Gorm + Casbin + Uber-FX 实现的 RBAC 权限管理脚手架,致力于提供一套尽可能轻量且优雅的中后台解决方案。 English | 简体中文 特性 遵循 RESTful API 设计规范 基于 Echo API 框架,提供了丰富的中间件支

Dec 14, 2022
Role Based Access Control (RBAC) with database persistence

Authority Role Based Access Control (RBAC) Go package with database persistence Install First get authority go get github.com/harranali/authority Next

Dec 8, 2022