permify_gorm

package module
v0.0.0-...-2e7d536 Latest Latest
Warning

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

Go to latest
Published: Dec 9, 2023 License: MIT Imports: 8 Imported by: 0

README ΒΆ

Permify logo

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

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/ai-psyche/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/ai-psyche/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/ai-psyche/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

Community & Support

Join our Discord channel for issues, feature requests, feedbacks or anything else. We love to talk about authorization and access control ❀

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

This section is empty.

Functions ΒΆ

This section is empty.

Types ΒΆ

type Options ΒΆ

type Options struct {
	Migrate bool
	DB      *gorm.DB
}

Options has the options for initiating the Permify

type Permify ΒΆ

type Permify struct {
	RoleRepository       repositories.IRoleRepository
	PermissionRepository repositories.IPermissionRepository
	UserRepository       repositories.IUserRepository
}

Permify is main struct of this package.

func New ΒΆ

func New(opts Options) (p *Permify, err error)

New initializer for Permify If migration is true, it generate all tables in the database if they don't exist.

func (*Permify) AddPermissionsToRole ΒΆ

func (s *Permify) AddPermissionsToRole(r interface{}, p interface{}) (err error)

AddPermissionsToRole add permission to role. First parameter can be role name or id, second parameter can be permission name(s) or id(s). If the first parameter is an array, the first element of the first parameter is used. @param interface{} @param interface{} @return error

func (*Permify) AddPermissionsToUser ΒΆ

func (s *Permify) AddPermissionsToUser(userID uint, p interface{}) (err error)

AddPermissionsToUser add direct permission or permissions to user according to the permission names or ids. First parameter is the user id, second parameter is can be permission name(s) or id(s). @param uint @param interface{} @return error

func (*Permify) AddRolesToUser ΒΆ

func (s *Permify) AddRolesToUser(userID uint, r interface{}) (err error)

AddRolesToUser add role or roles to user according to the role names or ids. First parameter is the user id, second parameter is can be role name(s) or id(s). @param uint @param interface{} @return error

func (*Permify) CreatePermission ΒΆ

func (s *Permify) CreatePermission(name string, description string) (err error)

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) @param string @param string @return error

func (*Permify) CreateRole ΒΆ

func (s *Permify) CreateRole(name string, description string) (err error)

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. @param string @param string @return error

func (*Permify) DeletePermission ΒΆ

func (s *Permify) DeletePermission(p interface{}) (err error)

DeletePermission delete permission. If the permission is in use, its relations from the pivot tables are deleted. First parameter can be permission name or id. If the first parameter is an array, the first element of the given array is used. @param interface{} @return error

func (*Permify) DeleteRole ΒΆ

func (s *Permify) DeleteRole(r interface{}) (err error)

DeleteRole delete role. If the role is in use, its relations from the pivot tables are deleted. First parameter can be role name or id. @param interface{} @return error

func (*Permify) GetAllPermissions ΒΆ

func (s *Permify) GetAllPermissions(option options.PermissionOption) (permissions collections.Permission, totalCount int64, err error)

GetAllPermissions fetch all the permissions. (with pagination option). First parameter is permission option. @param options.PermissionOption @return collections.Permission, int64, error

func (*Permify) GetAllPermissionsOfUser ΒΆ

func (s *Permify) GetAllPermissionsOfUser(userID uint) (permissions collections.Permission, err error)

GetAllPermissionsOfUser fetch all permissions of the user that come with direct and roles. First parameter is user id. @param uint @return collections.Permission, error

func (*Permify) GetAllRoles ΒΆ

func (s *Permify) GetAllRoles(option options.RoleOption) (roles collections.Role, totalCount int64, err error)

GetAllRoles fetch all the roles. (with pagination option). If withPermissions is true, it will preload the permissions to the role. First parameter is role option. @param options.RoleOption @return collections.Role, int64, error

func (*Permify) GetDirectPermissionsOfUser ΒΆ

func (s *Permify) GetDirectPermissionsOfUser(userID uint, option options.PermissionOption) (permissions collections.Permission, totalCount int64, err error)

GetDirectPermissionsOfUser fetch all direct permissions of the user. (with pagination option) First parameter is user id, second parameter is permission option. @param uint @param options.PermissionOption @return collections.Permission, int64, error

func (*Permify) GetPermission ΒΆ

