mirror of
https://github.com/prymitive/karma
synced 2026-08-23 11:56:20 +00:00
fix(auth): add missing test coverage
This commit is contained in:
committed by
Łukasz Mierzwa
parent
9b89b4ee2a
commit
4ccc0a35ab
@@ -6,6 +6,10 @@
|
||||
|
||||
- Toast popup messages didn't respond to clicks.
|
||||
|
||||
### Added
|
||||
|
||||
- Loading user groups from HTTP headers, #3361 (@supertassu).
|
||||
|
||||
## v0.92
|
||||
|
||||
### Fixed
|
||||
|
||||
+22
-14
@@ -22,6 +22,20 @@ func userGroups(username string) []string {
|
||||
return groups
|
||||
}
|
||||
|
||||
func groupsFromHeaders(r *http.Request, groupName, groupValueRegex, groupValueSeparator string) []string {
|
||||
groups := []string{}
|
||||
groupRegex := regex.MustCompileAnchored(groupValueRegex)
|
||||
rawGroups := groupRegex.FindAllStringSubmatch(r.Header.Get(groupName), 1)
|
||||
if len(rawGroups) > 0 && len(rawGroups[0]) > 1 {
|
||||
for _, group := range strings.Split(rawGroups[0][1], groupValueSeparator) {
|
||||
if v := strings.TrimSpace(group); v != "" {
|
||||
groups = append(groups, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
func headerAuth(name, valueRegex, groupName, groupValueRegex, groupValueSeparator string, allowBypass []string) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -49,18 +63,7 @@ func headerAuth(name, valueRegex, groupName, groupValueRegex, groupValueSeparato
|
||||
groups := userGroups(userName)
|
||||
|
||||
if groupName != "" {
|
||||
rawGroups := []string{r.Header.Get(groupName)}
|
||||
if groupValueSeparator != "" {
|
||||
rawGroups = strings.Split(rawGroups[0], groupValueSeparator)
|
||||
}
|
||||
|
||||
groupRegex := regex.MustCompileAnchored(groupValueRegex)
|
||||
for _, group := range rawGroups {
|
||||
groupMatches := groupRegex.FindAllStringSubmatch(group, 1)
|
||||
if len(groupMatches) != 0 && len(groupMatches[0]) > 1 {
|
||||
groups = append(groups, groupMatches[0][1])
|
||||
}
|
||||
}
|
||||
groups = append(groups, groupsFromHeaders(r, groupName, groupValueRegex, groupValueSeparator)...)
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), authUserKey("user"), userName)
|
||||
@@ -86,7 +89,7 @@ func getGroupsFromContext(r *http.Request) []string {
|
||||
return groups.([]string)
|
||||
}
|
||||
|
||||
func basicAuth(creds map[string]string, allowBypass []string) func(next http.Handler) http.Handler {
|
||||
func basicAuth(creds map[string]string, groupName, groupValueRegex, groupValueSeparator string, allowBypass []string) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if slices.StringInSlice(allowBypass, r.URL.Path) {
|
||||
@@ -106,8 +109,13 @@ func basicAuth(creds map[string]string, allowBypass []string) func(next http.Han
|
||||
return
|
||||
}
|
||||
|
||||
groups := userGroups(user)
|
||||
if groupName != "" {
|
||||
groups = append(groups, groupsFromHeaders(r, groupName, groupValueRegex, groupValueSeparator)...)
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), authUserKey("user"), user)
|
||||
ctx = context.WithValue(ctx, authUserKey("groups"), userGroups(user))
|
||||
ctx = context.WithValue(ctx, authUserKey("groups"), groups)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
+7
-1
@@ -132,7 +132,13 @@ func setupRouter(router *chi.Mux, historyPoller *historyPoller) {
|
||||
for _, u := range config.Config.Authentication.BasicAuth.Users {
|
||||
users[u.Username] = u.Password
|
||||
}
|
||||
router.Use(basicAuth(users, allowAuthBypass))
|
||||
router.Use(basicAuth(
|
||||
users,
|
||||
config.Config.Authentication.Header.GroupName,
|
||||
config.Config.Authentication.Header.GroupValueRegex,
|
||||
config.Config.Authentication.Header.GroupValueSeparator,
|
||||
allowAuthBypass,
|
||||
))
|
||||
}
|
||||
|
||||
if config.Config.Listen.Prefix != "/" {
|
||||
|
||||
@@ -85,7 +85,7 @@ level=info msg=" name: X-Auth"
|
||||
level=info msg=" value_re: ^(.+)$"
|
||||
level=info msg=" group_name: \"\""
|
||||
level=info msg=" group_value_re: \"\""
|
||||
level=info msg=" group_value_separator: \"\""
|
||||
level=info msg=" group_value_separator: ' '"
|
||||
level=info msg=" basicAuth:"
|
||||
level=info msg=" users: []"
|
||||
level=info msg="authorization:"
|
||||
|
||||
@@ -11,9 +11,9 @@ level=info msg="authentication:"
|
||||
level=info msg=" header:"
|
||||
level=info msg=" name: \"\""
|
||||
level=info msg=" value_re: \"\""
|
||||
level=info msg=" group_name: \"\""
|
||||
level=info msg=" group_value_re: \"\""
|
||||
level=info msg=" group_value_separator: \"\""
|
||||
level=info msg=" group_name: X-Groups"
|
||||
level=info msg=" group_value_re: .+"
|
||||
level=info msg=" group_value_separator: ','"
|
||||
level=info msg=" basicAuth:"
|
||||
level=info msg=" users:"
|
||||
level=info msg=" - username: number"
|
||||
@@ -267,6 +267,10 @@ level=info msg="Setting up proxy endpoints" alertmanager=local
|
||||
level=info msg="Configuration is valid"
|
||||
-- custom.yaml --
|
||||
authentication:
|
||||
header:
|
||||
group_name: X-Groups
|
||||
group_value_re: .+
|
||||
group_value_separator: ','
|
||||
basicAuth:
|
||||
users:
|
||||
- username: number
|
||||
|
||||
@@ -13,7 +13,7 @@ level=info msg=" name: \"\""
|
||||
level=info msg=" value_re: \"\""
|
||||
level=info msg=" group_name: \"\""
|
||||
level=info msg=" group_value_re: \"\""
|
||||
level=info msg=" group_value_separator: \"\""
|
||||
level=info msg=" group_value_separator: ' '"
|
||||
level=info msg=" basicAuth:"
|
||||
level=info msg=" users: []"
|
||||
level=info msg="authorization:"
|
||||
|
||||
@@ -13,7 +13,7 @@ level=info msg=" name: \"\""
|
||||
level=info msg=" value_re: \"\""
|
||||
level=info msg=" group_name: \"\""
|
||||
level=info msg=" group_value_re: \"\""
|
||||
level=info msg=" group_value_separator: \"\""
|
||||
level=info msg=" group_value_separator: ' '"
|
||||
level=info msg=" basicAuth:"
|
||||
level=info msg=" users: []"
|
||||
level=info msg="authorization:"
|
||||
|
||||
@@ -13,7 +13,7 @@ level=info msg=" name: \"\""
|
||||
level=info msg=" value_re: \"\""
|
||||
level=info msg=" group_name: \"\""
|
||||
level=info msg=" group_value_re: \"\""
|
||||
level=info msg=" group_value_separator: \"\""
|
||||
level=info msg=" group_value_separator: ' '"
|
||||
level=info msg=" basicAuth:"
|
||||
level=info msg=" users: []"
|
||||
level=info msg="authorization:"
|
||||
|
||||
@@ -15,7 +15,7 @@ level=info msg=" name: \"\""
|
||||
level=info msg=" value_re: \"\""
|
||||
level=info msg=" group_name: \"\""
|
||||
level=info msg=" group_value_re: \"\""
|
||||
level=info msg=" group_value_separator: \"\""
|
||||
level=info msg=" group_value_separator: ' '"
|
||||
level=info msg=" basicAuth:"
|
||||
level=info msg=" users: []"
|
||||
level=info msg="authorization:"
|
||||
|
||||
@@ -13,7 +13,7 @@ level=info msg=" name: \"\""
|
||||
level=info msg=" value_re: \"\""
|
||||
level=info msg=" group_name: \"\""
|
||||
level=info msg=" group_value_re: \"\""
|
||||
level=info msg=" group_value_separator: \"\""
|
||||
level=info msg=" group_value_separator: ' '"
|
||||
level=info msg=" basicAuth:"
|
||||
level=info msg=" users: []"
|
||||
level=info msg="authorization:"
|
||||
|
||||
@@ -13,7 +13,7 @@ level=info msg=" name: \"\""
|
||||
level=info msg=" value_re: \"\""
|
||||
level=info msg=" group_name: \"\""
|
||||
level=info msg=" group_value_re: \"\""
|
||||
level=info msg=" group_value_separator: \"\""
|
||||
level=info msg=" group_value_separator: ' '"
|
||||
level=info msg=" basicAuth:"
|
||||
level=info msg=" users: []"
|
||||
level=info msg="authorization:"
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
karma.bin-should-fail --config.file=karma.yaml
|
||||
! stdout .
|
||||
cmp stderr stderr.txt
|
||||
|
||||
-- stderr.txt --
|
||||
level=error msg="Execution failed" error="authentication.header.group_name is required when authentication.header.group_value_re is set"
|
||||
-- karma.yaml --
|
||||
alertmanager:
|
||||
servers:
|
||||
- name: default
|
||||
uri: https://127.0.0.1:9093
|
||||
authentication:
|
||||
header:
|
||||
group_value_re: "(.+)"
|
||||
@@ -0,0 +1,15 @@
|
||||
karma.bin-should-fail --config.file=karma.yaml
|
||||
! stdout .
|
||||
cmp stderr stderr.txt
|
||||
|
||||
-- stderr.txt --
|
||||
level=error msg="Execution failed" error="invalid regex for authentication.header.group_value_re: error parsing regexp: invalid nested repetition operator: `++`"
|
||||
-- karma.yaml --
|
||||
alertmanager:
|
||||
servers:
|
||||
- name: default
|
||||
uri: https://127.0.0.1:9093
|
||||
authentication:
|
||||
header:
|
||||
group_name: X-Groups
|
||||
group_value_re: "(.+++++.)"
|
||||
@@ -0,0 +1,14 @@
|
||||
karma.bin-should-fail --config.file=karma.yaml
|
||||
! stdout .
|
||||
cmp stderr stderr.txt
|
||||
|
||||
-- stderr.txt --
|
||||
level=error msg="Execution failed" error="authentication.header.group_value_re is required when authentication.header.group_name is set"
|
||||
-- karma.yaml --
|
||||
alertmanager:
|
||||
servers:
|
||||
- name: default
|
||||
uri: https://127.0.0.1:9093
|
||||
authentication:
|
||||
header:
|
||||
group_name: X-Groups
|
||||
@@ -163,8 +163,10 @@ func alerts(w http.ResponseWriter, r *http.Request) {
|
||||
ts, _ := start.UTC().MarshalText()
|
||||
|
||||
var username string
|
||||
var groups []string
|
||||
if config.Config.Authentication.Enabled {
|
||||
username = getUserFromContext(r)
|
||||
groups = getGroupsFromContext(r)
|
||||
}
|
||||
|
||||
upstreams := getUpstreams()
|
||||
@@ -207,6 +209,7 @@ func alerts(w http.ResponseWriter, r *http.Request) {
|
||||
resp.Authentication = models.AuthenticationInfo{
|
||||
Enabled: config.Config.Authentication.Enabled,
|
||||
Username: username,
|
||||
Groups: groups,
|
||||
}
|
||||
|
||||
if config.Config.Grid.Sorting.CustomValues.Labels != nil {
|
||||
|
||||
+168
-1
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
@@ -1140,12 +1141,16 @@ func TestAuthentication(t *testing.T) {
|
||||
name string
|
||||
headerName string
|
||||
headerRe string
|
||||
groupName string
|
||||
groupRe string
|
||||
groupSeparator string
|
||||
basicAuthUsers []config.AuthenticationUser
|
||||
requestHeaders map[string]string
|
||||
requestBasicAuthUser string
|
||||
requestBasicAuthPassword string
|
||||
responseCode int
|
||||
responseUsername string
|
||||
responseGroups []string
|
||||
}
|
||||
|
||||
authTests := []authTest{
|
||||
@@ -1207,6 +1212,7 @@ func TestAuthentication(t *testing.T) {
|
||||
requestBasicAuthPassword: "foobar",
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{},
|
||||
},
|
||||
{
|
||||
name: "header auth, missing header, 401",
|
||||
@@ -1241,6 +1247,7 @@ func TestAuthentication(t *testing.T) {
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{},
|
||||
},
|
||||
{
|
||||
name: "header auth, header correct #2, 200",
|
||||
@@ -1251,19 +1258,159 @@ func TestAuthentication(t *testing.T) {
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{},
|
||||
},
|
||||
{
|
||||
name: "header auth, no groups, 200",
|
||||
headerName: "X-Auth",
|
||||
headerRe: "Username (.+)",
|
||||
groupName: "X-Auth-Groups",
|
||||
groupRe: "(.+)",
|
||||
groupSeparator: ",",
|
||||
requestHeaders: map[string]string{
|
||||
"X-Auth": "Username john",
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{},
|
||||
},
|
||||
{
|
||||
name: "header auth, group present, 200",
|
||||
headerName: "X-Auth",
|
||||
headerRe: "Username (.+)",
|
||||
groupName: "X-Auth-Groups",
|
||||
groupRe: "(.+)",
|
||||
groupSeparator: ",",
|
||||
requestHeaders: map[string]string{
|
||||
"X-Auth": "Username john",
|
||||
"X-Auth-Groups": "foo",
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{"foo"},
|
||||
},
|
||||
{
|
||||
name: "header auth, unmatched groups, 200",
|
||||
headerName: "X-Auth",
|
||||
headerRe: "Username (.+)",
|
||||
groupName: "X-Auth-Groups",
|
||||
groupRe: "Groups: (.+)",
|
||||
groupSeparator: ",",
|
||||
requestHeaders: map[string]string{
|
||||
"X-Auth": "Username john",
|
||||
"X-Auth-Groups": "foo",
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{},
|
||||
},
|
||||
{
|
||||
name: "header auth, empty groups, 200",
|
||||
headerName: "X-Auth",
|
||||
headerRe: "Username (.+)",
|
||||
groupName: "X-Auth-Groups",
|
||||
groupRe: "Groups: (.+)",
|
||||
groupSeparator: ",",
|
||||
requestHeaders: map[string]string{
|
||||
"X-Auth": "Username john",
|
||||
"X-Auth-Groups": "Groups:",
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{},
|
||||
},
|
||||
{
|
||||
name: "header auth, empty groups with spaces, 200",
|
||||
headerName: "X-Auth",
|
||||
headerRe: "Username (.+)",
|
||||
groupName: "X-Auth-Groups",
|
||||
groupRe: "Groups: (.+)",
|
||||
groupSeparator: ",",
|
||||
requestHeaders: map[string]string{
|
||||
"X-Auth": "Username john",
|
||||
"X-Auth-Groups": "Groups: ",
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{},
|
||||
},
|
||||
{
|
||||
name: "header auth, multiple groups, 200",
|
||||
headerName: "X-Auth",
|
||||
headerRe: "Username (.+)",
|
||||
groupName: "X-Auth-Groups",
|
||||
groupRe: "(.+)",
|
||||
groupSeparator: ",",
|
||||
requestHeaders: map[string]string{
|
||||
"X-Auth": "Username john",
|
||||
"X-Auth-Groups": "foo,bar, baz baz ",
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{"foo", "bar", "baz baz"},
|
||||
},
|
||||
{
|
||||
name: "header auth, multiple groups separated by spaces, 200",
|
||||
headerName: "X-Auth",
|
||||
headerRe: "Username (.+)",
|
||||
groupName: "X-Auth-Groups",
|
||||
groupRe: "(.+)",
|
||||
groupSeparator: " ",
|
||||
requestHeaders: map[string]string{
|
||||
"X-Auth": "Username john",
|
||||
"X-Auth-Groups": "foo bar baz baz ",
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{"foo", "bar", "baz", "baz"},
|
||||
},
|
||||
{
|
||||
name: "header auth, only groups enabled, no basic auth, 200",
|
||||
groupName: "X-Auth-Groups",
|
||||
groupRe: "(.+)",
|
||||
groupSeparator: " ",
|
||||
requestHeaders: map[string]string{
|
||||
"X-Auth": "Username john",
|
||||
"X-Auth-Groups": "foo",
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "",
|
||||
responseGroups: []string{},
|
||||
},
|
||||
{
|
||||
name: "header auth, only groups enabled, basic auth, 200",
|
||||
basicAuthUsers: []config.AuthenticationUser{
|
||||
{Username: "john", Password: "foobar"},
|
||||
},
|
||||
requestBasicAuthUser: "john",
|
||||
requestBasicAuthPassword: "foobar",
|
||||
groupName: "X-Auth-Groups",
|
||||
groupRe: "Groups (.+)",
|
||||
groupSeparator: " ",
|
||||
requestHeaders: map[string]string{
|
||||
"X-Auth-Groups": "Groups foo bar",
|
||||
},
|
||||
responseCode: 200,
|
||||
responseUsername: "john",
|
||||
responseGroups: []string{"foo", "bar"},
|
||||
},
|
||||
}
|
||||
|
||||
zerolog.SetGlobalLevel(zerolog.FatalLevel)
|
||||
for _, testCase := range authTests {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
config.Config.Authentication.Header.Name = testCase.headerName
|
||||
config.Config.Authentication.Header.ValueRegex = testCase.headerRe
|
||||
config.Config.Authentication.Header.GroupName = testCase.groupName
|
||||
config.Config.Authentication.Header.GroupValueRegex = testCase.groupRe
|
||||
config.Config.Authentication.Header.GroupValueSeparator = testCase.groupSeparator
|
||||
config.Config.Authentication.BasicAuth.Users = testCase.basicAuthUsers
|
||||
r := testRouter()
|
||||
setupRouter(r, nil)
|
||||
mockCache()
|
||||
for _, path := range []string{
|
||||
"/",
|
||||
"/alerts.json",
|
||||
"/alertList.json",
|
||||
"/autocomplete.json?term=foo",
|
||||
"/labelNames.json",
|
||||
@@ -1276,7 +1423,23 @@ func TestAuthentication(t *testing.T) {
|
||||
"/metrics",
|
||||
"/metrics?bar=foo",
|
||||
} {
|
||||
req := httptest.NewRequest("GET", path, nil)
|
||||
method := "GET"
|
||||
var body io.Reader
|
||||
if path == "/alerts.json" {
|
||||
method = "POST"
|
||||
payload, err := json.Marshal(models.AlertsRequest{
|
||||
Filters: []string{},
|
||||
GridLimits: map[string]int{},
|
||||
DefaultGroupLimit: 50,
|
||||
})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.FailNow()
|
||||
}
|
||||
body = bytes.NewReader(payload)
|
||||
}
|
||||
|
||||
req := httptest.NewRequest(method, path, body)
|
||||
for k, v := range testCase.requestHeaders {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
@@ -1307,6 +1470,10 @@ func TestAuthentication(t *testing.T) {
|
||||
if ur.Authentication.Username != testCase.responseUsername {
|
||||
t.Errorf("Got Authentication.Username=%s, expected %s", ur.Authentication.Username, testCase.responseUsername)
|
||||
}
|
||||
if diff := cmp.Diff(ur.Authentication.Groups, testCase.responseGroups); diff != "" {
|
||||
t.Errorf("Incorrect groups list (-want +got):\n%s", diff)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
+20
-2
@@ -45,6 +45,9 @@ authentication:
|
||||
header:
|
||||
name: string
|
||||
value_re: regex
|
||||
group_name: string
|
||||
group_value_re: regex
|
||||
group_value_separator: string
|
||||
basicAuth:
|
||||
users:
|
||||
- username: string
|
||||
@@ -66,9 +69,9 @@ authentication:
|
||||
- `authentication:users:header:group_value_re` - Similar to
|
||||
`authentication:users:header:value_re`, but for groups instead of usernames.
|
||||
Must be set when `authentication:users:header:group_name` is set.
|
||||
- `authentication:users:header:group_value_separator` - If set, this will be
|
||||
- `authentication:users:header:group_value_separator` - This will be
|
||||
used to split the group header to multiple group names. The split is done
|
||||
before evaluating the value regex. Optional.
|
||||
after evaluating the value regex. Default value is `" "`.
|
||||
- `authentication:users` - list of users (username & password) allowed to login.
|
||||
Passwords are stored plain without any encryption.
|
||||
When set HTTP basic authentication will be used.
|
||||
@@ -107,6 +110,21 @@ authentication:
|
||||
value_re: ^(.+)$
|
||||
```
|
||||
|
||||
Example where the `X-Auth-User` and `X-Auth-Groups` headers will be used to
|
||||
set username and list of groups. This assume that `X-Auth-Groups` value has
|
||||
`Groups: foo,bar` syntax, where `foo` and `bar` are two groups user belongs to.
|
||||
|
||||
```YAML
|
||||
authentication:
|
||||
header:
|
||||
name: X-Auth-User
|
||||
value_re: ^(.+)$
|
||||
group_name: X-Auth-Groups
|
||||
group_value_re: 'Groups: (.+)'
|
||||
group_value_separator: ','
|
||||
|
||||
```
|
||||
|
||||
### Authorization
|
||||
|
||||
`authorization` section allows to configure authorization groups used in
|
||||
|
||||
@@ -289,6 +289,10 @@ func (config *configSchema) Read(flags *pflag.FlagSet) (string, error) {
|
||||
return "", fmt.Errorf("both authentication.basicAuth.users and authentication.header.name is set, only one can be enabled")
|
||||
}
|
||||
|
||||
if config.Authentication.Header.GroupValueSeparator == "" {
|
||||
config.Authentication.Header.GroupValueSeparator = " "
|
||||
}
|
||||
|
||||
if config.Authentication.Header.ValueRegex != "" {
|
||||
_, err = regex.CompileAnchored(config.Authentication.Header.ValueRegex)
|
||||
if err != nil {
|
||||
@@ -300,6 +304,17 @@ func (config *configSchema) Read(flags *pflag.FlagSet) (string, error) {
|
||||
} else if config.Authentication.Header.Name != "" {
|
||||
return "", fmt.Errorf("authentication.header.value_re is required when authentication.header.name is set")
|
||||
}
|
||||
if config.Authentication.Header.GroupValueRegex != "" {
|
||||
_, err = regex.CompileAnchored(config.Authentication.Header.GroupValueRegex)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid regex for authentication.header.group_value_re: %s", err.Error())
|
||||
}
|
||||
if config.Authentication.Header.GroupName == "" {
|
||||
return "", fmt.Errorf("authentication.header.group_name is required when authentication.header.group_value_re is set")
|
||||
}
|
||||
} else if config.Authentication.Header.GroupName != "" {
|
||||
return "", fmt.Errorf("authentication.header.group_value_re is required when authentication.header.group_name is set")
|
||||
}
|
||||
|
||||
for _, u := range config.Authentication.BasicAuth.Users {
|
||||
if u.Username == "" || u.Password == "" {
|
||||
|
||||
@@ -425,8 +425,9 @@ type Settings struct {
|
||||
}
|
||||
|
||||
type AuthenticationInfo struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Username string `json:"username"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Username string `json:"username"`
|
||||
Groups []string `json:"groups"`
|
||||
}
|
||||
|
||||
type APIGrid struct {
|
||||
|
||||
Reference in New Issue
Block a user