fleet/server/mdm/android/service/endpoint_utils.go
Victor Lyuboslavsky c88cc953fb
Refactor endpoint_utils for modularization (#36484)
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 -->
2025-12-31 09:12:00 -06:00

86 lines
2.6 KiB
Go

package service
import (
"context"
"io"
"net/http"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/android"
platform_http "github.com/fleetdm/fleet/v4/server/platform/http"
"github.com/fleetdm/fleet/v4/server/service/middleware/auth"
eu "github.com/fleetdm/fleet/v4/server/service/middleware/endpoint_utils"
"github.com/go-json-experiment/json"
"github.com/go-json-experiment/json/jsontext"
"github.com/go-kit/kit/endpoint"
kithttp "github.com/go-kit/kit/transport/http"
"github.com/gorilla/mux"
)
func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
return eu.EncodeCommonResponse(ctx, w, response,
func(w http.ResponseWriter, response interface{}) error {
return json.MarshalWrite(w, response, jsontext.WithIndent(" "))
},
nil, // no domain-specific error encoder
)
}
func makeDecoder(iface interface{}) kithttp.DecodeRequestFunc {
return eu.MakeDecoder(iface, func(body io.Reader, req any) error {
return json.UnmarshalRead(body, req)
}, nil, nil, nil, nil)
}
// handlerFunc is the handler function type for Android service endpoints.
type handlerFunc func(ctx context.Context, request any, svc android.Service) fleet.Errorer
// Compile-time check to ensure that endpointer implements Endpointer.
var _ eu.Endpointer[handlerFunc] = &endpointer{}
type endpointer struct {
svc android.Service
}
func (e *endpointer) CallHandlerFunc(f handlerFunc, ctx context.Context, request any,
svc any) (platform_http.Errorer, error) {
return f(ctx, request, svc.(android.Service)), nil
}
func (e *endpointer) Service() any {
return e.svc
}
func newUserAuthenticatedEndpointer(fleetSvc fleet.Service, svc android.Service, opts []kithttp.ServerOption, r *mux.Router,
versions ...string) *eu.CommonEndpointer[handlerFunc] {
return &eu.CommonEndpointer[handlerFunc]{
EP: &endpointer{
svc: svc,
},
MakeDecoderFn: makeDecoder,
EncodeFn: encodeResponse,
Opts: opts,
AuthMiddleware: func(next endpoint.Endpoint) endpoint.Endpoint {
return auth.AuthenticatedUser(fleetSvc, next)
},
Router: r,
Versions: versions,
}
}
func newNoAuthEndpointer(fleetSvc fleet.Service, svc android.Service, opts []kithttp.ServerOption, r *mux.Router,
versions ...string) *eu.CommonEndpointer[handlerFunc] {
return &eu.CommonEndpointer[handlerFunc]{
EP: &endpointer{
svc: svc,
},
MakeDecoderFn: makeDecoder,
EncodeFn: encodeResponse,
Opts: opts,
AuthMiddleware: func(next endpoint.Endpoint) endpoint.Endpoint {
return auth.UnauthenticatedRequest(fleetSvc, next)
},
Router: r,
Versions: versions,
}
}