48 lines
1.2 KiB
Go
48 lines
1.2 KiB
Go
package verification
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.sendico.io/tech/sxchnge/bff/pkg/merrors"
|
|
)
|
|
|
|
func (db *verificationDB) reserveIssuance(ctx context.Context, request *Request, now time.Time) error {
|
|
if len(request.IssuanceLimits) == 0 {
|
|
return nil
|
|
}
|
|
if db.limits == nil {
|
|
return merrors.ServiceUnavailable("verification rate-limit storage is unavailable")
|
|
}
|
|
for _, limit := range request.IssuanceLimits {
|
|
scopeKind := strings.TrimSpace(limit.ScopeKind)
|
|
if scopeKind == "" || strings.TrimSpace(limit.ScopeHash) == "" || limit.Limit < 1 ||
|
|
limit.WindowStart.IsZero() || !limit.ExpiresAt.After(limit.WindowStart) {
|
|
return merrors.InvalidArgument("invalid verification issuance limit", "issuanceLimits")
|
|
}
|
|
count, err := db.limits.Increment(
|
|
ctx,
|
|
scopeKind,
|
|
limit.ScopeHash,
|
|
limit.WindowStart,
|
|
limit.ExpiresAt,
|
|
)
|
|
if err != nil {
|
|
return merrors.OpaqueWrap(
|
|
merrors.ErrServiceUnavailable,
|
|
err,
|
|
"failed to reserve verification issuance capacity",
|
|
)
|
|
}
|
|
if count > limit.Limit {
|
|
retryAfter := limit.ExpiresAt.Sub(now)
|
|
if retryAfter < time.Second {
|
|
retryAfter = time.Second
|
|
}
|
|
return ErrorIssuanceRateLimited(scopeKind, retryAfter)
|
|
}
|
|
}
|
|
return nil
|
|
}
|