Skip to content

Commit

Permalink
wip: add accounts handler
Browse files Browse the repository at this point in the history
  • Loading branch information
katallaxie authored Apr 30, 2024
1 parent 0e3c10e commit 42b1a4c
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 46 deletions.
15 changes: 6 additions & 9 deletions cmd/accounts/cmd/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,22 @@ import (
"os"
)

var cfg = New()

// DB ...
type DB struct {
Username string
Password string
Port int
Database string
Username string `envconfig:"TYPHOON_DB_USERNAME" default:"example"`
Password string `envconfig:"TYPHOON_DB_PASSWORD" default:"example"`
Port int `envconfig:"TYPHOON_DB_PORT" default:"5432"`
Database string `envconfig:"TYPHOON_DB_DATABASE" default:"example"`
}

// Nats ...
type Nats struct {
Credentials string
Url string
Credentials string `envconfig:"TYPHOON_NATS_CREDENTIALS" default:"sys.creds"`
Url string `envconfig:"TYPHOON_NATS_URL" default:"nats://localhost:4222"`
}

// Flags contains the command line flags.
type Flags struct {
Addr string
DB *DB
Nats *Nats
}
Expand Down
80 changes: 62 additions & 18 deletions cmd/accounts/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,42 @@ package cmd

import (
"context"
"log"
"strings"

"github.com/zeiss/typhoon/internal/accounts/adapters"
"github.com/zeiss/typhoon/internal/accounts/controllers"
"github.com/zeiss/typhoon/internal/accounts/models"

"github.com/katallaxie/pkg/server"
"github.com/kelseyhightower/envconfig"
"github.com/nats-io/nats.go"
"github.com/spf13/cobra"
)

var cfg = New()

func init() {
Root.PersistentFlags().StringVar(&cfg.Flags.Addr, "addr", ":8080", "addr")
Root.PersistentFlags().StringVar(&cfg.Flags.DB.Database, "db-database", cfg.Flags.DB.Database, "Database name")
Root.PersistentFlags().StringVar(&cfg.Flags.DB.Username, "db-username", cfg.Flags.DB.Username, "Database user")
Root.PersistentFlags().StringVar(&cfg.Flags.DB.Password, "db-password", cfg.Flags.DB.Password, "Database password")
Root.PersistentFlags().IntVar(&cfg.Flags.DB.Port, "db-port", cfg.Flags.DB.Port, "Database port")
Root.PersistentFlags().StringVar(&cfg.Flags.Nats.Credentials, "credentials", cfg.Flags.Nats.Credentials, "credentials file")
Root.PersistentFlags().StringVar(&cfg.Flags.Nats.Url, "url", cfg.Flags.Nats.Url, "url")
Root.PersistentFlags().StringVar(&cfg.Flags.Nats.Credentials, "nats-credentials", cfg.Flags.Nats.Credentials, "credentials file")
Root.PersistentFlags().StringVar(&cfg.Flags.Nats.Url, "nats-url", cfg.Flags.Nats.Url, "url")

Root.SilenceUsage = true
}

var Root = &cobra.Command{
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
err := envconfig.Process("", cfg.Flags)
if err != nil {
return err
}

return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
srv := NewWebSrv(cfg)
srv := NewAccountSrv(cfg)

s, _ := server.WithContext(cmd.Context())
s.Listen(srv, false)
Expand All @@ -33,36 +46,67 @@ var Root = &cobra.Command{
},
}

var _ server.Listener = (*AccountServ)(nil)
var _ server.Listener = (*AccountSrv)(nil)

