veyron/security/flag: add a convenience method to read ACLs from flags
NewAuthorizerOrDie generates an authorizer using ACLs taken from
command line flags. Add a convenience method that can return the
ACLs. At the same time, update NewAuthorizerOrDie to use the veyron
flags system and a modules based test.
Change-Id: Ib1d32f6a74c2560df9ea69de68b6e7fd41f2d24a
diff --git a/security/flag/flag_test.go b/security/flag/flag_test.go
index 1d58998..3dbc118 100644
--- a/security/flag/flag_test.go
+++ b/security/flag/flag_test.go
@@ -1,89 +1,162 @@
package flag
import (
+ "bytes"
"flag"
+ "fmt"
+ "io"
"os"
"reflect"
"testing"
- tsecurity "v.io/core/veyron/lib/testutil/security"
-
"v.io/core/veyron2/security"
"v.io/core/veyron2/services/security/access"
+
+ "v.io/core/veyron/lib/modules"
+ "v.io/core/veyron/lib/testutil"
+ tsecurity "v.io/core/veyron/lib/testutil/security"
)
-func TestNewAuthorizerOrDie(t *testing.T) {
- type flagValue map[string]string
- testNewAuthorizerOrDie := func(flags flagValue, wantAuth security.Authorizer, wantPanic bool) {
- defer func() {
- if gotPanic := (recover() != nil); wantPanic != gotPanic {
- t.Errorf("AuthorizerFromFlags() with flags %v, got panic: %v, want panic: %v ", flags, gotPanic, wantPanic)
- }
- }()
- if got := NewAuthorizerOrDie(); !reflect.DeepEqual(got, wantAuth) {
- t.Errorf("AuthorizerFromFlags() with flags %v: got Authorizer: %v, want: %v", flags, got, wantAuth)
- }
- }
- clearACLFlags := func() {
- flag.Set("acl", "")
- flag.Set("acl_file", "")
- }
- var (
- acl1 = access.TaggedACLMap{}
- acl2 = access.TaggedACLMap{
- string(access.Read): access.ACL{
- In: []security.BlessingPattern{"veyron/alice", "veyron/bob"},
- },
- string(access.Write): access.ACL{
- In: []security.BlessingPattern{"veyron/alice"},
- },
- }
+func TestHelperProcess(t *testing.T) {
+ modules.DispatchInTest()
+}
- auth = func(a security.Authorizer, err error) security.Authorizer {
- if err != nil {
- panic(err)
- }
- return a
- }
- )
- acl2File := tsecurity.SaveACLToFile(acl2)
- defer os.Remove(acl2File)
+var (
+ acl1 = access.TaggedACLMap{}
+ acl2 = access.TaggedACLMap{
+ string(access.Read): access.ACL{
+ In: []security.BlessingPattern{"veyron/alice", "veyron/bob"},
+ },
+ string(access.Write): access.ACL{
+ In: []security.BlessingPattern{"veyron/alice"},
+ },
+ }
+
+ expectedAuthorizer = map[string]security.Authorizer{
+ "empty": auth(access.TaggedACLAuthorizer(acl1, access.TypicalTagType())),
+ "acl2": auth(access.TaggedACLAuthorizer(acl2, access.TypicalTagType())),
+ }
+)
+
+func init() {
+ testutil.Init()
+ modules.RegisterChild("fileAuth", "", fileAuth)
+ modules.RegisterChild("literalAuth", "", literalAuth)
+ modules.RegisterChild("tamFromFlag", "", tamFromFlag)
+}
+
+func auth(a security.Authorizer, err error) security.Authorizer {
+ if err != nil {
+ panic(err)
+ }
+ return a
+}
+
+func literalAuth(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+ nfargs := flag.CommandLine.Args()
+ want := expectedAuthorizer[nfargs[0]]
+ if got := NewAuthorizerOrDie(); !reflect.DeepEqual(got, want) {
+ fmt.Fprintf(stdout, "args %#v\n", args)
+ fmt.Fprintf(stdout, "AuthorizerFromFlags() got Authorizer: %v, want: %v", got, want)
+ }
+ return nil
+}
+
+func fileAuth(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+ // 0-th argument is the name of a file to open.
+ nfargs := flag.CommandLine.Args()
+ want := auth(access.TaggedACLAuthorizerFromFile(nfargs[0], access.TypicalTagType()))
+ if got := NewAuthorizerOrDie(); !reflect.DeepEqual(got, want) {
+ fmt.Fprintf(stdout, "args %#v\n", args)
+ fmt.Fprintf(stdout, "AuthorizerFromFlags() got Authorizer: %v, want: %v", got, want)
+ }
+ return nil
+}
+
+func tamFromFlag(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+ nfargs := flag.CommandLine.Args()
+ tam, err := TaggedACLMapFromFlag()
+ if err != nil {
+ fmt.Fprintf(stdout, "TaggedACLMapFromFlag() failed: %v", err)
+ return nil
+ }
+ got := auth(access.TaggedACLAuthorizer(tam, access.TypicalTagType()))
+ want := expectedAuthorizer[nfargs[0]]
+ if !reflect.DeepEqual(got, want) {
+ fmt.Fprintf(stdout, "args %#v\n", args)
+ fmt.Fprintf(stdout, "AuthorizerFromFlags() got Authorizer: %v, want: %v", got, want)
+ }
+ return nil
+}
+
+func TestNewAuthorizerOrDie(t *testing.T) {
+ sh, err := modules.NewShell(nil)
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
+ defer sh.Cleanup(os.Stderr, os.Stderr)
+
+ // Create a file.
+ acl2FileName := tsecurity.SaveACLToFile(acl2)
+ defer os.Remove(acl2FileName)
testdata := []struct {
- flags flagValue
- wantAuth security.Authorizer
- wantPanic bool
+ cmd string
+ flags []string
+ auth string
}{
{
- flags: flagValue{},
- wantAuth: nil,
+ cmd: "fileAuth",
+ flags: []string{"--veyron.acl.file", "runtime:" + acl2FileName},
+ auth: acl2FileName,
},
{
- flags: flagValue{"acl": "{}"},
- wantAuth: auth(access.TaggedACLAuthorizer(acl1, access.TypicalTagType())),
+ cmd: "literalAuth",
+ flags: []string{"--veyron.acl.literal", "{}"},
+ auth: "empty",
},
{
- flags: flagValue{"acl": `{"In":{"veyron/alice":"RW", "veyron/bob": "R"}}`},
- wantAuth: auth(access.TaggedACLAuthorizer(acl2, access.TypicalTagType())),
+ cmd: "literalAuth",
+ flags: []string{"--veyron.acl.literal", `{"In":{"veyron/alice":"RW", "veyron/bob": "R"}}`},
+ auth: "acl2",
},
{
- flags: flagValue{"acl": `{"In":{"veyron/bob":"R", "veyron/alice": "WR"}}`},
- wantAuth: auth(access.TaggedACLAuthorizer(acl2, access.TypicalTagType())),
+ cmd: "literalAuth",
+ flags: []string{"--veyron.acl.literal", `{"In":{"veyron/bob":"R", "veyron/alice": "WR"}}`},
+ auth: "acl2",
},
{
- flags: flagValue{"acl_file": acl2File},
- wantAuth: auth(access.TaggedACLAuthorizerFromFile(acl2File, access.TypicalTagType())),
+ cmd: "tamFromFlag",
+ flags: []string{"--veyron.acl.file", "runtime:" + acl2FileName},
+ auth: "acl2",
},
{
- flags: flagValue{"acl_file": acl2File, "acl": `{"In":{"veyron/alice":"RW", "veyron/bob": "R"}}`},
- wantPanic: true,
+ cmd: "tamFromFlag",
+ flags: []string{"--veyron.acl.literal", "{}"},
+ auth: "empty",
+ },
+ {
+ cmd: "tamFromFlag",
+ flags: []string{"--veyron.acl.literal", `{"In":{"veyron/alice":"RW", "veyron/bob": "R"}}`},
+ auth: "acl2",
+ },
+ {
+ cmd: "tamFromFlag",
+ flags: []string{"--veyron.acl.literal", `{"In":{"veyron/bob":"R", "veyron/alice": "WR"}}`},
+ auth: "acl2",
},
}
- for _, d := range testdata {
- clearACLFlags()
- for f, v := range d.flags {
- flag.Set(f, v)
+
+ for _, td := range testdata {
+ fp := append(td.flags, td.auth)
+ h, err := sh.Start(td.cmd, nil, fp...)
+ if err != nil {
+ t.Errorf("unexpected error: %s", err)
}
- testNewAuthorizerOrDie(d.flags, d.wantAuth, d.wantPanic)
+ b := new(bytes.Buffer)
+ h.Shutdown(b, os.Stderr)
+ if got := b.String(); got != "" {
+ t.Errorf(got)
+ }
}
}