package client import ( "context" "github.com/ory/fosite" "github.com/ory/x/errorsx" "edge-infra.dev/pkg/edge/iam/prometheus" "edge-infra.dev/pkg/edge/iam/session" "edge-infra.dev/pkg/edge/iam/util" ) const clientCredentials = "client_credentials" type RolesHandler struct { ClientStorage Storage metrics *prometheus.Metrics } func (h *RolesHandler) CanHandleTokenEndpointRequest(requester fosite.AccessRequester) bool { return requester.GetGrantTypes().ExactOne(clientCredentials) } func (h *RolesHandler) HandleTokenEndpointRequest(ctx context.Context, requester fosite.AccessRequester) error { // make sure we should handle the request... if !h.CanHandleTokenEndpointRequest(requester) { return errorsx.WithStack(fosite.ErrUnknownRequest) } h.metrics.IncHTTPRequestsTotal(clientCredentials) client := requester.GetClient() subject := client.GetID() //grab the client profile from the storage clientProfile, err := h.ClientStorage.GetIAMClient(ctx, subject) if err != nil { return errorsx.WithStack(fosite.ErrInvalidRequest.WithHint("client was not found")) } // encode the client roles into bsl format serializedRoles, err := util.Serialize(clientProfile.GetRoles()) if err != nil { // error occurred while trying to serialize the client roles return errorsx.WithStack(fosite.ErrServerError.WithHint(err.Error())) } // set the roles on the session session.FromRequester(requester).SetRls(serializedRoles) // set the sub on the session session.FromRequester(requester).SetSubject(subject) return nil } func (h *RolesHandler) PopulateTokenEndpointResponse(_ context.Context, requester fosite.AccessRequester, _ fosite.AccessResponder) (err error) { if !h.CanHandleTokenEndpointRequest(requester) { return errorsx.WithStack(fosite.ErrUnknownRequest) } // client credentials are successful h.metrics.IncSignInRequestsTotal(clientCredentials, util.Succeeded) return nil } // CanSkipClientAuth makes sure we only allow authenticated clients func (h *RolesHandler) CanSkipClientAuth(_ fosite.AccessRequester) bool { return false }