102 lines
3.6 KiB
Go
102 lines
3.6 KiB
Go
package native
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/tech/sendico/pkg/auth/internal/native/nstructures"
|
|
"github.com/tech/sendico/pkg/merrors"
|
|
"github.com/tech/sendico/pkg/mlogger"
|
|
"github.com/tech/sendico/pkg/model"
|
|
"github.com/tech/sendico/pkg/mutil/mzap"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// PermissionManager manages permissions using Casbin.
|
|
type PermissionManager struct {
|
|
logger mlogger.Logger
|
|
enforcer *Enforcer
|
|
}
|
|
|
|
// GrantToRole adds a permission to a role in Casbin.
|
|
func (m *PermissionManager) GrantToRole(ctx context.Context, policy *model.RolePolicy) error {
|
|
objRef := "any"
|
|
if (policy.ObjectRef != nil) && (*policy.ObjectRef != primitive.NilObjectID) {
|
|
objRef = policy.ObjectRef.Hex()
|
|
}
|
|
|
|
m.logger.Debug("Granting permission to role", mzap.ObjRef("role_ref", policy.RoleDescriptionRef),
|
|
mzap.ObjRef("permission_ref", policy.DescriptionRef), zap.String("object_ref", objRef),
|
|
zap.String("action", string(policy.Effect.Action)), zap.String("effect", string(policy.Effect.Effect)),
|
|
)
|
|
|
|
assignment := nstructures.PolicyAssignment{
|
|
Policy: policy.Policy,
|
|
RoleRef: policy.RoleDescriptionRef,
|
|
}
|
|
if err := m.enforcer.pdb.Create(ctx, &assignment); err != nil {
|
|
m.logger.Warn("Failed to grant policy", zap.Error(err), mzap.ObjRef("role_ref", policy.RoleDescriptionRef),
|
|
mzap.ObjRef("permission_ref", policy.DescriptionRef), zap.String("object_ref", objRef),
|
|
zap.String("action", string(policy.Effect.Action)), zap.String("effect", string(policy.Effect.Effect)))
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RevokeFromRole removes a permission from a role in Casbin.
|
|
func (m *PermissionManager) RevokeFromRole(ctx context.Context, policy *model.RolePolicy) error {
|
|
objRef := "*"
|
|
if policy.ObjectRef != nil {
|
|
objRef = policy.ObjectRef.Hex()
|
|
}
|
|
m.logger.Debug("Revoking permission from role", mzap.ObjRef("role_ref", policy.RoleDescriptionRef),
|
|
mzap.ObjRef("permission_ref", policy.DescriptionRef), zap.String("object_ref", objRef),
|
|
zap.String("action", string(policy.Effect.Action)), zap.String("effect", string(policy.Effect.Effect)),
|
|
)
|
|
if err := m.enforcer.pdb.Remove(ctx, policy); err != nil {
|
|
m.logger.Warn("Failed to revoke policy", zap.Error(err), mzap.ObjRef("role_ref", policy.RoleDescriptionRef),
|
|
mzap.ObjRef("permission_ref", policy.DescriptionRef), zap.String("object_ref", objRef),
|
|
zap.String("action", string(policy.Effect.Action)), zap.String("effect", string(policy.Effect.Effect)))
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetPolicies retrieves all policies for a specific role.
|
|
func (m *PermissionManager) GetPolicies(
|
|
ctx context.Context,
|
|
roleRef primitive.ObjectID,
|
|
) ([]model.RolePolicy, error) {
|
|
m.logger.Debug("Fetching policies for role", mzap.ObjRef("role_ref", roleRef))
|
|
|
|
assinments, err := m.enforcer.pdb.PoliciesForRole(ctx, roleRef)
|
|
if errors.Is(err, merrors.ErrNoData) {
|
|
m.logger.Debug("No policies found", mzap.ObjRef("role_ref", roleRef))
|
|
return []model.RolePolicy{}, nil
|
|
}
|
|
policies := make([]model.RolePolicy, len(assinments))
|
|
for i, assinment := range assinments {
|
|
policies[i] = model.RolePolicy{
|
|
Policy: assinment.Policy,
|
|
RoleDescriptionRef: assinment.RoleRef,
|
|
}
|
|
}
|
|
m.logger.Debug("Policies fetched successfully", mzap.ObjRef("role_ref", roleRef), zap.Int("count", len(policies)))
|
|
return policies, nil
|
|
}
|
|
|
|
// Save persists changes to the Casbin policy store.
|
|
func (m *PermissionManager) Save() error {
|
|
m.logger.Info("Policies successfully saved") // do nothing
|
|
return nil
|
|
}
|
|
|
|
func NewPermissionManager(logger mlogger.Logger, enforcer *Enforcer) *PermissionManager {
|
|
return &PermissionManager{
|
|
logger: logger.Named("permission"),
|
|
enforcer: enforcer,
|
|
}
|
|
}
|