Skip to content

feat: add SSS client with Auth0 token caching#5058

Open
psrsingh wants to merge 1 commit into
linuxfoundation:devfrom
psrsingh:feat/sss-client
Open

feat: add SSS client with Auth0 token caching#5058
psrsingh wants to merge 1 commit into
linuxfoundation:devfrom
psrsingh:feat/sss-client

Conversation

@psrsingh
Copy link
Copy Markdown

Summary

Adds a reusable Sanctions Screening Service (SSS) client package for EasyCLA.

Features

  • Auth0 M2M authentication using client credentials flow

  • in-memory token caching with refresh-before-expiry behavior

  • reusable HTTP client with configurable timeout

  • typed response models for SSS organization screening

  • typed error handling for:

    • 400 bad request
    • 401/403 authentication errors
    • 503 retryable service errors
    • request timeouts
  • context-aware requests

  • thread-safe token reuse using mutex protection

Tests

Added mocked HTTP tests using httptest for:

  • clean response
  • flagged response
  • 400 responses
  • 401 responses
  • 503 responses
  • timeout handling
  • token caching reuse
  • expired token refresh

Validation

go test ./sss -v
go test -race ./sss
go test ./sss -cover

Notes

The referenced API documentation files were not present in the repository, so the implementation follows the issue specification and currently uses a provisional organization_id query parameter pending confirmation.

Signed-off-by: psrsingh <psr.singh336@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 16, 2026

Review Change Stack

Walkthrough

This pull request introduces a new Go package sss that implements an HTTP client for querying a Sanctions Screening Service. The client handles Auth0 OAuth2 authentication with token caching, organization status lookups, and comprehensive error handling with retry support and timeout detection.

Changes

Sanctions Screening Service (SSS) Go Client

Layer / File(s) Summary
Type definitions and error contracts
cla-backend-go/sss/types.go, cla-backend-go/sss/errors.go, cla-backend-go/sss/auth.go
SSSConfig and ScreeningResult structs define client configuration and API response shapes; four error types (BadRequestError, AuthError, RetryableError, TimeoutError) implement error interface; internal authRequest and authResponse model Auth0 token payloads.
Client initialization and organization status query
cla-backend-go/sss/client.go (lines 1–116), cla-backend-go/sss/client_test.go (lines 17–173)
Client struct holds HTTP client and token state; NewClient validates Auth0 config and timeout; GetOrganizationStatus builds SSS request URL, adds authorization header using cached token, decodes HTTP 200 responses, and maps HTTP status codes to typed errors; tests verify successful and flagged responses, bad request/auth error mapping.
Token caching and refresh mechanics
cla-backend-go/sss/client.go (lines 118–197), cla-backend-go/sss/client_test.go (lines 250–328)
getToken reuses cached token until one minute before expiry, triggering fetchToken refresh if needed; fetchToken obtains new credentials via Auth0 client-credentials flow, validates access token presence, computes expiry from response; authTokenURL constructs OAuth endpoint from domain; tests verify token reuse across consecutive calls and refresh when tokens expire.
Helper utilities and error handling
cla-backend-go/sss/client.go (lines 199–226), cla-backend-go/sss/client_test.go (lines 175–248)
parseRetryAfter converts HTTP header value to time.Duration (seconds or HTTP-date format); toClientError wraps context timeout and network errors into TimeoutError; tests verify Retry-After duration parsing and timeout detection from slow service responses.

Sequence Diagram

sequenceDiagram
  participant Client
  participant Auth0Service as Auth0 OAuth Token
  participant SSSService as SSS Organization Endpoint
  Client->>Auth0Service: POST /oauth/token (client credentials)
  Auth0Service-->>Client: access_token, expires_in
  Client->>SSSService: GET /organizations/status?organization_id=X<br/>(Authorization: Bearer token)
  SSSService-->>Client: 200 ScreeningResult (status, entityID, source, screened_at)
  Note over Client: or 400/401/503 mapped to<br/>BadRequestError/AuthError/RetryableError
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main feature added: an SSS client with Auth0 token caching, which matches the primary changes across all modified files.
Description check ✅ Passed The description is well-organized and directly related to the changeset, detailing the features, tests, and validation approach for the SSS client package.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cla-backend-go/sss/client.go`:
- Around line 208-210: The parsed Retry-After timestamp may be in the past
causing time.Until(parsedTime) to return a negative duration; update the block
that uses http.ParseTime (the parsedTime handling in sss/client.go) to clamp the
returned duration to a non-negative value—compute d := time.Until(parsedTime)
and return time.Duration(0) if d < 0 else return d—so callers never receive
negative RetryAfter durations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aaca0b5d-8df6-44b3-8128-17f2342fda31

📥 Commits

Reviewing files that changed from the base of the PR and between 355223d and 8e0ab48.

📒 Files selected for processing (5)
  • cla-backend-go/sss/auth.go
  • cla-backend-go/sss/client.go
  • cla-backend-go/sss/client_test.go
  • cla-backend-go/sss/errors.go
  • cla-backend-go/sss/types.go

Comment on lines +208 to +210
if parsedTime, err := http.ParseTime(value); err == nil {
return time.Until(parsedTime)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clamp parsed Retry-After to non-negative duration.

http.ParseTime can yield a past timestamp, returning a negative duration. Exposing negative RetryAfter can cause incorrect retry scheduling.

💡 Proposed fix
 	if parsedTime, err := http.ParseTime(value); err == nil {
-		return time.Until(parsedTime)
+		d := time.Until(parsedTime)
+		if d < 0 {
+			return 0
+		}
+		return d
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if parsedTime, err := http.ParseTime(value); err == nil {
return time.Until(parsedTime)
}
if parsedTime, err := http.ParseTime(value); err == nil {
d := time.Until(parsedTime)
if d < 0 {
return 0
}
return d
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cla-backend-go/sss/client.go` around lines 208 - 210, The parsed Retry-After
timestamp may be in the past causing time.Until(parsedTime) to return a negative
duration; update the block that uses http.ParseTime (the parsedTime handling in
sss/client.go) to clamp the returned duration to a non-negative value—compute d
:= time.Until(parsedTime) and return time.Duration(0) if d < 0 else return d—so
callers never receive negative RetryAfter durations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant