From 9e72dbbfa5035cb4d519808f9b4ef16cef4e7795 Mon Sep 17 00:00:00 2001 From: djelusic Date: Mon, 28 Feb 2022 15:29:48 +0100 Subject: [PATCH] split auth and node management into two functions --- cli/controller/auth.go | 4 +- cli/controller/controller.go | 4 +- cli/controller/examples/node_example.go | 11 +++- node/api/auth/auth.go | 45 ------------- node/api/auth/store.go | 59 ----------------- node/api/{auth/jwt.go => node/auth.go} | 32 +++++++-- node/api/node/store.go | 65 +++++++++++++++++++ node/functions/auth/main.go | 4 +- node/functions/node/.gitignore | 1 + node/functions/node/main.go | 44 +++++++++++++ node/terraform/modules/functions-node/iam.tf | 43 ++++++++++++ node/terraform/modules/functions-node/main.tf | 9 +++ 12 files changed, 203 insertions(+), 118 deletions(-) delete mode 100644 node/api/auth/auth.go delete mode 100644 node/api/auth/store.go rename node/api/{auth/jwt.go => node/auth.go} (88%) create mode 100644 node/api/node/store.go create mode 100644 node/functions/node/.gitignore create mode 100644 node/functions/node/main.go diff --git a/cli/controller/auth.go b/cli/controller/auth.go index 394b3844..072c2913 100644 --- a/cli/controller/auth.go +++ b/cli/controller/auth.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "encoding/json" "errors" + "fmt" "net/url" "github.com/mantil-io/mantil.go/logs" @@ -19,7 +20,7 @@ const ( clientID = "db4946aabe86cd6c126e" ) -func authToken(n *domain.Node) (string, error) { +func AuthToken(n *domain.Node) (string, error) { t, err := n.AuthToken() var terr *domain.TokenExpiredError if errors.As(err, &terr) && n.GitHubAuthEnabled { @@ -96,6 +97,7 @@ func waitToken(inbox string) (string, error) { return "", err } if err := l.Done(context.Background()); err != nil { + fmt.Println(err) return "", err } return rsp.JWT, nil diff --git a/cli/controller/controller.go b/cli/controller/controller.go index 048e4bbe..8e6ce530 100644 --- a/cli/controller/controller.go +++ b/cli/controller/controller.go @@ -78,7 +78,7 @@ func awsClient(node *domain.Node, stage *domain.Stage) (*aws.AWS, error) { url.RawQuery = q.Encode() token := func() string { - token, err := authToken(node) + token, err := AuthToken(node) if err != nil { return "" } @@ -93,7 +93,7 @@ func awsClient(node *domain.Node, stage *domain.Stage) (*aws.AWS, error) { } func nodeInvoker(node *domain.Node) (*invoke.HTTPClient, error) { - token, err := authToken(node) + token, err := AuthToken(node) if err != nil { return nil, log.Wrap(err) } diff --git a/cli/controller/examples/node_example.go b/cli/controller/examples/node_example.go index faccffe0..45a99bfd 100644 --- a/cli/controller/examples/node_example.go +++ b/cli/controller/examples/node_example.go @@ -1,6 +1,7 @@ package examples import ( + "github.com/mantil-io/mantil/cli/controller" "github.com/mantil-io/mantil/cli/controller/invoke" "github.com/mantil-io/mantil/cli/ui" "github.com/mantil-io/mantil/domain" @@ -35,7 +36,7 @@ func NewUserAddCommand() *cobra.Command { if err != nil { return err } - return i.Do("auth/addUser", &AddUserRequest{ + return i.Do("node/addUser", &AddUserRequest{ Username: args[0], }, nil) }, @@ -72,7 +73,7 @@ func NewProjectAddCommand() *cobra.Command { if err != nil { return err } - return i.Do("auth/addProject", &AddProjectRequest{ + return i.Do("node/addProject", &AddProjectRequest{ Repo: args[0], }, nil) }, @@ -82,5 +83,9 @@ func NewProjectAddCommand() *cobra.Command { } func nodeInvoker(node *domain.Node) (*invoke.HTTPClient, error) { - return invoke.Node(node.Endpoints.Rest, "", ui.NodeLogsSink), nil + t, err := controller.AuthToken(node) + if err != nil { + return nil, err + } + return invoke.Node(node.Endpoints.Rest, t, ui.NodeLogsSink), nil } diff --git a/node/api/auth/auth.go b/node/api/auth/auth.go deleted file mode 100644 index fd6cc598..00000000 --- a/node/api/auth/auth.go +++ /dev/null @@ -1,45 +0,0 @@ -package auth - -import ( - "context" - "log" - - "github.com/google/go-github/v42/github" - "github.com/mantil-io/mantil.go" - "github.com/mantil-io/mantil.go/logs" -) - -type Auth struct { - JWTRequest *JWTRequest - users *mantil.KV - projects *mantil.KV - ghClient *github.Client - natsPublisher *logs.Publisher - privateKey string - githubUsername string - githubOrg string -} - -func New() *Auth { - a := &Auth{} - if err := a.initStore(); err != nil { - log.Fatal(err) - } - return a -} - -type AddUserRequest struct { - Username string `json:"username"` -} - -func (a *Auth) AddUser(ctx context.Context, req *AddUserRequest) error { - return a.storeUser(req.Username) -} - -type AddProjectRequest struct { - Repo string `json:"repo"` -} - -func (a *Auth) AddProject(ctx context.Context, req *AddProjectRequest) error { - return a.storeProject(req.Repo) -} diff --git a/node/api/auth/store.go b/node/api/auth/store.go deleted file mode 100644 index 6e5eb5c5..00000000 --- a/node/api/auth/store.go +++ /dev/null @@ -1,59 +0,0 @@ -package auth - -import "github.com/mantil-io/mantil.go" - -const ( - usersPartition = "users" - projectsPartition = "projects" -) - -func (a *Auth) initStore() error { - users, err := mantil.NewKV(usersPartition) - if err != nil { - return err - } - a.users = users - projects, err := mantil.NewKV(projectsPartition) - if err != nil { - return err - } - a.projects = projects - return nil -} - -type user struct { - Name string -} - -func (a *Auth) storeUser(name string) error { - return a.users.Put(name, &user{ - Name: name, - }) -} - -func (a *Auth) findUser(name string) (*user, error) { - u := &user{} - if err := a.users.Get(name, u); err != nil { - return nil, err - } - return u, nil -} - -type project struct { - Repo string -} - -func (a *Auth) storeProject(repo string) error { - return a.projects.Put(repo, &project{ - Repo: repo, - }) -} - -func (a *Auth) findProjects() ([]*project, error) { - projects := []*project{} - _, err := a.projects.FindAll(&projects) - if err != nil { - return nil, err - } - return projects, nil -} diff --git a/node/api/auth/jwt.go b/node/api/node/auth.go similarity index 88% rename from node/api/auth/jwt.go rename to node/api/node/auth.go index 3a91dc3d..cab8af80 100644 --- a/node/api/auth/jwt.go +++ b/node/api/node/auth.go @@ -1,14 +1,14 @@ -package auth +package node import ( "context" "encoding/json" "fmt" + "log" "time" "github.com/google/go-github/v42/github" "github.com/mantil-io/mantil.go/logs" - "github.com/mantil-io/mantil/cli/log" "github.com/mantil-io/mantil/cli/secret" "github.com/mantil-io/mantil/domain" "github.com/mantil-io/mantil/kit/aws" @@ -16,6 +16,26 @@ import ( "golang.org/x/oauth2" ) +type Auth struct { + JWTRequest *JWTRequest + store *Store + ghClient *github.Client + natsPublisher *logs.Publisher + privateKey string + githubUsername string + githubOrg string +} + +func NewAuth() *Auth { + s, err := NewStore() + if err != nil { + log.Fatal(err) + } + return &Auth{ + store: s, + } +} + type JWTRequest struct { Inbox string `json:"inbox"` GithubToken string `json:"github_token"` @@ -91,11 +111,11 @@ func (a *Auth) generateJWT() (string, error) { return a.ownerToken(*ghUser.Login) case domain.Member: // check if user is allowed to access the node - user, err := a.findUser(*ghUser.Login) + user, err := a.store.FindUser(*ghUser.Login) if err != nil { return "", err } - projects, err := a.findProjects() + projects, err := a.store.FindProjects() if err != nil { return "", err } @@ -162,9 +182,9 @@ func (a *Auth) publishJWT(jwt string) error { func (a *Auth) publishError(e error) { if err := a.natsPublisher.Error(e); err != nil { - log.Error(err) + log.Println(err) } if err := a.natsPublisher.Close(); err != nil { - log.Error(err) + log.Println(err) } } diff --git a/node/api/node/store.go b/node/api/node/store.go new file mode 100644 index 00000000..a92b30d2 --- /dev/null +++ b/node/api/node/store.go @@ -0,0 +1,65 @@ +package node + +import "github.com/mantil-io/mantil.go" + +const ( + usersPartition = "users" + projectsPartition = "projects" +) + +type Store struct { + users *mantil.KV + projects *mantil.KV +} + +func NewStore() (*Store, error) { + users, err := mantil.NewKV(usersPartition) + if err != nil { + return nil, err + } + projects, err := mantil.NewKV(projectsPartition) + if err != nil { + return nil, err + } + return &Store{ + users: users, + projects: projects, + }, nil +} + +type user struct { + Name string +} + +func (s *Store) StoreUser(name string) error { + return s.users.Put(name, &user{ + Name: name, + }) +} + +func (s *Store) FindUser(name string) (*user, error) { + u := &user{} + if err := s.users.Get(name, u); err != nil { + return nil, err + } + return u, nil +} + +type project struct { + Repo string +} + +func (s *Store) StoreProject(repo string) error { + return s.projects.Put(repo, &project{ + Repo: repo, + }) +} + +func (s *Store) FindProjects() ([]*project, error) { + projects := []*project{} + _, err := s.projects.FindAll(&projects) + if err != nil { + return nil, err + } + return projects, nil +} diff --git a/node/functions/auth/main.go b/node/functions/auth/main.go index 557385ef..5eca2958 100644 --- a/node/functions/auth/main.go +++ b/node/functions/auth/main.go @@ -2,10 +2,10 @@ package main import ( "github.com/mantil-io/mantil.go" - "github.com/mantil-io/mantil/node/api/auth" + "github.com/mantil-io/mantil/node/api/node" ) func main() { - var api = auth.New() + var api = node.NewAuth() mantil.LambdaHandler(api) } diff --git a/node/functions/node/.gitignore b/node/functions/node/.gitignore new file mode 100644 index 00000000..b7c200ac --- /dev/null +++ b/node/functions/node/.gitignore @@ -0,0 +1 @@ +bootstrap diff --git a/node/functions/node/main.go b/node/functions/node/main.go new file mode 100644 index 00000000..7dfb71e6 --- /dev/null +++ b/node/functions/node/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "log" + + "github.com/mantil-io/mantil.go" + "github.com/mantil-io/mantil/node/api/node" +) + +type Node struct { + store *node.Store +} + +func New() *Node { + s, err := node.NewStore() + if err != nil { + log.Fatal(err) + } + return &Node{ + store: s, + } +} + +type AddUserRequest struct { + Username string `json:"username"` +} + +func (n *Node) AddUser(ctx context.Context, req *AddUserRequest) error { + return n.store.StoreUser(req.Username) +} + +type AddProjectRequest struct { + Repo string `json:"repo"` +} + +func (n *Node) AddProject(ctx context.Context, req *AddProjectRequest) error { + return n.store.StoreProject(req.Repo) +} + +func main() { + var api = New() + mantil.LambdaHandler(api) +} diff --git a/node/terraform/modules/functions-node/iam.tf b/node/terraform/modules/functions-node/iam.tf index 9577934c..8a739329 100644 --- a/node/terraform/modules/functions-node/iam.tf +++ b/node/terraform/modules/functions-node/iam.tf @@ -395,3 +395,46 @@ data "aws_iam_policy_document" "auth" { ] } } + +data "aws_iam_policy_document" "node" { + statement { + effect = "Allow" + actions = [ + "dynamodb:DescribeTable", + "dynamodb:DescribeContinuousBackups", + "dynamodb:ListTagsOfResource", + "dynamodb:TagResource", + "dynamodb:DescribeTimeToLive", + "dynamodb:CreateTable", + "dynamodb:Query", + "dynamodb:PutItem", + "dynamodb:GetItem", + "dynamodb:BatchWriteItem", + "dynamodb:BatchGetItem", + "dynamodb:DeleteItem", + ] + resources = [ + "arn:aws:dynamodb:*:*:table/mantil-kv-${var.suffix}", + ] + } + statement { + effect = "Allow" + actions = [ + "logs:CreateLogStream", + "logs:PutLogEvents", + ] + resources = [ + "arn:aws:logs:*:*:log-group:*-${var.suffix}", + "arn:aws:logs:*:*:log-group:*-${var.suffix}:log-stream:*", + ] + } + statement { + effect = "Allow" + actions = [ + "ssm:GetParameter", + ] + resources = [ + "*", + ] + } +} diff --git a/node/terraform/modules/functions-node/main.tf b/node/terraform/modules/functions-node/main.tf index 905b730a..20163829 100644 --- a/node/terraform/modules/functions-node/main.tf +++ b/node/terraform/modules/functions-node/main.tf @@ -35,6 +35,15 @@ locals { policy = data.aws_iam_policy_document.auth.json env = var.auth_env } + "node" = { + method = "POST" + s3_key = "${var.functions_path}/node.zip" + memory_size = 128 + timeout = 900 + architecture = "arm64" + policy = data.aws_iam_policy_document.node.json + env = var.auth_env + } } }