big ole refactor
This commit is contained in:
99
internal/db/rolepermission.go
Normal file
99
internal/db/rolepermission.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
type RolePermission struct {
|
||||
RoleID int `bun:",pk"`
|
||||
Role *Role `bun:"rel:belongs-to,join:role_id=id"`
|
||||
PermissionID int `bun:",pk"`
|
||||
Permission *Permission `bun:"rel:belongs-to,join:permission_id=id"`
|
||||
}
|
||||
|
||||
func (r *Role) UpdatePermissions(ctx context.Context, tx bun.Tx, newPermissionsIDs []int, audit *AuditMeta) error {
|
||||
addPerms, removePerms, err := detectChangedPermissions(ctx, tx, r, newPermissionsIDs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "detectChangedPermissions")
|
||||
}
|
||||
addedPerms := []string{}
|
||||
removedPerms := []string{}
|
||||
for _, perm := range addPerms {
|
||||
rolePerm := &RolePermission{
|
||||
RoleID: r.ID,
|
||||
PermissionID: perm.ID,
|
||||
}
|
||||
err := Insert(tx, rolePerm).
|
||||
ConflictNothing("role_id", "permission_id").
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "db.Insert")
|
||||
}
|
||||
addedPerms = append(addedPerms, perm.Name.String())
|
||||
}
|
||||
for _, perm := range removePerms {
|
||||
err := DeleteItem[RolePermission](tx).
|
||||
Where("role_id = ?", r.ID).
|
||||
Where("permission_id = ?", perm.ID).
|
||||
Delete(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "DeleteItem")
|
||||
}
|
||||
removedPerms = append(removedPerms, perm.Name.String())
|
||||
}
|
||||
// Log the permission changes
|
||||
if len(addedPerms) > 0 || len(removedPerms) > 0 {
|
||||
details := map[string]any{
|
||||
"role_name": string(r.Name),
|
||||
}
|
||||
if len(addedPerms) > 0 {
|
||||
details["added_permissions"] = addedPerms
|
||||
}
|
||||
if len(removedPerms) > 0 {
|
||||
details["removed_permissions"] = removedPerms
|
||||
}
|
||||
info := &AuditInfo{
|
||||
"roles.update_permissions",
|
||||
"role",
|
||||
r.ID,
|
||||
details,
|
||||
}
|
||||
err = LogSuccess(ctx, tx, audit, info)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "LogSuccess")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func detectChangedPermissions(ctx context.Context, tx bun.Tx, role *Role, permissionIDs []int) ([]*Permission, []*Permission, error) {
|
||||
allPermissions, err := ListAllPermissions(ctx, tx)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "ListAllPermissions")
|
||||
}
|
||||
// Build map of current permissions
|
||||
currentPermIDs := make(map[int]bool)
|
||||
for _, perm := range role.Permissions {
|
||||
currentPermIDs[perm.ID] = true
|
||||
}
|
||||
|
||||
var addedPerms []*Permission
|
||||
var removedPerms []*Permission
|
||||
|
||||
// Determine what to add and remove
|
||||
for _, perm := range allPermissions {
|
||||
hasNow := currentPermIDs[perm.ID]
|
||||
shouldHave := slices.Contains(permissionIDs, perm.ID)
|
||||
|
||||
if shouldHave && !hasNow {
|
||||
addedPerms = append(addedPerms, perm)
|
||||
} else if !shouldHave && hasNow {
|
||||
removedPerms = append(removedPerms, perm)
|
||||
}
|
||||
}
|
||||
return addedPerms, removedPerms, nil
|
||||
}
|
||||
Reference in New Issue
Block a user