Ajout d'un filtre de connexion configurable pour l'utilisateur
This commit is contained in:
71
internal/auth/auth.go
Normal file
71
internal/auth/auth.go
Normal file
@ -0,0 +1,71 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"forge.cadoles.com/Cadoles/daddy/internal/model"
|
||||
"github.com/antonmedv/expr"
|
||||
"github.com/antonmedv/expr/vm"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnexpectedRuleResult = errors.New("unexpected rule result")
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
rules []*vm.Program
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (s *Service) LoadRules(rawRules ...string) error {
|
||||
rules := make([]*vm.Program, 0, len(rawRules))
|
||||
|
||||
for _, rr := range rawRules {
|
||||
r, err := expr.Compile(rr)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
rules = append(rules, r)
|
||||
}
|
||||
|
||||
s.mutex.Lock()
|
||||
s.rules = rules
|
||||
s.mutex.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) Authorize(user *model.User) (bool, error) {
|
||||
s.mutex.RLock()
|
||||
defer s.mutex.RUnlock()
|
||||
|
||||
env := map[string]interface{}{
|
||||
"user": user,
|
||||
}
|
||||
|
||||
for _, r := range s.rules {
|
||||
result, err := expr.Run(r, env)
|
||||
if err != nil {
|
||||
return false, errors.WithStack(err)
|
||||
}
|
||||
|
||||
authorized, ok := result.(bool)
|
||||
if !ok {
|
||||
return false, errors.WithStack(ErrUnexpectedRuleResult)
|
||||
}
|
||||
|
||||
if !authorized {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func NewService() *Service {
|
||||
return &Service{
|
||||
rules: make([]*vm.Program, 0),
|
||||
}
|
||||
}
|
20
internal/auth/provider.go
Normal file
20
internal/auth/provider.go
Normal file
@ -0,0 +1,20 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"gitlab.com/wpetit/goweb/service"
|
||||
)
|
||||
|
||||
func ServiceProvider(rules []string) service.Provider {
|
||||
srv := NewService()
|
||||
|
||||
err := srv.LoadRules(rules...)
|
||||
|
||||
return func(ctn *service.Container) (interface{}, error) {
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return srv, nil
|
||||
}
|
||||
}
|
33
internal/auth/service.go
Normal file
33
internal/auth/service.go
Normal file
@ -0,0 +1,33 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"gitlab.com/wpetit/goweb/service"
|
||||
)
|
||||
|
||||
const ServiceName service.Name = "auth"
|
||||
|
||||
// From retrieves the auth service in the given container.
|
||||
func From(container *service.Container) (*Service, error) {
|
||||
service, err := container.Service(ServiceName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error while retrieving '%s' service", ServiceName)
|
||||
}
|
||||
|
||||
srv, ok := service.(*Service)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("retrieved service is not a valid '%s' service", ServiceName)
|
||||
}
|
||||
|
||||
return srv, nil
|
||||
}
|
||||
|
||||
// Must retrieves the auth service in the given container or panic otherwise.
|
||||
func Must(container *service.Container) *Service {
|
||||
srv, err := From(container)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return srv
|
||||
}
|
Reference in New Issue
Block a user