From 3b6c38bf5102b15c71accfd9fcd3398068bef5f4 Mon Sep 17 00:00:00 2001 From: Edoardo Rosa <6991986+notdodo@users.noreply.github.com> Date: Thu, 7 Dec 2023 12:28:18 +0100 Subject: [PATCH] enh: create relationships between rules and groups --- cmd/dump.go | 2 +- pkg/app/app.go | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 pkg/app/app.go diff --git a/cmd/dump.go b/cmd/dump.go index a3480a7..1d1af46 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -21,7 +21,7 @@ var usersCmd = &cobra.Command{ if cmd.Flags().Changed(flagDebug) { logger.SetDebugLevel() } - oktaNeo4jApp := iamme.NewOktaNeo4jApp(okta.NewOktaClient(orgUrl, oktaClientToken), neo4jClient) + oktaNeo4jApp := app.NewOktaNeo4jApp(okta.NewOktaClient(orgUrl, oktaClientToken), neo4jClient) oktaNeo4jApp.Dump() }, } diff --git a/pkg/app/app.go b/pkg/app/app.go new file mode 100644 index 0000000..5010fc5 --- /dev/null +++ b/pkg/app/app.go @@ -0,0 +1,101 @@ +package app + +import ( + "github.com/notdodo/IAMme-IAMme/pkg/infra/neo4j" + "github.com/notdodo/IAMme-IAMme/pkg/infra/okta" + "github.com/notdodo/IAMme-IAMme/pkg/io/logging" + + "github.com/notdodo/goflat" +) + +type OktaNeo4jApp interface { + Dump() +} + +func NewOktaNeo4jApp(oktaClient okta.OktaClient, neo4jClient neo4j.Neo4jClient) OktaNeo4jApp { + logger := logging.GetLogManager() + return &oktaNeo4jApp{ + oktaClient: oktaClient, + neo4jClient: neo4jClient, + logger: logger, + } +} + +type oktaNeo4jApp struct { + oktaClient okta.OktaClient + neo4jClient neo4j.Neo4jClient + logger logging.LogManager +} + +func (a *oktaNeo4jApp) Dump() { + a.createNodes([]string{"User"}, flat(a.getUsers())) + a.createNodes([]string{"Group"}, flat(a.getGroups())) + rules := a.getRules() + a.createNodes([]string{"Rule"}, flat(rules)) + + groupRules := make([]map[string]interface{}, 0) + for _, rule := range rules { + for _, gid := range rule.Actions.AssignUserToGroups.GroupIds { + groupRules = append(groupRules, map[string]interface{}{ + "left_key": "GroupRule_Id", + "left_value": rule.GroupRule.Id, + "right_key": "Group_Id", + "right_value": gid, + }) + } + } + a.createRelations([]string{"GroupRule"}, []string{"Rule"}, []string{"Group"}, groupRules) +} + +func (a *oktaNeo4jApp) getUsers() []*okta.User { + users, err := a.oktaClient.GetUsers() + if err != nil { + a.logger.Error("Error fetching users from Okta:", "err", err) + } + return users +} + +func (a *oktaNeo4jApp) getGroups() []*okta.Group { + groups, err := a.oktaClient.GetGroups() + if err != nil { + a.logger.Error("Error fetching groups from Okta:", "err", err) + } + return groups +} + +func (a *oktaNeo4jApp) getRules() []*okta.GroupRule { + rules, err := a.oktaClient.GetGroupsRules() + if err != nil { + a.logger.Error("Error fetching rules from Okta:", "err", err) + } + return rules +} + +func flat[T any](data []T) []map[string]interface{} { + flatData := make([]map[string]interface{}, 0, len(data)) + for _, item := range data { + flatItem := goflat.FlatStruct(item, goflat.FlattenerConfig{ + Separator: "_", + OmitEmpty: true, + OmitNil: true, + }) + flatData = append(flatData, flatItem) + } + return flatData +} + +func (a *oktaNeo4jApp) createNodes(nodeLabels []string, properties []map[string]interface{}) []map[string]interface{} { + nodeIDs, err := a.neo4jClient.CreateNodes(nodeLabels, properties) + if err != nil { + a.logger.Error("Error creating nodes on Neo4J", "err", err) + } + return nodeIDs +} + +func (a *oktaNeo4jApp) createRelations(relationLabels []string, aLabels []string, bLabels []string, properties []map[string]interface{}) []map[string]interface{} { + relIDs, err := a.neo4jClient.CreateRelationsAtoB(relationLabels, aLabels, bLabels, properties) + if err != nil { + a.logger.Error("Error creating nodes on Neo4J", "err", err) + } + return relIDs +}