Validate options for user embedded NATS Server in their app

We were doing option validation from options parsing, but added
it also for Users/NKeyUsers options.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
This commit is contained in:
Ivan Kozlovic
2020-09-18 13:09:52 -06:00
parent e84f1cf52c
commit 04f96813a7
2 changed files with 79 additions and 0 deletions

View File

@@ -922,9 +922,35 @@ func comparePasswords(serverPassword, clientPassword string) bool {
}
func validateAuth(o *Options) error {
for _, u := range o.Users {
if err := validateAllowedConnectionTypes(u.AllowedConnectionTypes); err != nil {
return err
}
}
for _, u := range o.Nkeys {
if err := validateAllowedConnectionTypes(u.AllowedConnectionTypes); err != nil {
return err
}
}
return validateNoAuthUser(o, o.NoAuthUser)
}
func validateAllowedConnectionTypes(m map[string]struct{}) error {
for ct := range m {
ctuc := strings.ToUpper(ct)
switch ctuc {
case jwt.ConnectionTypeStandard, jwt.ConnectionTypeWebsocket, jwt.ConnectionTypeLeafnode:
default:
return fmt.Errorf("unknown connection type %q", ct)
}
if ctuc != ct {
delete(m, ct)
m[ctuc] = struct{}{}
}
}
return nil
}
func validateNoAuthUser(o *Options, noAuthUser string) error {
if noAuthUser == "" {
return nil

View File

@@ -15,7 +15,10 @@ package server
import (
"reflect"
"strings"
"testing"
"github.com/nats-io/jwt/v2"
)
func TestUserCloneNilPermissions(t *testing.T) {
@@ -101,3 +104,53 @@ func TestUserCloneNil(t *testing.T) {
t.Fatalf("Expected nil, got: %+v", clone)
}
}
func TestUserUnknownAllowedConnectionType(t *testing.T) {
o := DefaultOptions()
o.Users = []*User{&User{
Username: "user",
Password: "pwd",
AllowedConnectionTypes: testCreateAllowedConnectionTypes([]string{jwt.ConnectionTypeStandard, "someNewType"}),
}}
_, err := NewServer(o)
if err == nil || !strings.Contains(err.Error(), "connection type") {
t.Fatalf("Expected error about unknown connection type, got %v", err)
}
o.Users[0].AllowedConnectionTypes = testCreateAllowedConnectionTypes([]string{"websocket"})
s, err := NewServer(o)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
s.mu.Lock()
user := s.opts.Users[0]
s.mu.Unlock()
for act := range user.AllowedConnectionTypes {
if act != jwt.ConnectionTypeWebsocket {
t.Fatalf("Expected map to have been updated with proper case, got %v", act)
}
}
// Same with NKey user now.
o.Users = nil
o.Nkeys = []*NkeyUser{&NkeyUser{
Nkey: "somekey",
AllowedConnectionTypes: testCreateAllowedConnectionTypes([]string{jwt.ConnectionTypeStandard, "someNewType"}),
}}
_, err = NewServer(o)
if err == nil || !strings.Contains(err.Error(), "connection type") {
t.Fatalf("Expected error about unknown connection type, got %v", err)
}
o.Nkeys[0].AllowedConnectionTypes = testCreateAllowedConnectionTypes([]string{"websocket"})
s, err = NewServer(o)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
s.mu.Lock()
nkey := s.opts.Nkeys[0]
s.mu.Unlock()
for act := range nkey.AllowedConnectionTypes {
if act != jwt.ConnectionTypeWebsocket {
t.Fatalf("Expected map to have been updated with proper case, got %v", act)
}
}
}