From 33a58a3cc33228e02b852268a6c9fd05d887425f Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:25:14 +0200 Subject: [PATCH] feat(sshd_config): Add analyzer support for tokens --- .../handlers/sshd_config/analyzer/analyzer.go | 1 + .../handlers/sshd_config/analyzer/tokens.go | 49 +++++++++++++++ .../sshd_config/analyzer/tokens_test.go | 62 +++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 server/handlers/sshd_config/analyzer/tokens.go create mode 100644 server/handlers/sshd_config/analyzer/tokens_test.go diff --git a/server/handlers/sshd_config/analyzer/analyzer.go b/server/handlers/sshd_config/analyzer/analyzer.go index dae9924..0007b09 100644 --- a/server/handlers/sshd_config/analyzer/analyzer.go +++ b/server/handlers/sshd_config/analyzer/analyzer.go @@ -55,6 +55,7 @@ func Analyze( } analyzeMatchBlocks(ctx) + analyzeTokens(ctx) return ctx.diagnostics } diff --git a/server/handlers/sshd_config/analyzer/tokens.go b/server/handlers/sshd_config/analyzer/tokens.go new file mode 100644 index 0000000..ee642db --- /dev/null +++ b/server/handlers/sshd_config/analyzer/tokens.go @@ -0,0 +1,49 @@ +package analyzer + +import ( + "config-lsp/common" + "config-lsp/handlers/sshd_config/fields" + "config-lsp/utils" + "fmt" + "strings" + + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func analyzeTokens( + ctx *analyzerContext, +) { + for _, option := range ctx.document.Config.GetAllOptions() { + if option.Key == nil || option.OptionValue == nil { + continue + } + + key := option.Key.Key + text := option.OptionValue.Value.Value + var tokens []string + + if foundTokens, found := fields.OptionsTokensMap[key]; found { + tokens = foundTokens + } else { + tokens = []string{} + } + + disallowedTokens := utils.Without(utils.KeysOfMap(fields.AvailableTokens), tokens) + + for _, token := range disallowedTokens { + if strings.Contains(text, token) { + optionName := string(key) + + if formatted, found := fields.FieldsNameFormattedMap[key]; found { + optionName = formatted + } + + ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{ + Range: option.OptionValue.ToLSPRange(), + Message: fmt.Sprintf("Token '%s' is not allowed for option '%s'", token, optionName), + Severity: &common.SeverityError, + }) + } + } + } +} diff --git a/server/handlers/sshd_config/analyzer/tokens_test.go b/server/handlers/sshd_config/analyzer/tokens_test.go new file mode 100644 index 0000000..021deb2 --- /dev/null +++ b/server/handlers/sshd_config/analyzer/tokens_test.go @@ -0,0 +1,62 @@ +package analyzer + +import ( + testutils_test "config-lsp/handlers/sshd_config/test_utils" + "testing" + + protocol "github.com/tliron/glsp/protocol_3_16" +) + +func TestInvalidTokensForNonExisting( + t *testing.T, +) { + d := testutils_test.DocumentFromInput(t, ` +ThisOptionDoesNotExist Hello%%World +`) + ctx := &analyzerContext{ + document: d, + diagnostics: make([]protocol.Diagnostic, 0), + } + + analyzeTokens(ctx) + + if !(len(ctx.diagnostics) == 1) { + t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics)) + } +} + +func TestInvalidTokensForExistingOption( + t *testing.T, +) { + d := testutils_test.DocumentFromInput(t, ` +Tunnel Hello%%World +`) + ctx := &analyzerContext{ + document: d, + diagnostics: make([]protocol.Diagnostic, 0), + } + + analyzeTokens(ctx) + + if !(len(ctx.diagnostics) == 1) { + t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics)) + } +} + +func TestValidTokens( + t *testing.T, +) { + d := testutils_test.DocumentFromInput(t, ` +AuthorizedPrincipalsCommand Hello World %% and %d +`) + ctx := &analyzerContext{ + document: d, + diagnostics: make([]protocol.Diagnostic, 0), + } + + analyzeTokens(ctx) + + if len(ctx.diagnostics) > 0 { + t.Fatalf("Expected no errors, but got %v", len(ctx.diagnostics)) + } +}