From 2c44c080817a8e914c57e383f1157efe4cbf777c Mon Sep 17 00:00:00 2001
From: postmannen <postmannen@gmail.com>
Date: Mon, 9 May 2022 07:00:52 +0200
Subject: [PATCH] command groups ok

---
 doc/concept/auth/auth_parser.go | 18 +++++++++-------
 doc/concept/auth/main.go        | 37 +++++++++++++++++++++++++++++++--
 doc/concept/auth/main_test.go   | 19 ++++++++---------
 3 files changed, 55 insertions(+), 19 deletions(-)

diff --git a/doc/concept/auth/auth_parser.go b/doc/concept/auth/auth_parser.go
index 5970447..40055e3 100644
--- a/doc/concept/auth/auth_parser.go
+++ b/doc/concept/auth/auth_parser.go
@@ -56,19 +56,23 @@ func (a *authParser) hostIsGroup() parseFn {
 	for source, cmdMap := range a.authSchema.schemaMain.ACLMap[a.currentHost] {
 
 		for cmd, emptyStruct := range cmdMap {
+			cmdSlice := a.authSchema.convertToActualCommandSlice(cmd)
 
 			// Expand eventual groups, so we use real fromNode nodenames in ACL for nodes.
 			sourceNodes := a.authSchema.convToActualNodeSlice(source)
 			for _, sourceNode := range sourceNodes {
 				for _, host := range hosts {
-					if a.authSchema.schemaGenerated.ACLsToConvert[host] == nil {
-						a.authSchema.schemaGenerated.ACLsToConvert[host] = make(map[node]map[command]struct{})
-					}
-					if a.authSchema.schemaGenerated.ACLsToConvert[host][sourceNode] == nil {
-						a.authSchema.schemaGenerated.ACLsToConvert[host][sourceNode] = make(map[command]struct{})
-					}
 
-					a.authSchema.schemaGenerated.ACLsToConvert[host][sourceNode][cmd] = emptyStruct
+					for _, cm := range cmdSlice {
+						if a.authSchema.schemaGenerated.ACLsToConvert[host] == nil {
+							a.authSchema.schemaGenerated.ACLsToConvert[host] = make(map[node]map[command]struct{})
+						}
+						if a.authSchema.schemaGenerated.ACLsToConvert[host][sourceNode] == nil {
+							a.authSchema.schemaGenerated.ACLsToConvert[host][sourceNode] = make(map[command]struct{})
+						}
+
+						a.authSchema.schemaGenerated.ACLsToConvert[host][sourceNode][cm] = emptyStruct
+					}
 				}
 			}
 		}
diff --git a/doc/concept/auth/main.go b/doc/concept/auth/main.go
index 1a2bfdf..03d4764 100644
--- a/doc/concept/auth/main.go
+++ b/doc/concept/auth/main.go
@@ -1,8 +1,10 @@
 package main
 
 import (
+	"encoding/json"
 	"fmt"
 	"log"
+	"os"
 	"sort"
 	"strings"
 	"sync"
@@ -118,12 +120,12 @@ func (a *authSchema) convToActualNodeSlice(n node) []node {
 	return nodes
 }
 
-// convertCommandToCommandSlice will convert the given argument into a slice representation.
+// convertToActualCommandSlice will convert the given argument into a slice representation.
 // If the argument is a group, then all the members of that group will be expanded into
 // the slice.
 // If the argument is not a group kind of value, then only a slice with that single
 // value is returned.
-func (a *authSchema) convertCommandToCommandSlice(c command) []command {
+func (a *authSchema) convertToActualCommandSlice(c command) []command {
 	commands := []command{}
 
 	// Check if we are given a nodeGroup variable, and if we are, get all the
@@ -239,12 +241,43 @@ func (a *authSchema) aclSourceDelete(host node, source node) error {
 func (a *authSchema) generateJSONForAllNodes() error {
 	a.schemaGenerated.ACLsToConvert = make(map[node]map[node]map[command]struct{})
 
+	// Rangle all ACL's. Both for single hosts, and group of hosts.
+	// ACL's that are for a group of hosts will be generated split
+	// out in it's indivial host name, and that current ACL will
+	// be added to the individual host in the ACLsToConvert map to
+	// built a complete picture of what the ACL's looks like for each
+	// individual hosts.
 	for n := range a.schemaMain.ACLMap {
 		//a.schemaGenerated.ACLsToConvert = make(map[node]map[node]map[command]struct{})
 		ap := newAuthParser(n, a)
 		ap.parse()
 	}
 
+	// ACLsToConvert got the complete picture of what ACL's that
+	// are defined for each individual host node.
+	// Range this map, and generate a JSON representation of all
+	// the ACL's each host.
+	func() {
+		for n, m := range a.schemaGenerated.ACLsToConvert {
+
+			b, err := json.Marshal(m)
+			if err != nil {
+				er := fmt.Errorf("error: failed to generate json for host in schemaGenerated: %v", err)
+				log.Printf("%v\n", er)
+				os.Exit(1)
+			}
+
+			nd := NodeDataWithHash{
+				Data: b,
+				// TODO: Also add the hash here.
+				// Hash: [32]byte,
+			}
+
+			a.schemaGenerated.NodeMap[n] = nd
+
+		}
+	}()
+
 	return nil
 }
 
diff --git a/doc/concept/auth/main_test.go b/doc/concept/auth/main_test.go
index 5e33c3f..05d52e5 100644
--- a/doc/concept/auth/main_test.go
+++ b/doc/concept/auth/main_test.go
@@ -69,15 +69,15 @@ func TestACLWithGroups(t *testing.T) {
 
 	// --- Tests ---
 
-	if _, ok := c.authorization.authSchema.schemaMain.ACLMap[grp_nodes_ships][grp_nodes_operators][grp_cmds_commandset1]; !ok {
-		t.Fatal(" \U0001F631  [FAILED]: missing map entry")
-	}
+	//if _, ok := c.authorization.authSchema.schemaMain.ACLMap[grp_nodes_ships][grp_nodes_operators][grp_cmds_commandset1]; !ok {
+	//	t.Fatal(" \U0001F631  [FAILED]: missing map entry")
+	//}
 
 	// Also check the generated data for the nodes.
 
-	if _, ok := c.authorization.authSchema.schemaMain.ACLMap[grp_nodes_ships]["admin"]["useradd -m kongen"]; !ok {
-		t.Fatal(" \U0001F631  [FAILED]: missing map entry")
-	}
+	// if _, ok := c.authorization.authSchema.schemaMain.ACLMap[grp_nodes_ships]["admin"]["useradd -m kongen"]; !ok {
+	// 	t.Fatal(" \U0001F631  [FAILED]: missing map entry")
+	// }
 
 	mapOfFromNodeCommands := make(map[node]map[command]struct{})
 	err := json.Unmarshal(c.authorization.authSchema.schemaGenerated.NodeMap["ship101"].Data, &mapOfFromNodeCommands)
@@ -107,10 +107,9 @@ func TestACLWithGroups(t *testing.T) {
 		t.Fatal(" \U0001F631  [FAILED]: missing map entry")
 	}
 
-	// // TODO: Check why this one fails
-	// if _, ok := mapOfFromNodeCommands["admin"]["HORSE"]; !ok {
-	// 	t.Fatal(" \U0001F631  [FAILED]: missing map entry")
-	// }
+	if _, ok := mapOfFromNodeCommands["admin"]["HORSE"]; !ok {
+		t.Fatal(" \U0001F631  [FAILED]: missing map entry")
+	}
 
 }