Skip to content

Commit 8902ade

Browse files
Merge pull request #5 from mauriciozanettisalomao/feat/lfxv2--492-auth0-user-lookup
[LFX-V2-492] Auth0 user lookup - email_to_username
2 parents 085f5de + 8b4868d commit 8902ade

File tree

25 files changed

+1561
-593
lines changed

25 files changed

+1561
-593
lines changed

README.md

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
# LFX V2 Auth Service
1+
# LFX v2 Auth Service
22

3-
This repository contains the source code for the LFX v2 platform authentication service.
3+
A NATS-based authentication and user management microservice for the LFX v2 platform. This service provides an abstraction layer between applications and identity providers (Auth0 and Authelia).
44

55
## Overview
66

77
The LFX v2 Auth Service provides authentication and profile access in the v2 Platform, serving as an abstraction layer between applications and identity providers (Auth0 and Authelia). This service enables user management, profile updates, email/social account linking, and user discovery while maintaining compatibility across different deployment environments.
88

99
The service operates as a NATS-based microservice, responding to request/reply patterns on specific subjects.
1010

11-
## File Structure
11+
### Prerequisites
12+
- Go 1.24.5+
13+
- NATS server
14+
- Auth0 configuration (optional, defaults to mock mode)
15+
16+
### Installation
1217