func (s *Permify) GetPermission(p interface{}) (permission models.Permission, err error)

GetPermission fetch permission according to the permission name or id. First parameter can be permission name or id. If the first parameter is an array, the first element of the given array is returned. @param interface{} @return error

func (*Permify) GetPermissions ΒΆ

func (s *Permify) GetPermissions(p interface{}) (permissions collections.Permission, err error)

GetPermissions fetch permissions according to the permission names or ids. First parameter is can be permission name(s) or id(s). @param interface{} @return collections.Permission, error

func (*Permify) GetPermissionsOfRoles ΒΆ

func (s *Permify) GetPermissionsOfRoles(r interface{}, option options.PermissionOption) (permissions collections.Permission, totalCount int64, err error)

GetPermissionsOfRoles fetch all permissions of the roles. (with pagination option) First parameter can be role name(s) or id(s), second parameter is permission option. @param interface{} @param options.PermissionOption @return collections.Permission, int64, error

func (*Permify) GetRole ΒΆ

func (s *Permify) GetRole(r interface{}, withPermissions bool) (role models.Role, err error)

GetRole fetch role according to the role name or id. If withPermissions is true, it will preload the permissions to the role. First parameter is can be role name or id, second parameter is boolean. If the given variable is an array, the first element of the given array is returned. @param interface{} @param bool @return models.Role, error

func (*Permify) GetRoles ΒΆ

func (s *Permify) GetRoles(r interface{}, withPermissions bool) (roles collections.Role, err error)

GetRoles fetch roles according to the role names or ids. First parameter is can be role name(s) or id(s), second parameter is boolean. If withPermissions is true, it will preload the permissions to the roles. @param interface{} @param bool @return collections.Role, error

func (*Permify) GetRolesOfUser ΒΆ

func (s *Permify) GetRolesOfUser(userID uint, option options.RoleOption) (roles collections.Role, totalCount int64, err error)

GetRolesOfUser fetch all the roles of the user. (with pagination option). If withPermissions is true, it will preload the permissions to the role. First parameter is user id, second parameter is role option. @param uint @param options.RoleOption @return collections.Role, int64, error

func (*Permify) RemovePermissionsFromRole ΒΆ

func (s *Permify) RemovePermissionsFromRole(r interface{}, p interface{}) (err error)

RemovePermissionsFromRole remove permissions from role according to the permission names or ids. First parameter can be role name or id, second parameter can be permission name(s) or id(s). If the first parameter is an array, the first element of the first parameter is used. @param interface{} @param interface{} @return error

func (*Permify) RemovePermissionsFromUser ΒΆ

func (s *Permify) RemovePermissionsFromUser(userID uint, p interface{}) (err error)

RemovePermissionsFromUser remove direct permissions from user according to the permission names or ids. First parameter is the user id, second parameter is can be permission name(s) or id(s). @param uint @param interface{} @return error

func (*Permify) RemoveRolesFromUser ΒΆ

func (s *Permify) RemoveRolesFromUser(userID uint, r interface{}) (err error)

RemoveRolesFromUser remove roles from user according to the role names or ids. First parameter is the user id, second parameter is can be role name(s) or id(s). @param uint @param interface{} @return error

func (*Permify) ReplacePermissionsToRole ΒΆ

func (s *Permify) ReplacePermissionsToRole(r interface{}, p interface{}) (err error)

ReplacePermissionsToRole overwrites the permissions of the role according to the permission names or ids. First parameter can be role name or id, second parameter can be permission name(s) or id(s). If the first parameter is an array, the first element of the first parameter is used. @param interface{} @param interface{} @return error

func (*Permify) ReplacePermissionsToUser ΒΆ

func (s *Permify) ReplacePermissionsToUser(userID uint, p interface{}) (err error)

ReplacePermissionsToUser overwrites the direct permissions of the user according to the permission names or ids. First parameter is the user id, second parameter is can be permission name(s) or id(s). @param uint @param interface{} @return error

func (*Permify) ReplaceRolesToUser ΒΆ

func (s *Permify) ReplaceRolesToUser(userID uint, r interface{}) (err error)

ReplaceRolesToUser overwrites the roles of the user according to the role names or ids. First parameter is the user id, second parameter is can be role name(s) or id(s). @param uint @param interface{} @return error

func (*Permify) RoleHasAllPermissions ΒΆ

