From e87aebcb742ca8b783dac205c2e83529f22d055d Mon Sep 17 00:00:00 2001 From: timbastin Date: Thu, 20 Jun 2024 15:01:29 +0200 Subject: [PATCH 1/2] adds email as identifier for webauthn --- .kratos/identity.schema.json | 3 +++ charts/flawfix/templates/kratos/kratos-config.yaml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.kratos/identity.schema.json b/.kratos/identity.schema.json index cd23ac0..fd0b9a2 100644 --- a/.kratos/identity.schema.json +++ b/.kratos/identity.schema.json @@ -16,6 +16,9 @@ "credentials": { "password": { "identifier": true + }, + "webauthn": { + "identifier": true } }, "verification": { diff --git a/charts/flawfix/templates/kratos/kratos-config.yaml b/charts/flawfix/templates/kratos/kratos-config.yaml index 9c56b05..5954b20 100644 --- a/charts/flawfix/templates/kratos/kratos-config.yaml +++ b/charts/flawfix/templates/kratos/kratos-config.yaml @@ -23,6 +23,9 @@ data: "credentials": { "password": { "identifier": true + }, + "webauthn": { + "identifier": true } }, "verification": { From 997ccaca6e29b8a13cb3fbef45c959fabbf0c25c Mon Sep 17 00:00:00 2001 From: timbastin Date: Thu, 20 Jun 2024 15:47:07 +0200 Subject: [PATCH 2/2] fixes undeterministic test --- .kratos/kratos.example.yml | 23 ++++----- internal/core/asset/dependency_tree.go | 17 ++++--- internal/core/asset/dependency_tree_test.go | 56 ++++++++++++++++----- 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/.kratos/kratos.example.yml b/.kratos/kratos.example.yml index da9c7db..2139bda 100644 --- a/.kratos/kratos.example.yml +++ b/.kratos/kratos.example.yml @@ -8,16 +8,15 @@ session: serve: public: - base_url: http://127.0.0.1:4433/ + base_url: http://localhost:4433/ cors: enabled: true admin: - base_url: http://127.0.0.1:4434/ + base_url: http://localhost:4434/ selfservice: - default_browser_return_url: http://127.0.0.1:3000/ + default_browser_return_url: http://localhost:3000/ allowed_return_urls: - - http://127.0.0.1:3000 - http://localhost:3000 methods: webauthn: @@ -50,36 +49,36 @@ selfservice: flows: error: - ui_url: http://127.0.0.1:3000/error + ui_url: http://localhost:3000/error settings: - ui_url: http://127.0.0.1:3000/settings + ui_url: http://localhost:3000/user-settings privileged_session_max_age: 15m required_aal: highest_available recovery: enabled: true - ui_url: http://127.0.0.1:3000/recovery + ui_url: http://localhost:3000/recovery use: code verification: enabled: true - ui_url: http://127.0.0.1:3000/verification + ui_url: http://localhost:3000/verification use: code after: - default_browser_return_url: http://127.0.0.1:3000/ + default_browser_return_url: http://localhost:3000/ logout: after: - default_browser_return_url: http://127.0.0.1:3000/login + default_browser_return_url: http://localhost:3000/login login: - ui_url: http://127.0.0.1:3000/login + ui_url: http://localhost:3000/login lifespan: 10m registration: lifespan: 10m - ui_url: http://127.0.0.1:3000/registration + ui_url: http://localhost:3000/registration after: password: hooks: diff --git a/internal/core/asset/dependency_tree.go b/internal/core/asset/dependency_tree.go index a562b20..dfe7064 100644 --- a/internal/core/asset/dependency_tree.go +++ b/internal/core/asset/dependency_tree.go @@ -27,8 +27,9 @@ type treeNode struct { } type tree struct { - Root *treeNode `json:"root"` - cursors map[string]*treeNode + Root *treeNode `json:"root"` + cursors map[string]*treeNode + insertionOrder []string } func newNode(name string) *treeNode { @@ -42,10 +43,12 @@ func (tree *tree) addNode(source string, dep string) { // check if source does exist if _, ok := tree.cursors[source]; !ok { tree.cursors[source] = newNode(source) + tree.insertionOrder = append(tree.insertionOrder, source) } // check if dep does already exist if _, ok := tree.cursors[dep]; !ok { tree.cursors[dep] = newNode(dep) + tree.insertionOrder = append(tree.insertionOrder, source) } // check if connection does already exist @@ -98,7 +101,8 @@ func cutCycles(tree *tree, removedEdges map[string][]string) { } // Iterate over all nodes in the graph and apply DFS - for _, node := range tree.cursors { + for _, nodeKey := range tree.insertionOrder { + node := tree.cursors[nodeKey] if !visited[node.Name] { dfs(node) } @@ -107,14 +111,15 @@ func cutCycles(tree *tree, removedEdges map[string][]string) { func buildDependencyTree(elements []models.ComponentDependency) (tree, map[string][]string) { // sort by depth - slices.SortFunc(elements, func(a, b models.ComponentDependency) int { + slices.SortStableFunc(elements, func(a, b models.ComponentDependency) int { return a.Depth - b.Depth }) // create a new tree tree := tree{ - Root: &treeNode{Name: "root"}, - cursors: make(map[string]*treeNode), + Root: &treeNode{Name: "root"}, + cursors: make(map[string]*treeNode), + insertionOrder: make([]string, 0), } tree.cursors["root"] = tree.Root diff --git a/internal/core/asset/dependency_tree_test.go b/internal/core/asset/dependency_tree_test.go index fe03ed9..102328e 100644 --- a/internal/core/asset/dependency_tree_test.go +++ b/internal/core/asset/dependency_tree_test.go @@ -60,31 +60,61 @@ func TestDependencyTree(t *testing.T) { }) t.Run("test removes cycles", func(t *testing.T) { + /* + a + | | + b <---> c # here is the cycle in the tree + */ graph := []models.ComponentDependency{ {ComponentPurlOrCpe: nil, DependencyPurlOrCpe: "a", Depth: 0}, {ComponentPurlOrCpe: utils.Ptr("a"), DependencyPurlOrCpe: "b", Depth: 1}, - {ComponentPurlOrCpe: utils.Ptr("b"), DependencyPurlOrCpe: "a", Depth: 2}, + {ComponentPurlOrCpe: utils.Ptr("a"), DependencyPurlOrCpe: "c", Depth: 1}, + {ComponentPurlOrCpe: utils.Ptr("b"), DependencyPurlOrCpe: "c", Depth: 2}, + {ComponentPurlOrCpe: utils.Ptr("c"), DependencyPurlOrCpe: "b", Depth: 2}, // closes the cycle } tree, removedEdges := buildDependencyTree(graph) // expect root node to be created with a single child: a if len(tree.Root.Children) != 1 { - t.Errorf("expected 1 root child, got %d", len(tree.Root.Children)) + t.Fatalf("expected 1 root child, got %d", len(tree.Root.Children)) } - // expect a to have a single child: b - if len(tree.Root.Children[0].Children) != 1 { - t.Errorf("expected 1 children for a, got %d", len(tree.Root.Children[0].Children)) + // expect a to have a two children b and c + if len(tree.Root.Children[0].Children) != 2 { + t.Fatalf("expected 2 children for a, got %d", len(tree.Root.Children[0].Children)) } - // expect b to have no children - if len(tree.Root.Children[0].Children[0].Children) != 0 { - t.Errorf("expected 0 children for b, got %d", len(tree.Root.Children[0].Children[0].Children)) + // get b and c + var b, c *treeNode + for _, child := range tree.Root.Children[0].Children { + if child.Name == "b" { + b = child + } else if child.Name == "c" { + c = child + } } - // expect the cycle to be removed - b -> a completes the cycle - if len(removedEdges["b"]) != 1 { - t.Errorf("expected 1 removed edge for b, got %d", len(removedEdges["b"])) - if removedEdges["b"][0] != "a" { - t.Errorf("expected removed edge to be a, got %s", removedEdges["b"][0]) + // expect either b or c to have no children + if len(b.Children) != 0 && len(c.Children) != 0 { + t.Fatalf("expected either b or c to have no children, got %d and %d", len(b.Children), len(c.Children)) + } + + // check if b has children + if len(b.Children) == 0 { + // expect the edge between b and c to be removed + if len(removedEdges["b"]) != 1 { + t.Fatalf("expected 1 removed edge for b, got %d", len(removedEdges["b"])) + } + // expect the removed edge to be c + if removedEdges["b"][0] != "c" { + t.Fatalf("expected removed edge to be c, got %s", removedEdges["b"][0]) + } + } else { + // expect the edge between c and b to be removed + if len(removedEdges["c"]) != 1 { + t.Fatalf("expected 1 removed edge for c, got %d", len(removedEdges["c"])) + } + // expect the removed edge to be b + if removedEdges["c"][0] != "b" { + t.Fatalf("expected removed edge to be b, got %s", removedEdges["c"][0]) } } })