Skip to content

Commit

Permalink
feat(core): refactored checks into specifics
Browse files Browse the repository at this point in the history
  • Loading branch information
ConsoleTVs committed Nov 10, 2024
1 parent 314a91e commit 440ec70
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 46 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ jobs:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: "1.22"
go-version-file: "go.mod"
cache-dependency-path: "go.sum"

- name: Test
run: go test -v ./...
59 changes: 59 additions & 0 deletions authorizer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package akumu

import (
"errors"
"fmt"
"net/http"
"reflect"
)

type Authorizer interface {
Authorize(request *http.Request) error
}

type AuthorizerFunc func(request *http.Request) error

var (
ErrAuthorizationFailed = errors.New("authorization failed")
ErrInvalidAuthorizerInContext = errors.New("invalid authorizer in context")
ErrAuthorizerNotFoundInContext = errors.New("authorizer not found in context")
)

func (authorizer AuthorizerFunc) Authorize(request *http.Request) error {
return authorizer(request)
}

func Authorize[T Authorizer](request *http.Request) error {
return AuthorizeWith(request, *new(T))
}

func AuthorizeFrom(request *http.Request, key any) error {
value := request.Context().Value(key)

if value != nil {
return fmt.Errorf("%w: %s", ErrAuthorizerNotFoundInContext, reflect.TypeOf(key))
}

authorizer, ok := value.(Authorizer)

if !ok {
return fmt.Errorf("%w: %s", ErrInvalidAuthorizerInContext, reflect.TypeOf(key))
}

return AuthorizeWith(request, authorizer)
}

func AuthorizeWith[T Authorizer](request *http.Request, authorizer T) error {
if err := authorizer.Authorize(request); err != nil {
return NewProblem(
errors.Join(ErrAuthorizationFailed, err),
http.StatusForbidden,
)
}

return nil
}

func AuthorizeWithFunc(request *http.Request, authorizer AuthorizerFunc) error {
return AuthorizeWith(request, authorizer)
}
43 changes: 0 additions & 43 deletions check.go

This file was deleted.

27 changes: 27 additions & 0 deletions middleware/authorizer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package middleware

import (
"net/http"

"github.com/studiolambda/akumu"
)

func Authorizer(authorizer akumu.Authorizer) akumu.Middleware {
return func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if err := akumu.AuthorizeWith(request, authorizer); err != nil {
akumu.
Failed(err).
Handle(writer, request)

return
}

handler.ServeHTTP(writer, request)
})
}
}

func AuthorizerFunc(authorizer akumu.AuthorizerFunc) akumu.Middleware {
return Authorizer(authorizer)
}
27 changes: 27 additions & 0 deletions middleware/validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package middleware

import (
"net/http"

"github.com/studiolambda/akumu"
)

func Validator(validator akumu.Validator) akumu.Middleware {
return func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if err := akumu.ValidateWith(request, validator); err != nil {
akumu.
Failed(err).
Handle(writer, request)

return
}

handler.ServeHTTP(writer, request)
})
}
}

func ValidatorFunc(validator akumu.ValidatorFunc) akumu.Middleware {
return Validator(validator)
}
59 changes: 59 additions & 0 deletions validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package akumu

import (
"errors"
"fmt"
"net/http"
"reflect"
)

type Validator interface {
Validate(request *http.Request) error
}

type ValidatorFunc func(request *http.Request) error

var (
ErrValidationFailed = errors.New("validation failed")
ErrInvalidValidatorInContext = errors.New("invalid validator in context")
ErrValidatorNotFoundInContext = errors.New("validator not found in context")
)

func (validator ValidatorFunc) Validate(request *http.Request) error {
return validator(request)
}

func Validate[T Validator](request *http.Request) error {
return ValidateWith(request, *new(T))
}

func ValidateFrom(request *http.Request, key any) error {
value := request.Context().Value(key)

if value != nil {
return fmt.Errorf("%w: %s", ErrValidatorNotFoundInContext, reflect.TypeOf(key))
}

validator, ok := value.(Validator)

if !ok {
return fmt.Errorf("%w: %s", ErrInvalidValidatorInContext, reflect.TypeOf(key))
}

return ValidateWith(request, validator)
}

func ValidateWith[T Validator](request *http.Request, validator T) error {
if err := validator.Validate(request); err != nil {
return NewProblem(
errors.Join(ErrValidationFailed, err),
http.StatusUnprocessableEntity,
)
}

return nil
}

func ValidateWithFunc(request *http.Request, validator ValidatorFunc) error {
return ValidateWith(request, validator)
}

0 comments on commit 440ec70

Please sign in to comment.