func (s *Permify) RoleHasAllPermissions(r interface{}, p interface{}) (b bool, err error)

RoleHasAllPermissions does the role or roles have all the given permissions? First parameter is can be role name(s) or id(s), second parameter is can be permission name(s) or id(s). @param interface{} @param interface{} @return error

func (*Permify) RoleHasAnyPermissions ΒΆ

func (s *Permify) RoleHasAnyPermissions(r interface{}, p interface{}) (b bool, err error)

RoleHasAnyPermissions does the role or roles have any of the given permissions? First parameter is can be role name(s) or id(s), second parameter is can be permission name(s) or id(s). @param interface{} @param interface{} @return error

func (*Permify) RoleHasPermission ΒΆ

func (s *Permify) RoleHasPermission(r interface{}, p interface{}) (b bool, err error)

RoleHasPermission does the role or any of the roles have given permission? First parameter is can be role name(s) or id(s), second parameter is can be permission name or id. If the second parameter is an array, the first element of the given array is used. @param interface{} @param interface{} @return error

func (*Permify) UserHasAllDirectPermissions ΒΆ

func (s *Permify) UserHasAllDirectPermissions(userID uint, p interface{}) (b bool, err error)

UserHasAllDirectPermissions does the user have all the given permissions? (not including the permissions of the roles) First parameter is the user id, second parameter is can be permission name(s) or id(s). @param uint @param interface{} @return bool, error

func (*Permify) UserHasAllPermissions ΒΆ

func (s *Permify) UserHasAllPermissions(userID uint, p interface{}) (b bool, err error)

UserHasAllPermissions does the user have all the given permissions? (including the permissions of the roles). First parameter is the user id, second parameter is can be permission name(s) or id(s). @param uint @param interface{} @return bool, error

func (*Permify) UserHasAllRoles ΒΆ

func (s *Permify) UserHasAllRoles(userID uint, r interface{}) (b bool, err error)

UserHasAllRoles does the user have all the given roles? First parameter is the user id, second parameter is can be role name(s) or id(s). @param uint @param interface{} @return bool, error

func (*Permify) UserHasAnyDirectPermissions ΒΆ

func (s *Permify) UserHasAnyDirectPermissions(userID uint, p interface{}) (b bool, err error)

UserHasAnyDirectPermissions does the user have any of the given permissions? (not including the permissions of the roles) First parameter is the user id, second parameter is can be permission name(s) or id(s). @param uint @param interface{} @return bool, error

func (*Permify) UserHasAnyPermissions ΒΆ

func (s *Permify) UserHasAnyPermissions(userID uint, p interface{}) (b bool, err error)

UserHasAnyPermissions does the user have any of the given permissions? (including the permissions of the roles). First parameter is the user id, second parameter is can be permission name(s) or id(s). @param uint @param interface{} @return bool, error

func (*Permify) UserHasAnyRoles ΒΆ

func (s *Permify) UserHasAnyRoles(userID uint, r interface{}) (b bool, err error)

UserHasAnyRoles does the user have any of the given roles? First parameter is the user id, second parameter is can be role name(s) or id(s). @param uint @param interface{} @return bool, error

func (*Permify) UserHasDirectPermission ΒΆ

func (s *Permify) UserHasDirectPermission(userID uint, p interface{}) (b bool, err error)

UserHasDirectPermission does the user have the given permission? (not including the permissions of the roles) First parameter is the user id, second parameter is can be permission name or id. If the second parameter is an array, the first element of the given array is used. @param uint @param interface{} @return bool, error

func (*Permify) UserHasPermission ΒΆ

func (s *Permify) UserHasPermission(userID uint, p interface{}) (b bool, err error)

UserHasPermission does the user have the given permission? (including the permissions of the roles) First parameter is the user id, second parameter is can be permission name or id. If the second parameter is an array, the first element of the given array is used. @param uint @param interface{} @return bool, error

func (*Permify) UserHasRole ΒΆ

func (s *Permify) UserHasRole(userID uint, r interface{}) (b bool, err error)

UserHasRole does the user have the given role? First parameter is the user id, second parameter is can be role name or id. If the second parameter is an array, the first element of the given array is used. @param uint @param interface{} @return bool, error

Directories ΒΆ

Path Synopsis

Jump to

Keyboard shortcuts

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