// AccountServ is the server that implements the Noop interface.
type AccountServ struct {
// AccountSrv is the server that implements the Noop interface.
type AccountSrv struct {
cfg *Config
}

// NewWebSrv returns a new instance of AccountServ.
func NewWebSrv(cfg *Config) *AccountServ {
return &AccountServ{cfg}
// NewAccountSrv returns a new instance of AccountServ.
func NewAccountSrv(cfg *Config) *AccountSrv {
return &AccountSrv{cfg}
}

// Start starts the server.
func (s *AccountServ) Start(ctx context.Context, ready server.ReadyFunc, run server.RunFunc) func() error {
func (s *AccountSrv) Start(ctx context.Context, ready server.ReadyFunc, run server.RunFunc) func() error {
return func() error {
db := adapters.NewDB(nil)
ac := controllers.NewAccountsController(db)
lh := adapters.NewAccountLookupRequestHandler(ac)

nc, err := nats.Connect(cfg.Flags.Nats.Url, nats.UserCredentials(cfg.Flags.Nats.Credentials))
if err != nil {
return err
}

sub, err := nc.Subscribe("$SYS.REQ.ACCOUNT.*.CLAIMS.LOOKUP", func(msg *nats.Msg) {
accountId := strings.TrimSuffix(strings.TrimPrefix(msg.Subject, "$SYS.REQ.ACCOUNT."), ".CLAIMS.LOOKUP")
log.Println("account lookup", "accountId", accountId)
})
sub, err := nc.SubscribeSync("$SYS.REQ.ACCOUNT.*.CLAIMS.LOOKUP")
if err != nil {
return err
}

<-ctx.Done()
for {
select {
case <-ctx.Done():
return sub.Unsubscribe()
default:
}

msg, err := sub.NextMsgWithContext(ctx)
if err != nil {
return err
}

return sub.Unsubscribe()
err = msg.InProgress()
if err != nil {
return err
}

accountId := strings.TrimSuffix(strings.TrimPrefix(msg.Subject, "$SYS.REQ.ACCOUNT."), ".CLAIMS.LOOKUP")
accountJWTToken, err := lh.HandleLookupRequest(ctx, models.AccountPublicKey(accountId))
if err != nil {
return err
}

err = msg.Respond([]byte(accountJWTToken))
if err != nil {
return err
}

err = msg.Ack(nats.Context(ctx))
if err != nil {
return err
}
}
}
}
27 changes: 27 additions & 0 deletions internal/accounts/adapters/db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package adapters

import (
"context"

"github.com/zeiss/typhoon/internal/accounts/models"
"github.com/zeiss/typhoon/internal/accounts/ports"

"gorm.io/gorm"
)

var _ ports.Accounts = (*DB)(nil)

// DB ...
type DB struct {
conn *gorm.DB
}

// NewDB ...
func NewDB(conn *gorm.DB) *DB {
return &DB{conn}
}

// GetToken ...
func (db *DB) GetToken(ctx context.Context, account models.AccountPublicKey) (models.AccountToken, error) {
return models.AccountToken(""), nil
}
23 changes: 23 additions & 0 deletions internal/accounts/adapters/lookup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package adapters

import (
"context"

"github.com/zeiss/typhoon/internal/accounts/controllers"
"github.com/zeiss/typhoon/internal/accounts/models"
)

// AccountLookupRequestHandler ...
type AccountLookupRequestHandler struct {
ctrl controllers.AccountsController
}

// NewAccountLookupRequestHandler ...
func NewAccountLookupRequestHandler(ctrl controllers.AccountsController) *AccountLookupRequestHandler {
return &AccountLookupRequestHandler{ctrl: ctrl}
}

// HandleLookupRequest ...
func (h *AccountLookupRequestHandler) HandleLookupRequest(ctx context.Context, accountPublicKey models.AccountPublicKey) (models.AccountToken, error) {
return h.ctrl.GetToken(ctx, accountPublicKey)
}
28 changes: 28 additions & 0 deletions internal/accounts/controllers/accounts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package controllers

import (
"context"

"github.com/zeiss/typhoon/internal/accounts/models"
"github.com/zeiss/typhoon/internal/accounts/ports"
)

// AccountsController ...
type AccountsController interface {
GetToken(ctx context.Context, accountPublicKey models.AccountPublicKey) (models.AccountToken, error)
}

// AccountsController ...
type accountsController struct {
db ports.Accounts
}

// NewAccountsController ...
func NewAccountsController(db ports.Accounts) *accountsController {
return &accountsController{db: db}
}

// GetToken ...
func (c *accountsController) GetToken(ctx context.Context, pubkey models.AccountPublicKey) (models.AccountToken, error) {
return c.db.GetToken(ctx, pubkey)
}
11 changes: 11 additions & 0 deletions internal/accounts/models/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package models

import "strings"

// AccountPublicKey ...
type AccountPublicKey string

// String ...
func (a AccountPublicKey) String() string {
return strings.TrimSpace(string(a))
}
11 changes: 11 additions & 0 deletions internal/accounts/models/token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package models

import "strings"

// AccountToken ...
type AccountToken string

// String ...
func (a AccountToken) String() string {
return strings.TrimSpace(string(a))
}
13 changes: 13 additions & 0 deletions internal/accounts/ports/accounts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ports

import (
"context"

"github.com/zeiss/typhoon/internal/accounts/models"
)

// Accounts ...
type Accounts interface {
// GetToken returns the token for the given account.
GetToken(ctx context.Context, account models.AccountPublicKey) (models.AccountToken, error)
}
4 changes: 4 additions & 0 deletions internal/accounts/ports/repos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ports

// Repositories ...
type Repositories interface{}
9 changes: 9 additions & 0 deletions internal/accounts/services/lookup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package services

// LookupService ...
type LookupService struct{}

// NewLookupService ...
func NewLookupService() *LookupService {
return &LookupService{}
}
38 changes: 19 additions & 19 deletions internal/api/controllers/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/nats-io/nkeys"
"github.com/zeiss/typhoon/internal/api/models"
"github.com/zeiss/typhoon/internal/api/ports"
"github.com/zeiss/typhoon/internal/utils"

openapi "github.com/zeiss/typhoon/pkg/apis"
)
Expand Down Expand Up @@ -133,24 +132,25 @@ func (c *AccountsController) UpdateAccount(ctx context.Context, req UpdateOperat
if err != nil {
return nil, err
}

if len(*req.Body.Claims.Exports) > 0 {
for _, e := range *req.Body.Claims.Exports {
export := &jwt.Export{
Name: utils.PtrStr(e.Name),
Subject: jwt.Subject(utils.PtrStr(e.Subject)),
Type: jwt.ExportType(*e.Type),
ResponseType: jwt.ResponseType(*e.ResponseType),
AccountTokenPosition: *e.AccountTokenPosition,
Info: jwt.Info{
Description: utils.PtrStr(e.Info.Description),
InfoURL: utils.PtrStr(e.Info.InfoUrl),
},
}

ac.Exports.Add(export)
}
}
ac.Exports = make([]*jwt.Export, 0)

// if len(*req.Body.Claims.Exports) > 0 {
// for _, e := range *req.Body.Claims.Exports {
// export := &jwt.Export{
// Name: utils.PtrStr(e.Name),
// Subject: jwt.Subject(utils.PtrStr(e.Subject)),
// Type: jwt.ExportType(*e.Type),
// ResponseType: jwt.ResponseType(*e.ResponseType),
// AccountTokenPosition: *e.AccountTokenPosition,
// Info: jwt.Info{
// Description: utils.PtrStr(e.Info.Description),
// InfoURL: utils.PtrStr(e.Info.InfoUrl),
// },
// }

// ac.Exports.Add(export)
// }
// }

token, err := ac.Encode(osk)
if err != nil {
Expand Down

0 comments on commit 42b1a4c

Please sign in to comment.