From b825cd1316e95cb9bbce3da0c467d63144e2e993 Mon Sep 17 00:00:00 2001 From: Eric Zorn Date: Tue, 7 Jan 2025 16:22:56 -0500 Subject: [PATCH] feat: adding auth0 config --- apps/services/accounts-worker/.env.example | 7 +++++++ .../accounts-worker/cmd/server/main.go | 21 ++++++++++++++++++- .../handlers/messagebroker/lavinmq.go | 5 ++++- .../accounts-worker/internal/app/app.go | 13 +++++++++++- .../accounts-worker/internal/config/config.go | 10 +++++++++ .../domain/services/account_service.go | 13 ++++++++++++ libs/backend/auth/m2m/m2m.go | 7 ++++--- 7 files changed, 70 insertions(+), 6 deletions(-) diff --git a/apps/services/accounts-worker/.env.example b/apps/services/accounts-worker/.env.example index c640777..dd43375 100644 --- a/apps/services/accounts-worker/.env.example +++ b/apps/services/accounts-worker/.env.example @@ -1,2 +1,9 @@ AMQP_CONNECTION_URI="amqp://guest:guest@lavinmq:5672" ACCOUNTS_API_URI="" + + +# AUTH0 +AUTH0_DOMAIN='' +AUTH0_CLIENT_ID='' +AUTH0_CLIENT_SECRET='' +AUTH0_AUDIENCE='' diff --git a/apps/services/accounts-worker/cmd/server/main.go b/apps/services/accounts-worker/cmd/server/main.go index 2d44526..d3a670a 100644 --- a/apps/services/accounts-worker/cmd/server/main.go +++ b/apps/services/accounts-worker/cmd/server/main.go @@ -15,6 +15,7 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" + "libs/backend/auth/m2m" boot "libs/backend/boot" "libs/backend/eventing" ) @@ -68,17 +69,35 @@ func run() error { }, Handlers: []boot.AMQPHandler{ func(hp boot.AMQPHandlerParams) error { + + // Initialize M2M Token Client + m2mClient, err := m2m.NewM2M( + config.Auth0Domain, + config.Auth0Audience, + config.Auth0ClientID, + config.Auth0ClientSecret, + ) + if err != nil { + return err + } + // Initialize services accountService := services.NewAccountService(services.AccountServiceParams{ Logger: logger, AccountsAPIURI: config.AccountsAPIUri, + M2MClient: m2mClient, }) // Initialize the application application := app.NewApp(app.WithAccountService(accountService)) // Initialize the message broker handler - handler := messagebroker.NewLavinMQHandler(logger, hp.AMQPController.Consumer, application) + handler := messagebroker.NewLavinMQHandler( + logger, + hp.AMQPController.Consumer, + application, + m2mClient, + ) // Handle the user registered event if err := handler.HandleUserRegisteredEvent(ctx, config.UserRegistrationQueueName); err != nil { diff --git a/apps/services/accounts-worker/internal/adapters/handlers/messagebroker/lavinmq.go b/apps/services/accounts-worker/internal/adapters/handlers/messagebroker/lavinmq.go index dcca676..6c7d372 100644 --- a/apps/services/accounts-worker/internal/adapters/handlers/messagebroker/lavinmq.go +++ b/apps/services/accounts-worker/internal/adapters/handlers/messagebroker/lavinmq.go @@ -3,6 +3,7 @@ package messagebroker import ( "apps/services/accounts-worker/internal/app" "context" + "libs/backend/auth/m2m" "libs/backend/boot" userEntities "libs/backend/domain/user/entities" userValueObjects "libs/backend/domain/user/valueobjects" @@ -16,15 +17,17 @@ import ( type LavinMQHandler struct { Logger boot.Logger Consumer boot.AMQPConsumer + M2M m2m.M2MGenerator App app.App } // LavinMQHandler is the constructor for LavinMQHandler -func NewLavinMQHandler(logger boot.Logger, consumer boot.AMQPConsumer, app app.App) LavinMQHandler { +func NewLavinMQHandler(logger boot.Logger, consumer boot.AMQPConsumer, app app.App, m2mGenerator m2m.M2MGenerator) LavinMQHandler { return LavinMQHandler{ Logger: logger, Consumer: consumer, App: app, + M2M: m2mGenerator, } } diff --git a/apps/services/accounts-worker/internal/app/app.go b/apps/services/accounts-worker/internal/app/app.go index f2d871b..4c2d3e7 100644 --- a/apps/services/accounts-worker/internal/app/app.go +++ b/apps/services/accounts-worker/internal/app/app.go @@ -1,10 +1,14 @@ package app -import "apps/services/accounts-worker/internal/app/ports" +import ( + "apps/services/accounts-worker/internal/app/ports" + "libs/backend/auth/m2m" +) // App is the main application struct type App struct { AccountService ports.AccountService + M2MService m2m.M2MGenerator } // AppOption is a function that modifies the App struct @@ -27,3 +31,10 @@ func WithAccountService(accountService ports.AccountService) AppOption { app.AccountService = accountService } } + +// WithM2MGenerator will allow the application to access m2m tokens from the auth provider +func WithM2MGenerator(m2mGenerator m2m.M2MGenerator) AppOption { + return func(a *App) { + a.M2MService = m2mGenerator + } +} diff --git a/apps/services/accounts-worker/internal/config/config.go b/apps/services/accounts-worker/internal/config/config.go index a66c079..cc6044f 100644 --- a/apps/services/accounts-worker/internal/config/config.go +++ b/apps/services/accounts-worker/internal/config/config.go @@ -19,6 +19,11 @@ type Config struct { AMQPUri string UserRegistrationQueueName string AccountsAPIUri string + + Auth0Domain string + Auth0ClientID string + Auth0ClientSecret string + Auth0Audience string } // NewConfig constructs the config @@ -28,6 +33,11 @@ func NewConfig() (Config, error) { AMQPUri: os.Getenv("AMQP_CONNECTION_URI"), UserRegistrationQueueName: fmt.Sprintf("%s-%s", serviceName, userRegistrationQueueName), AccountsAPIUri: os.Getenv("ACCOUNTS_API_URI"), + + Auth0Domain: os.Getenv("AUTH0_DOMAIN"), + Auth0ClientID: os.Getenv("AUTH0_CLIENT_ID"), + Auth0ClientSecret: os.Getenv("AUTH0_CLIENT_SECRET"), + Auth0Audience: os.Getenv("AUTH0_AUDIENCE"), } return config, nil diff --git a/apps/services/accounts-worker/internal/domain/services/account_service.go b/apps/services/accounts-worker/internal/domain/services/account_service.go index b74a69f..b6e5a68 100644 --- a/apps/services/accounts-worker/internal/domain/services/account_service.go +++ b/apps/services/accounts-worker/internal/domain/services/account_service.go @@ -3,8 +3,11 @@ package services import ( "apps/services/accounts-worker/internal/app/ports" "context" + "fmt" + "libs/backend/auth/m2m" boot "libs/backend/boot" userEntities "libs/backend/domain/user/entities" + "libs/backend/httpauth" accountsapiv1 "libs/backend/proto-gen/go/accounts/accountsapi/v1" "libs/backend/proto-gen/go/accounts/accountsapi/v1/accountsapiv1connect" "log/slog" @@ -18,6 +21,7 @@ type AccountService struct { Logger boot.Logger AccountConsumer boot.AMQPConsumer RegistrationServiceClient accountsapiv1connect.AccountServiceClient + M2MClient m2m.M2MGenerator } // AccountServiceParams is a struct to hold the parameters for the AccountService @@ -25,6 +29,7 @@ type AccountServiceParams struct { Logger boot.Logger AccountConsumer boot.AMQPConsumer AccountsAPIURI string + M2MClient m2m.M2MGenerator } // NewAccountService will construct the auth service @@ -35,18 +40,26 @@ func NewAccountService(params AccountServiceParams) AccountService { Logger: params.Logger, AccountConsumer: params.AccountConsumer, RegistrationServiceClient: registrationServiceClient, + M2MClient: params.M2MClient, } } // RegisterUser is an application interface method to handle user registration // webhooks func (s AccountService) CreateAccount(ctx context.Context, user userEntities.User) error { + // Obtain machine-to-machine-token + m2mToken, err := s.M2MClient.GetToken() + if err != nil { + return fmt.Errorf("m2m token generation failure") + } + // Call the accounts-api to create the account req := connect.NewRequest(&accountsapiv1.CreateAccountRequest{ Username: user.Username, EmailAddress: user.EmailAddress.String(), CommonId: user.CommonID.String(), }) + req.Header().Add(httpauth.AuthorizationHeaderKey, m2mToken.GetHeaderValue()) account, err := s.RegistrationServiceClient.CreateAccount(ctx, req) if err != nil { diff --git a/libs/backend/auth/m2m/m2m.go b/libs/backend/auth/m2m/m2m.go index e32844a..2ea7f8a 100644 --- a/libs/backend/auth/m2m/m2m.go +++ b/libs/backend/auth/m2m/m2m.go @@ -16,7 +16,6 @@ import ( var _ M2MGenerator = (*M2M)(nil) const ( - audience string = "https://career-cue-auth-api.com" clientCredentials string = "client_credentials" ) @@ -26,6 +25,7 @@ type M2MGenerator interface { type M2M struct { domain string + audience string clientID string clientSecret string auth *authentication.Authentication @@ -65,7 +65,7 @@ func (t Token) GetHeaderValue() string { return fmt.Sprintf("%s %s", t.tokenType, t.accessToken) } -func NewM2M(auth0Domain, auth0ClientID, auth0ClientSecret string) (*M2M, error) { +func NewM2M(auth0Domain, auth0Audience, auth0ClientID, auth0ClientSecret string) (*M2M, error) { ctx := context.Background() a, err := authentication.New(ctx, auth0Domain, authentication.WithClientID(auth0ClientID), authentication.WithClientSecret(auth0ClientSecret)) if err != nil { @@ -74,6 +74,7 @@ func NewM2M(auth0Domain, auth0ClientID, auth0ClientSecret string) (*M2M, error) return &M2M{ domain: auth0Domain, + audience: auth0Audience, clientID: auth0ClientID, clientSecret: auth0ClientSecret, auth: a, @@ -107,7 +108,7 @@ func (g *M2M) fetchToken() (Token, error) { reqBody := tokenRequestBody{ ClientID: g.clientID, ClientSecret: g.clientSecret, - Audience: audience, + Audience: g.audience, GrantType: clientCredentials, }