From 997105c20dcaaa6abbfcc06584251789c69195d9 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Mon, 16 Jan 2023 14:03:20 +0100 Subject: [PATCH] Config: Support JSON list syntax (#61288) * Config: Separate lists either by spaces or by commas. * Simplify space separation * use separate function for the config strings * Change behavior only if string contains quotes * add test for invalid string * Use JSON list syntax * ignore leading spaces when process list * Add notes about using JSON lists into the docs * Fix typo * Apply suggestions from code review Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com> Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com> --- .../configure-authentication/gitlab/index.md | 6 ++++++ .../configure-authentication/okta/index.md | 6 ++++++ .../configure-authentication/saml/index.md | 6 ++++++ pkg/util/strings.go | 11 +++++++++++ pkg/util/strings_test.go | 17 +++++++++++------ 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md index 63f38d3cd4d..c15151b064f 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md @@ -110,6 +110,12 @@ the group `foo`, set allowed_groups = example, foo/bar ``` +To put values containing spaces in the list, use the following JSON syntax: + +```ini +allowed_groups = ["Admins", "Software Engineers"] +``` + Note that in GitLab, the group or subgroup name doesn't always match its display name, especially if the display name contains spaces or special characters. Make sure you always use the group or subgroup name as it appears diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md index ae587b56cb4..4b3834cf72e 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md @@ -81,6 +81,12 @@ The `allowed_domains` option limits access to the users belonging to the specifi allowed_domains = mycompany.com mycompany.org ``` +To put values containing spaces in the list, use the following JSON syntax: + +```ini +allowed_groups = ["Admins", "Software Engineers"] +``` + ### Map roles Grafana can attempt to do role mapping through Okta OAuth. In order to achieve this, Grafana checks for the presence of a role using the [JMESPath](http://jmespath.org/examples.html) specified via the `role_attribute_path` configuration option. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md index df1e6340556..82aab5f70cd 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md @@ -390,6 +390,12 @@ You can use `*` as the Grafana organization in the mapping if you want all users With the [`allowed_organizations`]({{< relref "../../../configure-grafana/enterprise-configuration/#allowed-organizations" >}}) option you can specify a list of organizations where the user must be a member of at least one of them to be able to log in to Grafana. +To put values containing spaces in the list, use the following JSON syntax: + +```ini +allowed_organizations = ["org 1", "second org"] +``` + ### Example SAML configuration ```bash diff --git a/pkg/util/strings.go b/pkg/util/strings.go index 1cacce669ef..2b469833e5c 100644 --- a/pkg/util/strings.go +++ b/pkg/util/strings.go @@ -1,6 +1,7 @@ package util import ( + "encoding/json" "fmt" "math" "strings" @@ -33,6 +34,16 @@ func SplitString(str string) []string { return []string{} } + // JSON list syntax support + if strings.Index(strings.TrimSpace(str), "[") == 0 { + var res []string + err := json.Unmarshal([]byte(str), &res) + if err != nil { + return []string{} + } + return res + } + return strings.Fields(strings.ReplaceAll(str, ",", " ")) } diff --git a/pkg/util/strings_test.go b/pkg/util/strings_test.go index efb3dbbb773..876cb705974 100644 --- a/pkg/util/strings_test.go +++ b/pkg/util/strings_test.go @@ -46,12 +46,17 @@ func TestStringsFallback3(t *testing.T) { func TestSplitString(t *testing.T) { tests := map[string][]string{ - "": {}, - "test": {"test"}, - "test1 test2 test3": {"test1", "test2", "test3"}, - "test1,test2,test3": {"test1", "test2", "test3"}, - "test1, test2, test3": {"test1", "test2", "test3"}, - "test1 , test2 test3": {"test1", "test2", "test3"}, + "": {}, + "test": {"test"}, + " test1 test2 test3": {"test1", "test2", "test3"}, + "test1,test2,test3": {"test1", "test2", "test3"}, + "test1, test2, test3": {"test1", "test2", "test3"}, + "test1 , test2 test3": {"test1", "test2", "test3"}, + "foo, bar baz": {"foo", "bar", "baz"}, + `["foo", "bar baz"]`: {"foo", "bar baz"}, + `["foo", "bar \"baz\""]`: {"foo", "bar \"baz\""}, + ` ["foo", "bar baz"]`: {"foo", "bar baz"}, + `[]`: {}, } for input, expected := range tests { assert.EqualValues(t, expected, SplitString(input))