rbac system first stage
This commit is contained in:
154
internal/db/permission.go
Normal file
154
internal/db/permission.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"git.haelnorr.com/h/oslstats/internal/permissions"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
type Permission struct {
|
||||
bun.BaseModel `bun:"table:permissions,alias:p"`
|
||||
|
||||
ID int `bun:"id,pk,autoincrement"`
|
||||
Name permissions.Permission `bun:"name,unique,notnull"`
|
||||
DisplayName string `bun:"display_name,notnull"`
|
||||
Description string `bun:"description"`
|
||||
Resource string `bun:"resource,notnull"`
|
||||
Action string `bun:"action,notnull"`
|
||||
IsSystem bool `bun:"is_system,default:false"`
|
||||
CreatedAt int64 `bun:"created_at,notnull"`
|
||||
}
|
||||
|
||||
// GetPermissionByName queries the database for a permission matching the given name
|
||||
// Returns nil, nil if no permission is found
|
||||
func GetPermissionByName(ctx context.Context, tx bun.Tx, name permissions.Permission) (*Permission, error) {
|
||||
if name == "" {
|
||||
return nil, errors.New("name cannot be empty")
|
||||
}
|
||||
|
||||
perm := new(Permission)
|
||||
err := tx.NewSelect().
|
||||
Model(perm).
|
||||
Where("name = ?", name).
|
||||
Limit(1).
|
||||
Scan(ctx)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "tx.NewSelect")
|
||||
}
|
||||
return perm, nil
|
||||
}
|
||||
|
||||
// GetPermissionByID queries the database for a permission matching the given ID
|
||||
// Returns nil, nil if no permission is found
|
||||
func GetPermissionByID(ctx context.Context, tx bun.Tx, id int) (*Permission, error) {
|
||||
if id <= 0 {
|
||||
return nil, errors.New("id must be positive")
|
||||
}
|
||||
|
||||
perm := new(Permission)
|
||||
err := tx.NewSelect().
|
||||
Model(perm).
|
||||
Where("id = ?", id).
|
||||
Limit(1).
|
||||
Scan(ctx)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "tx.NewSelect")
|
||||
}
|
||||
return perm, nil
|
||||
}
|
||||
|
||||
// GetPermissionsByResource queries for all permissions for a given resource
|
||||
func GetPermissionsByResource(ctx context.Context, tx bun.Tx, resource string) ([]*Permission, error) {
|
||||
if resource == "" {
|
||||
return nil, errors.New("resource cannot be empty")
|
||||
}
|
||||
|
||||
var perms []*Permission
|
||||
err := tx.NewSelect().
|
||||
Model(&perms).
|
||||
Where("resource = ?", resource).
|
||||
Order("action ASC").
|
||||
Scan(ctx)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "tx.NewSelect")
|
||||
}
|
||||
return perms, nil
|
||||
}
|
||||
|
||||
// GetPermissionsByIDs queries for permissions matching the given IDs
|
||||
func GetPermissionsByIDs(ctx context.Context, tx bun.Tx, ids []int) ([]*Permission, error) {
|
||||
if len(ids) == 0 {
|
||||
return []*Permission{}, nil
|
||||
}
|
||||
|
||||
var perms []*Permission
|
||||
err := tx.NewSelect().
|
||||
Model(&perms).
|
||||
Where("id IN (?)", bun.In(ids)).
|
||||
Scan(ctx)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "tx.NewSelect")
|
||||
}
|
||||
return perms, nil
|
||||
}
|
||||
|
||||
// ListAllPermissions returns all permissions
|
||||
func ListAllPermissions(ctx context.Context, tx bun.Tx) ([]*Permission, error) {
|
||||
var perms []*Permission
|
||||
err := tx.NewSelect().
|
||||
Model(&perms).
|
||||
Order("resource ASC", "action ASC").
|
||||
Scan(ctx)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "tx.NewSelect")
|
||||
}
|
||||
return perms, nil
|
||||
}
|
||||
|
||||
// CreatePermission creates a new permission
|
||||
func CreatePermission(ctx context.Context, tx bun.Tx, perm *Permission) error {
|
||||
if perm == nil {
|
||||
return errors.New("permission cannot be nil")
|
||||
}
|
||||
|
||||
_, err := tx.NewInsert().
|
||||
Model(perm).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "tx.NewInsert")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeletePermission deletes a permission (checks IsSystem protection)
|
||||
func DeletePermission(ctx context.Context, tx bun.Tx, id int) error {
|
||||
if id <= 0 {
|
||||
return errors.New("id must be positive")
|
||||
}
|
||||
|
||||
// Check if permission is system permission
|
||||
perm, err := GetPermissionByID(ctx, tx, id)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetPermissionByID")
|
||||
}
|
||||
if perm == nil {
|
||||
return errors.New("permission not found")
|
||||
}
|
||||
if perm.IsSystem {
|
||||
return errors.New("cannot delete system permission")
|
||||
}
|
||||
|
||||
_, err = tx.NewDelete().
|
||||
Model((*Permission)(nil)).
|
||||
Where("id = ?", id).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "tx.NewDelete")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user