mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 13:37:30 +00:00
Resolves #37192 Separating generic endpoint_utils middleware logic from domain-specific business logic. New bounded contexts would share the generic logic and implement their own domain-specific logic. The two approaches used in this PR are: - Use common `platform` types - Use interfaces In the next PR we will move `endpointer_utils`, `authzcheck` and `ratelimit` into `platform` directory. # Checklist for submitter - [x] Added changes file ## Testing - [x] Added/updated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Restructured internal error handling and context management to support bounded context architecture. * Improved error context collection and telemetry observability through a provider-based mechanism. * Decoupled licensing and authentication concerns into interfaces for better modularity. * **Chores** * Updated internal package dependencies to align with new architectural boundaries. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
60 lines
2.2 KiB
Go
60 lines
2.2 KiB
Go
// Package authzcheck implements a middleware that ensures that an authorization
|
|
// check was performed. This does not ensure that the correct authorization
|
|
// check was performed, but offers a backstop in case that a developer misses a
|
|
// check.
|
|
package authzcheck
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
authz_ctx "github.com/fleetdm/fleet/v4/server/contexts/authz"
|
|
platform_http "github.com/fleetdm/fleet/v4/server/platform/http"
|
|
"github.com/go-kit/kit/endpoint"
|
|
)
|
|
|
|
// Middleware is the authzcheck middleware type.
|
|
type Middleware struct{}
|
|
|
|
// NewMiddleware returns a new authzcheck middleware.
|
|
func NewMiddleware() *Middleware {
|
|
return &Middleware{}
|
|
}
|
|
|
|
func (m *Middleware) AuthzCheck() endpoint.Middleware {
|
|
return func(next endpoint.Endpoint) endpoint.Endpoint {
|
|
return func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
authzctx := &authz_ctx.AuthorizationContext{}
|
|
ctx = authz_ctx.NewContext(ctx, authzctx)
|
|
|
|
response, err := next(ctx, req)
|
|
|
|
// If authentication check failed, return that error (so that we log
|
|
// appropriately).
|
|
var authFailedError *platform_http.AuthFailedError
|
|
var authRequiredError *platform_http.AuthRequiredError
|
|
var authHeaderRequiredError *platform_http.AuthHeaderRequiredError
|
|
if errors.As(err, &authFailedError) ||
|
|
errors.As(err, &authRequiredError) ||
|
|
errors.As(err, &authHeaderRequiredError) ||
|
|
errors.Is(err, platform_http.ErrPasswordResetRequired) {
|
|
return nil, err
|
|
}
|
|
|
|
// TODO(mna): currently, any error detected before an authorization check gets
|
|
// lost and the response is always Unauthorized because of the following condition.
|
|
// I _think_ it would be safe to check here of response.error() returns a non-nil
|
|
// error and if so, leave that error go through instead of returning a check missing
|
|
// authorization error. To look into when addressing #4406.
|
|
|
|
// If authorization was not checked, return a response that will
|
|
// marshal to a generic error and log that the check was missed.
|
|
if !authzctx.Checked() {
|
|
// Getting to here means there is an authorization-related bug in our code.
|
|
return nil, platform_http.CheckMissingWithResponse(response)
|
|
}
|
|
|
|
return response, err
|
|
}
|
|
}
|
|
}
|