Mise en place d'un système de vérification des autorisations côté
serveur - Création d'un service d'autorisation dynamique basé sur des "voter" (à la Symfony) - Mise en place des autorisations sur les principales queries/mutations de l'API GraphQL
This commit is contained in:
13
internal/model/action.go
Normal file
13
internal/model/action.go
Normal file
@ -0,0 +1,13 @@
|
||||
package model
|
||||
|
||||
type Action string
|
||||
|
||||
const (
|
||||
ActionCreate Action = "create"
|
||||
ActionRead Action = "read"
|
||||
ActionUpdate Action = "update"
|
||||
ActionDelete Action = "delete"
|
||||
ActionJoin Action = "join"
|
||||
ActionLeave Action = "leave"
|
||||
ActionClose Action = "close"
|
||||
)
|
@ -88,6 +88,17 @@ func (r *DSFRepository) updateFromChanges(dsf *DecisionSupportFile, changes *Dec
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *DSFRepository) Find(ctx context.Context, id string) (*DecisionSupportFile, error) {
|
||||
dsf := &DecisionSupportFile{}
|
||||
query := r.db.Model(dsf).Preload("Workgroup").Where("id = ?", id)
|
||||
|
||||
if err := query.First(&dsf).Error; err != nil {
|
||||
return nil, errs.WithStack(err)
|
||||
}
|
||||
|
||||
return dsf, nil
|
||||
}
|
||||
|
||||
func (r *DSFRepository) Search(ctx context.Context, filter *DecisionSupportFileFilter) ([]*DecisionSupportFile, error) {
|
||||
query := r.db.Model(&DecisionSupportFile{}).Preload("Workgroup")
|
||||
|
||||
|
48
internal/model/dsf_voter.go
Normal file
48
internal/model/dsf_voter.go
Normal file
@ -0,0 +1,48 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"forge.cadoles.com/Cadoles/daddy/internal/voter"
|
||||
)
|
||||
|
||||
type DecisionSupportFileVoter struct {
|
||||
}
|
||||
|
||||
func (v *DecisionSupportFileVoter) Vote(ctx context.Context, subject interface{}, obj interface{}, act interface{}) (voter.Decision, error) {
|
||||
user, ok := subject.(*User)
|
||||
if !ok {
|
||||
return voter.Abstain, nil
|
||||
}
|
||||
|
||||
dsf, ok := obj.(*DecisionSupportFile)
|
||||
if !ok {
|
||||
return voter.Abstain, nil
|
||||
}
|
||||
|
||||
action, ok := act.(Action)
|
||||
if !ok {
|
||||
return voter.Abstain, nil
|
||||
}
|
||||
|
||||
switch action {
|
||||
case ActionCreate:
|
||||
return voter.Allow, nil
|
||||
case ActionRead:
|
||||
return voter.Allow, nil
|
||||
case ActionUpdate:
|
||||
if inWorkgroup(user, dsf.Workgroup) {
|
||||
return voter.Allow, nil
|
||||
}
|
||||
|
||||
return voter.Deny, nil
|
||||
case ActionDelete:
|
||||
return voter.Deny, nil
|
||||
}
|
||||
|
||||
return voter.Abstain, nil
|
||||
}
|
||||
|
||||
func NewDecisionSupportFileVoter() *DecisionSupportFileVoter {
|
||||
return &DecisionSupportFileVoter{}
|
||||
}
|
15
internal/model/helper.go
Normal file
15
internal/model/helper.go
Normal file
@ -0,0 +1,15 @@
|
||||
package model
|
||||
|
||||
func inWorkgroup(user *User, workgroup *Workgroup) bool {
|
||||
if workgroup == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, w := range user.Workgroups {
|
||||
if w.ID == workgroup.ID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/pkg/errors"
|
||||
errs "github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type WorkgroupRepository struct {
|
||||
@ -135,6 +136,17 @@ func (r *WorkgroupRepository) RemoveUserFromWorkgroup(ctx context.Context, userI
|
||||
return workgroup, nil
|
||||
}
|
||||
|
||||
func (r *WorkgroupRepository) Find(ctx context.Context, id string) (*Workgroup, error) {
|
||||
wg := &Workgroup{}
|
||||
query := r.db.Model(wg).Where("id = ?", id)
|
||||
|
||||
if err := query.First(&wg).Error; err != nil {
|
||||
return nil, errs.WithStack(err)
|
||||
}
|
||||
|
||||
return wg, nil
|
||||
}
|
||||
|
||||
func NewWorkgroupRepository(db *gorm.DB) *WorkgroupRepository {
|
||||
return &WorkgroupRepository{db}
|
||||
}
|
||||
|
54
internal/model/workgroup_voter.go
Normal file
54
internal/model/workgroup_voter.go
Normal file
@ -0,0 +1,54 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"forge.cadoles.com/Cadoles/daddy/internal/voter"
|
||||
)
|
||||
|
||||
type WorkgroupVoter struct {
|
||||
}
|
||||
|
||||
func (v *WorkgroupVoter) Vote(ctx context.Context, subject interface{}, obj interface{}, act interface{}) (voter.Decision, error) {
|
||||
user, ok := subject.(*User)
|
||||
if !ok {
|
||||
return voter.Abstain, nil
|
||||
}
|
||||
|
||||
workgroup, ok := obj.(*Workgroup)
|
||||
if !ok {
|
||||
return voter.Abstain, nil
|
||||
}
|
||||
|
||||
action, ok := act.(Action)
|
||||
if !ok {
|
||||
return voter.Abstain, nil
|
||||
}
|
||||
|
||||
switch action {
|
||||
case ActionCreate:
|
||||
return voter.Allow, nil
|
||||
case ActionRead:
|
||||
return voter.Allow, nil
|
||||
case ActionJoin:
|
||||
return voter.Allow, nil
|
||||
case ActionLeave:
|
||||
fallthrough
|
||||
case ActionUpdate:
|
||||
fallthrough
|
||||
case ActionClose:
|
||||
if inWorkgroup(user, workgroup) {
|
||||
return voter.Allow, nil
|
||||
} else {
|
||||
return voter.Deny, nil
|
||||
}
|
||||
case ActionDelete:
|
||||
return voter.Deny, nil
|
||||
}
|
||||
|
||||
return voter.Abstain, nil
|
||||
}
|
||||
|
||||
func NewWorkgroupVoter() *WorkgroupVoter {
|
||||
return &WorkgroupVoter{}
|
||||
}
|
Reference in New Issue
Block a user