Skip to content

Commit 14cdda8

Browse files
committed
Updates from comments
Signed-off-by: Derek Collison <[email protected]>
1 parent 9f8330b commit 14cdda8

File tree

7 files changed

+228
-45
lines changed

7 files changed

+228
-45
lines changed

server/accounts_test.go

+155-19
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@
1414
package server
1515

1616
import (
17+
"encoding/base64"
18+
"encoding/json"
1719
"fmt"
1820
"os"
1921
"strings"
2022
"testing"
23+
24+
"github.com/nats-io/nkeys"
2125
)
2226

2327
func simpleAccountServer(t *testing.T) (*Server, *Account, *Account) {
@@ -45,9 +49,6 @@ func TestRegisterDuplicateAccounts(t *testing.T) {
4549

4650
func TestAccountIsolation(t *testing.T) {
4751
s, fooAcc, barAcc := simpleAccountServer(t)
48-
if fooAcc == nil || barAcc == nil {
49-
t.Fatalf("Error retrieving accounts for 'foo' and 'bar'")
50-
}
5152
cfoo, crFoo, _ := newClientForServer(s)
5253
if err := cfoo.registerWithAccount(fooAcc); err != nil {
5354
t.Fatalf("Error register client with 'foo' account: %v", err)
@@ -135,10 +136,18 @@ func TestNewAccountsFromClients(t *testing.T) {
135136
opts.AllowNewAccounts = true
136137
s = New(&opts)
137138

138-
c, _, _ = newClientForServer(s)
139+
c, cr, _ = newClientForServer(s)
139140
err := c.parse(connectOp)
140141
if err != nil {
141-
t.Fatalf("Received an error trying to create an account: %v", err)
142+
t.Fatalf("Received an error trying to connect: %v", err)
143+
}
144+
go c.parse([]byte("PING\r\n"))
145+
l, err = cr.ReadString('\n')
146+
if err != nil {
147+
t.Fatalf("Error reading response for client from server: %v", err)
148+
}
149+
if !strings.HasPrefix(l, "PONG\r\n") {
150+
t.Fatalf("PONG response incorrect: %q", l)
142151
}
143152
}
144153

@@ -255,7 +264,6 @@ func TestAccountParseConfig(t *testing.T) {
255264
if u.Username == "derek" {
256265
if u.Account != natsAcc {
257266
t.Fatalf("Expected to see the 'nats.io' account, but received %+v", u.Account)
258-
break
259267
}
260268
}
261269
}
@@ -302,8 +310,7 @@ func TestAccountParseConfigImportsExports(t *testing.T) {
302310
for _, acc := range opts.Accounts {
303311
if acc.Name == "nats.io" {
304312
natsAcc = acc
305-
}
306-
if acc.Name == "synadia" {
313+
} else if acc.Name == "synadia" {
307314
synAcc = acc
308315
}
309316
}
@@ -420,7 +427,7 @@ func TestImportExportConfigFailures(t *testing.T) {
420427
cf = createConfFile(t, []byte(`
421428
accounts {
422429
nats.io {
423-
exports = [{service: {account: nats.io, subject:"foo.*"}]
430+
exports = [{service: {account: nats.io, subject:"foo.*"}}]
424431
}
425432
}
426433
`))
@@ -490,6 +497,7 @@ func TestImportAuthorized(t *testing.T) {
490497
}
491498

492499
func TestSimpleMapping(t *testing.T) {
500+
t.Helper()
493501
s, fooAcc, barAcc := simpleAccountServer(t)
494502
defer s.Shutdown()
495503

@@ -555,7 +563,7 @@ func TestSimpleMapping(t *testing.T) {
555563

556564
l, err = crBar.ReadString('\n')
557565
if err != nil {
558-
t.Fatalf("Error reading from client 'baz': %v", err)
566+
t.Fatalf("Error reading from client 'bar': %v", err)
559567
}
560568
checkMsg(l, "2")
561569
checkPayload(crBar, []byte("hello\r\n"), t)
@@ -578,11 +586,11 @@ func TestNoPrefixWildcardMapping(t *testing.T) {
578586
t.Fatalf("Error registering client with 'bar' account: %v", err)
579587
}
580588

581-
if err := cfoo.acc.addStreamExport(">", []*Account{barAcc}); err != nil { // Public with no accounts defined.
582-
t.Fatalf("Error adding account export to client foo: %v", err)
589+
if err := cfoo.acc.addStreamExport(">", []*Account{barAcc}); err != nil {
590+
t.Fatalf("Error adding stream export to client foo: %v", err)
583591
}
584592
if err := cbar.acc.addStreamImport(fooAcc, "*", ""); err != nil {
585-
t.Fatalf("Error adding account import to client bar: %v", err)
593+
t.Fatalf("Error adding stream import to client bar: %v", err)
586594
}
587595

588596
// Normal Subscription on bar client for literal "foo".
@@ -631,11 +639,12 @@ func TestPrefixWildcardMapping(t *testing.T) {
631639
t.Fatalf("Error registering client with 'bar' account: %v", err)
632640
}
633641

634-
if err := cfoo.acc.addStreamExport(">", []*Account{barAcc}); err != nil { // Public with no accounts defined.
635-
t.Fatalf("Error adding account export to client foo: %v", err)
642+
if err := cfoo.acc.addStreamExport(">", []*Account{barAcc}); err != nil {
643+
t.Fatalf("Error adding stream export to client foo: %v", err)
636644
}
645+
// Checking that trailing '.' is accepted, tested that it is auto added above.
637646
if err := cbar.acc.addStreamImport(fooAcc, "*", "pub.imports."); err != nil {
638-
t.Fatalf("Error adding account import to client bar: %v", err)
647+
t.Fatalf("Error adding stream import to client bar: %v", err)
639648
}
640649

641650
// Normal Subscription on bar client for wildcard.
@@ -684,11 +693,11 @@ func TestPrefixWildcardMappingWithLiteralSub(t *testing.T) {
684693
t.Fatalf("Error registering client with 'bar' account: %v", err)
685694
}
686695

687-
if err := cfoo.acc.addStreamExport(">", []*Account{barAcc}); err != nil { // Public with no accounts defined.
688-
t.Fatalf("Error adding account export to client foo: %v", err)
696+
if err := cfoo.acc.addStreamExport(">", []*Account{barAcc}); err != nil {
697+
t.Fatalf("Error adding stream export to client foo: %v", err)
689698
}
690699
if err := cbar.acc.addStreamImport(fooAcc, "*", "pub.imports."); err != nil {
691-
t.Fatalf("Error adding account import to client bar: %v", err)
700+
t.Fatalf("Error adding stream import to client bar: %v", err)
692701
}
693702

694703
// Normal Subscription on bar client for wildcard.
@@ -819,6 +828,133 @@ func TestCrossAccountRequestReply(t *testing.T) {
819828
}
820829
}
821830

831+
func TestAccountMapsUsers(t *testing.T) {
832+
// Used for the nkey users to properly sign.
833+
seed1 := "SUAPM67TC4RHQLKBX55NIQXSMATZDOZK6FNEOSS36CAYA7F7TY66LP4BOM"
834+
seed2 := "SUAIS5JPX4X4GJ7EIIJEQ56DH2GWPYJRPWN5XJEDENJOZHCBLI7SEPUQDE"
835+
836+
confFileName := createConfFile(t, []byte(`
837+
accounts {
838+
synadia {
839+
users = [
840+
{user: derek, password: foo},
841+
{nkey: UCNGL4W5QX66CFX6A6DCBVDH5VOHMI7B2UZZU7TXAUQQSI2JPHULCKBR}
842+
]
843+
}
844+
nats {
845+
users = [
846+
{user: ivan, password: bar},
847+
{nkey: UDPGQVFIWZ7Q5UH4I5E6DBCZULQS6VTVBG6CYBD7JV3G3N2GMQOMNAUH}
848+
]
849+
}
850+
}
851+
`))
852+
defer os.Remove(confFileName)
853+
opts, err := ProcessConfigFile(confFileName)
854+
if err != nil {
855+
t.Fatalf("Unexpected error parsing config file: %v", err)
856+
}
857+
s := New(opts)
858+
synadia := s.LookupAccount("synadia")
859+
nats := s.LookupAccount("nats")
860+
861+
if synadia == nil || nats == nil {
862+
t.Fatalf("Expected non nil accounts during lookup")
863+
}
864+
865+
// Make sure a normal log in maps the accounts correctly.
866+
c, _, _ := newClientForServer(s)
867+
connectOp := []byte("CONNECT {\"user\":\"derek\",\"pass\":\"foo\"}\r\n")
868+
c.parse(connectOp)
869+
if c.acc != synadia {
870+
t.Fatalf("Expected the client's account to match 'synadia', got %v", c.acc)
871+
}
872+
// Also test client sublist.
873+
if c.sl != synadia.sl {
874+
t.Fatalf("Expected the client's sublist to match 'synadia' account")
875+
}
876+
877+
c, _, _ = newClientForServer(s)
878+
connectOp = []byte("CONNECT {\"user\":\"ivan\",\"pass\":\"bar\"}\r\n")
879+
c.parse(connectOp)
880+
if c.acc != nats {
881+
t.Fatalf("Expected the client's account to match 'nats', got %v", c.acc)
882+
}
883+
// Also test client sublist.
884+
if c.sl != nats.sl {
885+
t.Fatalf("Expected the client's sublist to match 'nats' account")
886+
}
887+
888+
// Now test nkeys as well.
889+
kp, _ := nkeys.FromSeed(seed1)
890+
pubKey, _ := kp.PublicKey()
891+
892+
c, cr, l := newClientForServer(s)
893+
// Check for Nonce
894+
var info nonceInfo
895+
err = json.Unmarshal([]byte(l[5:]), &info)
896+
if err != nil {
897+
t.Fatalf("Could not parse INFO json: %v\n", err)
898+
}
899+
if info.Nonce == "" {
900+
t.Fatalf("Expected a non-empty nonce with nkeys defined")
901+
}
902+
sigraw, err := kp.Sign([]byte(info.Nonce))
903+
if err != nil {
904+
t.Fatalf("Failed signing nonce: %v", err)
905+
}
906+
sig := base64.StdEncoding.EncodeToString(sigraw)
907+
908+
// PING needed to flush the +OK to us.
909+
cs := fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
910+
go c.parse([]byte(cs))
911+
l, _ = cr.ReadString('\n')
912+
if !strings.HasPrefix(l, "+OK") {
913+
t.Fatalf("Expected an OK, got: %v", l)
914+
}
915+
if c.acc != synadia {
916+
t.Fatalf("Expected the nkey client's account to match 'synadia', got %v", c.acc)
917+
}
918+
// Also test client sublist.
919+
if c.sl != synadia.sl {
920+
t.Fatalf("Expected the client's sublist to match 'synadia' account")
921+
}
922+
923+
// Now nats account nkey user.
924+
kp, _ = nkeys.FromSeed(seed2)
925+
pubKey, _ = kp.PublicKey()
926+
927+
c, cr, l = newClientForServer(s)
928+
// Check for Nonce
929+
err = json.Unmarshal([]byte(l[5:]), &info)
930+
if err != nil {
931+
t.Fatalf("Could not parse INFO json: %v\n", err)
932+
}
933+
if info.Nonce == "" {
934+
t.Fatalf("Expected a non-empty nonce with nkeys defined")
935+
}
936+
sigraw, err = kp.Sign([]byte(info.Nonce))
937+
if err != nil {
938+
t.Fatalf("Failed signing nonce: %v", err)
939+
}
940+
sig = base64.StdEncoding.EncodeToString(sigraw)
941+
942+
// PING needed to flush the +OK to us.
943+
cs = fmt.Sprintf("CONNECT {\"nkey\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", pubKey, sig)
944+
go c.parse([]byte(cs))
945+
l, _ = cr.ReadString('\n')
946+
if !strings.HasPrefix(l, "+OK") {
947+
t.Fatalf("Expected an OK, got: %v", l)
948+
}
949+
if c.acc != nats {
950+
t.Fatalf("Expected the nkey client's account to match 'nats', got %v", c.acc)
951+
}
952+
// Also test client sublist.
953+
if c.sl != nats.sl {
954+
t.Fatalf("Expected the client's sublist to match 'nats' account")
955+
}
956+
}
957+
822958
func BenchmarkNewRouteReply(b *testing.B) {
823959
opts := defaultServerOptions
824960
s := New(&opts)

server/auth.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,13 @@ type serviceImport struct {
6464
ae bool
6565
}
6666

67+
// importMap tracks the imported streams and services.
6768
type importMap struct {
6869
streams map[string]*streamImport
6970
services map[string]*serviceImport // TODO(dlc) sync.Map may be better.
7071
}
7172

73+
// exportMap tracks the exported streams and services.
7274
type exportMap struct {
7375
streams map[string]map[string]*Account
7476
services map[string]map[string]*Account
@@ -364,7 +366,7 @@ func (s *Server) checkAuthforWarnings() {
364366
}
365367
if warn {
366368
// Warning about using plaintext passwords.
367-
s.Warnf("Plaintext passwords detected. Use Nkeys or Bcrypt passwords in config files.")
369+
s.Warnf("Plaintext passwords detected, use nkeys or bcrypt.")
368370
}
369371
}
370372

@@ -480,6 +482,7 @@ func (s *Server) isClientAuthorized(c *client) bool {
480482
if err := pub.Verify(c.nonce, sig); err != nil {
481483
return false
482484
}
485+
c.RegisterNkeyUser(nkey)
483486
return true
484487
}
485488

0 commit comments

Comments
 (0)