// Copyright (c) Abstract Machines // SPDX-License-Identifier: Apache-2.0 //go:build !test package middleware import ( "context" "time" "github.com/absmach/magistrala/auth" "github.com/absmach/magistrala/pkg/policies" "github.com/go-kit/kit/metrics" ) var _ auth.Service = (*metricsMiddleware)(nil) type metricsMiddleware struct { counter metrics.Counter latency metrics.Histogram svc auth.Service } // NewMetrics instruments service by tracking request count and latency. func NewMetrics(svc auth.Service, counter metrics.Counter, latency metrics.Histogram) auth.Service { return &metricsMiddleware{ counter: counter, latency: latency, svc: svc, } } func (ms *metricsMiddleware) Issue(ctx context.Context, token string, key auth.Key) (auth.Token, error) { defer func(begin time.Time) { ms.counter.With("method", "issue_key").Add(1) ms.latency.With("method", "issue_key").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.Issue(ctx, token, key) } func (ms *metricsMiddleware) RevokeToken(ctx context.Context, userID, tokenID string) error { defer func(begin time.Time) { ms.counter.With("method", "revoke_token").Add(1) ms.latency.With("method", "revoke_token").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RevokeToken(ctx, userID, tokenID) } func (ms *metricsMiddleware) Revoke(ctx context.Context, token, id string) error { defer func(begin time.Time) { ms.counter.With("method", "revoke_key").Add(1) ms.latency.With("method", "revoke_key").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.Revoke(ctx, token, id) } func (ms *metricsMiddleware) RetrieveKey(ctx context.Context, token, id string) (auth.Key, error) { defer func(begin time.Time) { ms.counter.With("method", "retrieve_key").Add(1) ms.latency.With("method", "retrieve_key").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RetrieveKey(ctx, token, id) } func (ms *metricsMiddleware) Identify(ctx context.Context, token string) (auth.Key, error) { defer func(begin time.Time) { ms.counter.With("method", "identify").Add(1) ms.latency.With("method", "identify").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.Identify(ctx, token) } func (ms *metricsMiddleware) RetrieveJWKS() []auth.PublicKeyInfo { defer func(begin time.Time) { ms.counter.With("method", "retrieve_jwks").Add(1) ms.latency.With("method", "retrieve_jwks").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RetrieveJWKS() } func (ms *metricsMiddleware) ListUserRefreshTokens(ctx context.Context, userID string) ([]auth.TokenInfo, error) { defer func(begin time.Time) { ms.counter.With("method", "list_user_refresh_tokens").Add(1) ms.latency.With("method", "list_user_refresh_tokens").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.ListUserRefreshTokens(ctx, userID) } func (ms *metricsMiddleware) Authorize(ctx context.Context, pr policies.Policy, patAuthz *auth.PATAuthz) error { defer func(begin time.Time) { ms.counter.With("method", "authorize").Add(1) ms.latency.With("method", "authorize").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.Authorize(ctx, pr, patAuthz) } func (ms *metricsMiddleware) CreatePAT(ctx context.Context, token, name, description string, duration time.Duration) (auth.PAT, error) { defer func(begin time.Time) { ms.counter.With("method", "create_pat").Add(1) ms.latency.With("method", "create_pat").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.CreatePAT(ctx, token, name, description, duration) } func (ms *metricsMiddleware) UpdatePATName(ctx context.Context, token, patID, name string) (auth.PAT, error) { defer func(begin time.Time) { ms.counter.With("method", "update_pat_name").Add(1) ms.latency.With("method", "update_pat_name").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.UpdatePATName(ctx, token, patID, name) } func (ms *metricsMiddleware) UpdatePATDescription(ctx context.Context, token, patID, description string) (auth.PAT, error) { defer func(begin time.Time) { ms.counter.With("method", "update_pat_description").Add(1) ms.latency.With("method", "update_pat_description").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.UpdatePATDescription(ctx, token, patID, description) } func (ms *metricsMiddleware) RetrievePAT(ctx context.Context, token, patID string) (auth.PAT, error) { defer func(begin time.Time) { ms.counter.With("method", "retrieve_pat").Add(1) ms.latency.With("method", "retrieve_pat").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RetrievePAT(ctx, token, patID) } func (ms *metricsMiddleware) ListPATS(ctx context.Context, token string, pm auth.PATSPageMeta) (auth.PATSPage, error) { defer func(begin time.Time) { ms.counter.With("method", "list_pats").Add(1) ms.latency.With("method", "list_pats").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.ListPATS(ctx, token, pm) } func (ms *metricsMiddleware) ListScopes(ctx context.Context, token string, pm auth.ScopesPageMeta) (auth.ScopesPage, error) { defer func(begin time.Time) { ms.counter.With("method", "list_scopes").Add(1) ms.latency.With("method", "list_scopes").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.ListScopes(ctx, token, pm) } func (ms *metricsMiddleware) DeletePAT(ctx context.Context, token, patID string) error { defer func(begin time.Time) { ms.counter.With("method", "delete_pat").Add(1) ms.latency.With("method", "delete_pat").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.DeletePAT(ctx, token, patID) } func (ms *metricsMiddleware) ResetPATSecret(ctx context.Context, token, patID string, duration time.Duration) (auth.PAT, error) { defer func(begin time.Time) { ms.counter.With("method", "reset_pat_secret").Add(1) ms.latency.With("method", "reset_pat_secret").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.ResetPATSecret(ctx, token, patID, duration) } func (ms *metricsMiddleware) RevokePATSecret(ctx context.Context, token, patID string) error { defer func(begin time.Time) { ms.counter.With("method", "revoke_pat_secret").Add(1) ms.latency.With("method", "revoke_pat_secret").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RevokePATSecret(ctx, token, patID) } func (ms *metricsMiddleware) RemoveAllPAT(ctx context.Context, token string) error { defer func(begin time.Time) { ms.counter.With("method", "clear_all_pat").Add(1) ms.latency.With("method", "clear_all_pat").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RemoveAllPAT(ctx, token) } func (ms *metricsMiddleware) AddScope(ctx context.Context, token, patID string, scopes []auth.Scope) error { defer func(begin time.Time) { ms.counter.With("method", "add_pat_scope").Add(1) ms.latency.With("method", "add_pat_scope").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.AddScope(ctx, token, patID, scopes) } func (ms *metricsMiddleware) RemoveScope(ctx context.Context, token, patID string, scopesID ...string) error { defer func(begin time.Time) { ms.counter.With("method", "remove_pat_scope").Add(1) ms.latency.With("method", "remove_pat_scope").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RemoveScope(ctx, token, patID, scopesID...) } func (ms *metricsMiddleware) RemovePATAllScope(ctx context.Context, token, patID string) error { defer func(begin time.Time) { ms.counter.With("method", "clear_pat_all_scope").Add(1) ms.latency.With("method", "clear_pat_all_scope").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.RemovePATAllScope(ctx, token, patID) } func (ms *metricsMiddleware) IdentifyPAT(ctx context.Context, paToken string) (auth.PAT, error) { defer func(begin time.Time) { ms.counter.With("method", "identify_pat").Add(1) ms.latency.With("method", "identify_pat").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.IdentifyPAT(ctx, paToken) } func (ms *metricsMiddleware) AuthorizePAT(ctx context.Context, userID, patID string, entityType auth.EntityType, domainID string, operation string, entityID string) error { defer func(begin time.Time) { ms.counter.With("method", "authorize_pat").Add(1) ms.latency.With("method", "authorize_pat").Observe(time.Since(begin).Seconds()) }(time.Now()) return ms.svc.AuthorizePAT(ctx, userID, patID, entityType, domainID, operation, entityID) }