1318
```bash
1419
├── .github/ # Github files
@@ -37,7 +42,57 @@ The service operates as a NATS-based microservice, responding to request/reply p
3742

3843
The LFX v2 Auth Service operates as a NATS-based microservice that responds to request/reply patterns on specific subjects. The service provides user management capabilities through NATS messaging.
3944

40-
#### User Update Operations
45+
---
46+
47+
### Email to Username Lookup
48+
49+
To look up a username by email address, send a NATS request to the following subject:
50+
51+
**Subject:** `lfx.auth-service.email_to_username`
52+
**Pattern:** Request/Reply
53+
54+
##### Request Payload
55+
56+
The request payload should be a plain text email address (no JSON wrapping required):
57+
58+
```
59+
user@example.com
60+
```
61+
62+
##### Reply
63+
64+
The service returns the username as plain text if the email is found:
65+
66+
**Success Reply:**
67+
```
68+
john.doe
69+
```
70+
71+
**Error Reply:**
72+
```json
73+
{
74+
"success": false,
75+
"error": "user not found"
76+
}
77+
```
78+
79+
##### Example using NATS CLI
80+
81+
```bash
82+
# Look up username by email
83+
nats request lfx.auth-service.email_to_username zephyr.stormwind@mythicaltech.io
84+
85+
# Expected response: zephyr.stormwind
86+
```
87+
88+
**Important Notes:**
89+
- This service searches for users by their **primary email** only
90+
- Linked/alternate email addresses are **not** supported for lookup
91+
- The service works with both Auth0 and mock repositories based on configuration
92+
93+
---
94+
95+
### User Update Operation
4196

4297
To update a user profile, send a NATS request to the following subject:
4398

@@ -141,14 +196,18 @@ The NATS client can be configured using environment variables:
141196

142197
The Auth0 integration can be configured using environment variables:
143198

199+
- `USER_REPOSITORY_TYPE`: Set to `"auth0"` to use Auth0 integration, or `"mock"` for local development
200+
- **If not set, defaults to `"mock"`**
144201
- `AUTH0_TENANT`: Auth0 tenant name (e.g., `"linuxfoundation"`, `"linuxfoundation-staging"`, `"linuxfoundation-dev"`)
145-
- **If not set, the service will automatically use mock/local behavior**
202+
- **Required when using Auth0 repository type**
146203
- `AUTH0_DOMAIN`: Auth0 domain for Management API calls (e.g., `"sso.linuxfoundation.org"`)
147204
- **If not set, defaults to `${AUTH0_TENANT}.auth0.com`**
148-
- `USER_REPOSITORY_TYPE`: Set to `"auth0"` to use Auth0 integration, or `"mock"` for local development
149-
- **Defaults to `"auth0"` when `AUTH0_TENANT` is set, `"mock"` otherwise**
150-
151-
**Note:** When `AUTH0_DOMAIN` and `AUTH0_MANAGEMENT_TOKEN` are not set, the service will validate JWT tokens but won't make actual calls to Auth0's Management API.
205+
- `AUTH0_CLIENT_ID`: Auth0 Machine-to-Machine application client ID
206+
- **Required when using Auth0 repository type**
207+
- `AUTH0_PRIVATE_BASE64_KEY`: Base64-encoded private key for Auth0 M2M authentication
208+
- **Required when using Auth0 repository type**
209+
- `AUTH0_AUDIENCE`: Auth0 API audience/identifier for the Management API
210+
- **Required when using Auth0 repository type**
152211

153212
## Releases
154213

charts/lfx-v2-auth-service/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ apiVersion: v2
55
name: lfx-v2-auth-service
66
description: LFX Platform V2 Auth Service chart
77
type: application
8-
version: 0.1.1
8+
version: 0.2.0
99
appVersion: "latest"

charts/lfx-v2-auth-service/values.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ app:
1919
use_oidc_contextualizer: true
2020
# environment is the configuration for the application environment
2121
environment:
22+
# NATS Configuration
2223
NATS_URL:
2324
value: nats://lfx-platform-nats.lfx.svc.cluster.local:4222
2425
# Repository type for user management
@@ -27,8 +28,16 @@ app:
2728
USER_REPOSITORY_TYPE:
2829
value: mock
2930
# Auth0 Management API configuration
30-
## Optional when using mock or autheliarepository type
31+
## Optional when using mock or authelia repository type
3132
AUTH0_TENANT:
3233
value: null
3334
AUTH0_DOMAIN:
3435
value: null
36+
# Auth0 M2M Authentication configuration
37+
## Required when using auth0 repository type
38+
AUTH0_CLIENT_ID:
39+
value: null
40+
AUTH0_PRIVATE_BASE64_KEY:
41+
value: null
42+
AUTH0_AUDIENCE:
43+
value: null

cmd/server/service/message_handler.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func (mhs *MessageHandlerService) HandleMessage(ctx context.Context, msg port.Tr
2727

2828
handlers := map[string]func(ctx context.Context, msg port.TransportMessenger) ([]byte, error){
2929
constants.UserMetadataUpdateSubject: mhs.messageHandler.UpdateUser,
30+
constants.UserEmailToUserSubject: mhs.messageHandler.EmailToUsername,
3031
}
3132

3233
handler, ok := handlers[subject]

cmd/server/service/providers.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func newUserReaderWriter(ctx context.Context) port.UserReaderWriter {
8585

8686
userRepositoryType := os.Getenv(constants.UserRepositoryTypeEnvKey)
8787
if userRepositoryType == "" {
88-
userRepositoryType = constants.UserRepositoryTypeAuth0 // default to auth0 when tenant is set
88+
userRepositoryType = constants.UserRepositoryTypeMock // default to mock when not set
8989
}
9090

9191
switch userRepositoryType {
@@ -112,7 +112,18 @@ func newUserReaderWriter(ctx context.Context) port.UserReaderWriter {
112112
Tenant: auth0Tenant,
113113
Domain: auth0Domain,
114114
}
115-
return auth0.NewUserReaderWriter(httpclient.DefaultConfig(), auth0Config)
115+
116+
slog.DebugContext(ctx, "Auth0 client initialized with M2M token support",
117+
"tenant", auth0Tenant,
118+
"domain", auth0Domain,
119+
)
120+
121+
userReaderWriter, err := auth0.NewUserReaderWriter(ctx, httpclient.DefaultConfig(), auth0Config)
122+
if err != nil {
123+
log.Fatalf("failed to create Auth0 user reader writer: %v", err)
124+
}
125+
126+
return userReaderWriter
116127
default:
117128
log.Fatalf("unsupported user repository type: %s", userRepositoryType)
118129
return nil // This will never be reached due to log.Fatalf, but satisfies the linter
@@ -126,10 +137,15 @@ func QueueSubscriptions(ctx context.Context) error {
126137
// Initialize NATS client first
127138
natsInit(ctx)
128139

140+
userReaderWriter := newUserReaderWriter(ctx)
141+
129142
messageHandlerService := &MessageHandlerService{
130143
messageHandler: service.NewMessageHandlerOrchestrator(
131144
service.WithUserWriterForMessageHandler(
132-
service.NewUserWriterOrchestrator(service.WithUserWriter(newUserReaderWriter(ctx))),
145+
userReaderWriter,
146+
),
147+
service.WithUserReaderForMessageHandler(
148+
userReaderWriter,
133149
),
134150
),
135151
}
@@ -143,6 +159,7 @@ func QueueSubscriptions(ctx context.Context) error {
143159
// Start subscriptions for each subject
144160
subjects := map[string]func(context.Context, port.TransportMessenger){
145161
constants.UserMetadataUpdateSubject: messageHandlerService.HandleMessage,
162+
constants.UserEmailToUserSubject: messageHandlerService.HandleMessage,
146163
// Add more subjects here as needed
147164
}
148165

go.mod

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,41 @@ module github.com/linuxfoundation/lfx-v2-auth-service
66
go 1.24.5
77

88
require (
9+
github.com/auth0/go-auth0 v1.28.0
910
github.com/golang-jwt/jwt/v5 v5.3.0
1011
github.com/nats-io/nats.go v1.45.0
1112
goa.design/clue v1.2.3
1213
goa.design/goa/v3 v3.22.2
14+
golang.org/x/oauth2 v0.31.0
1315
gopkg.in/yaml.v3 v3.0.1
1416
)
1517

1618
require (
19+
github.com/PuerkitoBio/rehttp v1.4.0 // indirect
1720
github.com/aws/smithy-go v1.23.0 // indirect
1821
github.com/davecgh/go-spew v1.1.1 // indirect
22+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
1923
github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 // indirect
2024
github.com/go-chi/chi/v5 v5.2.3 // indirect
2125
github.com/go-logr/logr v1.4.3 // indirect
26+
github.com/goccy/go-json v0.10.5 // indirect
2227
github.com/gohugoio/hashstructure v0.5.0 // indirect
2328
github.com/google/uuid v1.6.0 // indirect
2429
github.com/gorilla/websocket v1.5.3 // indirect
2530
github.com/klauspost/compress v1.18.0 // indirect
31+
github.com/lestrrat-go/blackmagic v1.0.3 // indirect
32+
github.com/lestrrat-go/httpcc v1.0.1 // indirect
33+
github.com/lestrrat-go/httprc v1.0.6 // indirect
34+
github.com/lestrrat-go/iter v1.0.2 // indirect
35+
github.com/lestrrat-go/jwx/v2 v2.1.6 // indirect
36+
github.com/lestrrat-go/option v1.0.1 // indirect
2637
github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d // indirect
2738
github.com/nats-io/nkeys v0.4.11 // indirect
2839
github.com/nats-io/nuid v1.0.1 // indirect
2940
github.com/pmezard/go-difflib v1.0.0 // indirect
41+
github.com/segmentio/asm v1.2.0 // indirect
3042
github.com/stretchr/testify v1.11.1 // indirect
43+
go.devnw.com/structs v1.0.0 // indirect
3144
go.opentelemetry.io/otel v1.38.0 // indirect
3245
go.opentelemetry.io/otel/trace v1.38.0 // indirect
3346
golang.org/x/crypto v0.42.0 // indirect

go.sum

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
1+
github.com/PuerkitoBio/rehttp v1.4.0 h1:rIN7A2s+O9fmHUM1vUcInvlHj9Ysql4hE+Y0wcl/xk8=
2+
github.com/PuerkitoBio/rehttp v1.4.0/go.mod h1:LUwKPoDbDIA2RL5wYZCNsQ90cx4OJ4AWBmq6KzWZL1s=
3+
github.com/auth0/go-auth0 v1.28.0 h1:yJULZamgYW95sxbAkSwQl9Q5n05XPxdxQ/wZRp5E7fY=
4+
github.com/auth0/go-auth0 v1.28.0/go.mod h1:uNoJKgkhEToRfN5zmHa0sC7btn0l6RrG4jx8q2/q43E=
15
github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE=
26
github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
7+
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48=
8+
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA=
9+
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
10+
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
311
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
412
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
13+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
514
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
615
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
16+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
17+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
718
github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 h1:MGKhKyiYrvMDZsmLR/+RGffQSXwEkXgfLSA08qDn9AI=
819
github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598/go.mod h1:0FpDmbrt36utu8jEmeU05dPC9AB5tsLYVVi+ZHfyuwI=
20+
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
921
github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE=
1022
github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
1123
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
1224
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
1325
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
1426
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
27+
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
28+
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
1529
github.com/gohugoio/hashstructure v0.5.0 h1:G2fjSBU36RdwEJBWJ+919ERvOVqAg9tfcYp47K9swqg=
1630
github.com/gohugoio/hashstructure v0.5.0/go.mod h1:Ser0TniXuu/eauYmrwM4o64EBvySxNzITEOLlm4igec=
1731
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
@@ -24,8 +38,22 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
2438
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
2539
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
2640
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
41+
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
42+
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
2743
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
2844
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
45+
github.com/lestrrat-go/blackmagic v1.0.3 h1:94HXkVLxkZO9vJI/w2u1T0DAoprShFd13xtnSINtDWs=
46+
github.com/lestrrat-go/blackmagic v1.0.3/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw=
47+
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
48+
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
49+
github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k=
50+
github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
51+
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
52+
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
53+
github.com/lestrrat-go/jwx/v2 v2.1.6 h1:hxM1gfDILk/l5ylers6BX/Eq1m/pnxe9NBwW6lVfecA=
54+
github.com/lestrrat-go/jwx/v2 v2.1.6/go.mod h1:Y722kU5r/8mV7fYDifjug0r8FK8mZdw0K0GpJw/l8pU=
55+
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
56+
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
2957
github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d h1:Zj+PHjnhRYWBK6RqCDBcAhLXoi3TzC27Zad/Vn+gnVQ=
3058
github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d/go.mod h1:WZy8Q5coAB1zhY9AOBJP0O6J4BuDfbupUDavKY+I3+s=
3159
github.com/manveru/gobdd v0.0.0-20131210092515-f1a17fdd710b h1:3E44bLeN8uKYdfQqVQycPnaVviZdBLbizFhU49mtbe4=
@@ -38,8 +66,16 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
3866
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
3967
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4068
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
69+
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
70+
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
71+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
72+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
73+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
74+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
4175
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
4276
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
77+
go.devnw.com/structs v1.0.0 h1:FFkBoBOkapCdxFEIkpOZRmMOMr9b9hxjKTD3bJYl9lk=
78+
go.devnw.com/structs v1.0.0/go.mod h1:wHBkdQpNeazdQHszJ2sxwVEpd8zGTEsKkeywDLGbrmg=
4379
go.opentelemetry.io/auto/sdk v1.2.0 h1:YpRtUFjvhSymycLS2T81lT6IGhcUP+LUPtv0iv1N8bM=
4480
go.opentelemetry.io/auto/sdk v1.2.0/go.mod h1:1deq2zL7rwjwC8mR7XgY2N+tlIl6pjmEUoLDENMEzwk=
4581
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
@@ -62,16 +98,24 @@ golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
6298
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
6399
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
64100
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
101+
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
65102
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
66103
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
104+
golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo=
105+
golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
67106
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
68107
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
108+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
109+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
69110
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
70111
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
112+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
71113
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
72114
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
115+
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
73116
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
74117
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
118+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
75119
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
76120
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
77121
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
@@ -84,5 +128,8 @@ google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7I
84128
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
85129
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
86130
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
131+
gopkg.in/dnaeon/go-vcr.v3 v3.2.0 h1:Rltp0Vf+Aq0u4rQXgmXgtgoRDStTnFN83cWgSGSoRzM=
132+
gopkg.in/dnaeon/go-vcr.v3 v3.2.0/go.mod h1:2IMOnnlx9I6u9x+YBsM3tAMx6AlOxnJ0pWxQAzZ79Ag=
133+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
87134
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
88135
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 commit comments

Comments
 (0)