Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[added] support for wildcard imports #343

Merged
merged 1 commit into from
Jan 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions cmd/addimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,6 @@ func (p *AddImportParams) addLocalExport(ctx ActionCtx) (bool, error) {
subject = strings.Join(a, ".")
subject, err = cli.Prompt("export subject", subject, cli.Val(func(s string) error {
sub := jwt.Subject(s)
if sub.HasWildCards() {
return errors.New("services cannot have wildcard subjects")
}
var vr jwt.ValidationResults
sub.Validate(&vr)
if len(vr.Issues) > 0 {
Expand Down Expand Up @@ -434,11 +431,6 @@ func (p *AddImportParams) PostInteractive(ctx ActionCtx) error {
if !vr.IsEmpty() {
return errors.New(vr.Issues[0].Error())
}

if sub.HasWildCards() {
return fmt.Errorf("%s cannot have wildcards", m)
}

return nil
}))
if err != nil {
Expand Down Expand Up @@ -477,18 +469,11 @@ func (p *AddImportParams) Validate(ctx ActionCtx) error {
// local becomes Subject for services, or prefix for streams
sub := jwt.Subject(p.local)
if sub.HasWildCards() {
if kind == jwt.Service {
return errors.New("local subject cannot have wildcards")
} else {
if kind == jwt.Stream {
return errors.New("stream prefix subject cannot have wildcards")
}
}

resub := jwt.Subject(p.remote)
if kind == jwt.Service && resub.HasWildCards() {
return errors.New("imported services cannot have wildcards")
}

for _, im := range p.filter(kind, p.claim.Imports) {
remote := string(im.Subject)
if im.Type == jwt.Service {
Expand Down
82 changes: 46 additions & 36 deletions cmd/addimport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"

Expand Down Expand Up @@ -175,7 +176,7 @@ func Test_AddServiceImportGeneratingTokenInteractive(t *testing.T) {

cmd := createAddImportCmd()
HoistRootFlags(cmd)
input := []interface{}{1, true, 1, "barfoo.xx", true, "my import", "foobar.yy"}
input := []interface{}{1, true, 1, "barfoo.*.xx", true, "my import", "foobar.yy"}
_, _, err = ExecuteInteractiveCmd(cmd, input)
require.NoError(t, err)

Expand All @@ -184,7 +185,7 @@ func Test_AddServiceImportGeneratingTokenInteractive(t *testing.T) {
require.Len(t, ac.Imports, 1)
require.Equal(t, true, ac.Imports[0].Share)
require.Equal(t, "my import", ac.Imports[0].Name)
require.Equal(t, "barfoo.xx", string(ac.Imports[0].To))
require.Equal(t, "barfoo.*.xx", string(ac.Imports[0].To))
require.Equal(t, "foobar.yy", string(ac.Imports[0].Subject))
require.Equal(t, apub, ac.Imports[0].Account)
}
Expand Down Expand Up @@ -243,7 +244,7 @@ func Test_AddImport_PublicInteractive(t *testing.T) {
cmd := createAddImportCmd()
HoistRootFlags(cmd)
// B, public, A's pubkey, local sub, service, name test, remote subj "test.foobar.alberto, key
input := []interface{}{1, false, true, apub, "foobar.x", true, "test", "test.foobar.alberto", 0}
input := []interface{}{1, false, true, apub, "foobar.x.*", true, "test", "test.foobar.alberto.*", 0}
_, _, err = ExecuteInteractiveCmd(cmd, input, "-i")
require.NoError(t, err)

Expand All @@ -252,8 +253,8 @@ func Test_AddImport_PublicInteractive(t *testing.T) {
require.Len(t, ac.Imports, 1)
require.Equal(t, "test", ac.Imports[0].Name)
// for services remote local is subject, remote is to
require.Equal(t, "test.foobar.alberto", string(ac.Imports[0].Subject))
require.Equal(t, "foobar.x", string(ac.Imports[0].To))
require.Equal(t, "test.foobar.alberto.*", string(ac.Imports[0].Subject))
require.Equal(t, "foobar.x.*", string(ac.Imports[0].To))
require.Equal(t, jwt.Service, ac.Imports[0].Type)
require.Equal(t, apub, ac.Imports[0].Account)
}
Expand All @@ -264,7 +265,7 @@ func Test_AddImport_PublicImportsInteractive(t *testing.T) {

ts.AddAccount(t, "A")
ts.AddExport(t, "A", jwt.Stream, "foobar.>", true)
ts.AddExport(t, "A", jwt.Service, "q", true)
ts.AddExport(t, "A", jwt.Service, "q.*", true)

akp := ts.GetAccountKey(t, "A")
require.NotNil(t, akp)
Expand All @@ -290,15 +291,15 @@ func Test_AddImport_PublicImportsInteractive(t *testing.T) {
require.Equal(t, apub, ac.Imports[0].Account)

// B, don't pick, public, A's pubkey, remote sub, service, name test, local subj "test.foobar.>, key
input = []interface{}{1, false, true, apub, "q", true, "q", "qq", 0}
input = []interface{}{1, false, true, apub, "q.*", true, "q", "qq", 0}
_, _, err = ExecuteInteractiveCmd(cmd, input)
require.NoError(t, err)

ac, err = ts.Store.ReadAccountClaim("B")
require.NoError(t, err)
require.Len(t, ac.Imports, 2)
require.Equal(t, "q", ac.Imports[1].Name)
require.Equal(t, "q", string(ac.Imports[1].To))
require.Equal(t, "q.*", string(ac.Imports[1].To))
require.Equal(t, "qq", string(ac.Imports[1].Subject))
require.True(t, ac.Imports[1].IsService())
require.Equal(t, apub, ac.Imports[1].Account)
Expand Down Expand Up @@ -464,34 +465,6 @@ func Test_ImportServiceHandlesDecorations(t *testing.T) {
require.Equal(t, bc.Imports[0].To, bc.Imports[0].Subject)
}

func Test_ImportServiceLocalWildcards(t *testing.T) {
ts := NewTestStore(t, "test")
defer ts.Done(t)

ts.AddAccount(t, "A")
ts.AddExport(t, "A", jwt.Service, "q.>", true)
apk := ts.GetAccountPublicKey(t, "A")

ts.AddAccount(t, "B")
_, _, err := ExecuteCmd(createAddImportCmd(), "--account", "B", "--service", "--src-account", apk, "--remote-subject", "q.a", "--local-subject", "q.>")
require.Error(t, err)
require.Contains(t, "local subject cannot have wildcards", err.Error())
}

func Test_ImportStreamLocalWildcards(t *testing.T) {
ts := NewTestStore(t, "test")
defer ts.Done(t)

ts.AddAccount(t, "A")
ts.AddExport(t, "A", jwt.Stream, "s.>", true)
apk := ts.GetAccountPublicKey(t, "A")

ts.AddAccount(t, "B")
_, _, err := ExecuteCmd(createAddImportCmd(), "--account", "B", "--src-account", apk, "--remote-subject", "s.>", "--local-subject", "t.>")
require.Error(t, err)
require.Contains(t, "stream prefix subject cannot have wildcards", err.Error())
}

func Test_AddImportToAccount(t *testing.T) {
ts := NewTestStore(t, t.Name())
defer ts.Done(t)
Expand All @@ -508,3 +481,40 @@ func Test_AddImportToAccount(t *testing.T) {
require.NoError(t, err)
require.Len(t, bc.Imports, 1)
}

func Test_AddWilcdardImport(t *testing.T) {
ts := NewTestStore(t, "test")
defer ts.Done(t)

ts.AddAccount(t, "B")
ts.AddAccount(t, "A")
ts.AddExport(t, "A", jwt.Service, "priv-srvc.>", false)
ts.AddExport(t, "A", jwt.Stream, "priv-strm.>", false)
ts.AddExport(t, "A", jwt.Service, "pub-srvc.>", true)
ts.AddExport(t, "A", jwt.Stream, "pub-strm.>", true)

aPub := ts.GetAccountPublicKey(t, "A")

srvcToken := ts.GenerateActivation(t, "A", "priv-srvc.>", "B")
srvcFp := filepath.Join(ts.Dir, "srvc-token.jwt")
require.NoError(t, Write(srvcFp, []byte(srvcToken)))
defer os.Remove(srvcFp)

strmToken := ts.GenerateActivation(t, "A", "priv-strm.>", "B")
strmFp := filepath.Join(ts.Dir, "strm-token.jwt")
require.NoError(t, Write(strmFp, []byte(strmToken)))
defer os.Remove(strmFp)

tests := CmdTests{
{createAddImportCmd(), []string{"add", "import", "--account", "B", "--token", srvcFp}, nil,
[]string{"added service import"}, false},
{createAddImportCmd(), []string{"add", "import", "--account", "B", "--token", strmFp}, nil,
[]string{"added stream import"}, false},
{createAddImportCmd(), []string{"add", "import", "--account", "B", "--src-account", aPub, "--service",
"--remote-subject", "pub-srvc.>"}, nil, []string{"added service import"}, false},
{createAddImportCmd(), []string{"add", "import", "--account", "B", "--src-account", aPub,
"--remote-subject", "pub-strm.>"}, nil, []string{"added stream import"}, false},
}

tests.Run(t, "root", "add")
}
8 changes: 0 additions & 8 deletions cmd/generateactivation.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ func (p *GenerateActivationParams) PostInteractive(ctx ActionCtx) error {
if p.subject == "" {
p.subject = string(p.export.Subject)
}
kind := p.export.Type

p.subject, err = cli.Prompt("subject", p.subject, cli.Val(func(v string) error {
t := jwt.Subject(v)
Expand All @@ -145,9 +144,6 @@ func (p *GenerateActivationParams) PostInteractive(ctx ActionCtx) error {
if len(vr.Issues) > 0 {
return errors.New(vr.Issues[0].Description)
}
if kind == jwt.Service && t.HasWildCards() {
return errors.New("services cannot have wildcards")
}
if t != p.export.Subject && !t.IsContainedIn(p.export.Subject) {
return fmt.Errorf("%q doesn't contain %q", string(p.export.Subject), string(t))
}
Expand Down Expand Up @@ -213,10 +209,6 @@ func (p *GenerateActivationParams) Validate(ctx ActionCtx) error {
}
}

if p.export.Type == jwt.Service && sub.HasWildCards() {
return fmt.Errorf("services cannot have wildcards %q", p.subject)
}

if p.export.Subject == "" {
return fmt.Errorf("a private export for %q was not found in account %q", p.subject, p.AccountContextParams.Name)
}
Expand Down