// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package access_test

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"
	"io/ioutil"
	"os"
	"reflect"
	"sort"
	"testing"
	"time"

	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/security/access/internal"
	"v.io/v23/vdl"
	"v.io/v23/verror"
)

func authorize(authorizer security.Authorizer, params *security.CallParams) error {
	ctx, cancel := context.RootContext()
	defer cancel()
	return authorizer.Authorize(ctx, security.NewCall(params))
}

func enforceable(al access.AccessList, p security.Principal) error {
	ctx, cancel := context.RootContext()
	defer cancel()
	return al.Enforceable(ctx, p)
}

func TestAccessListAuthorizer(t *testing.T) {
	var (
		pali = newPrincipal(t)
		pbob = newPrincipal(t)
		pche = newPrincipal(t)

		expired, _ = security.NewExpiryCaveat(time.Now().Add(-1 * time.Minute))

		ali, _                = pbob.BlessSelf("ali")
		bob, _                = pbob.BlessSelf("bob")
		bobSelf, _            = pbob.BlessSelf("bob:self")
		bobDelegate, _        = pbob.Bless(pche.PublicKey(), bob, "delegate:che", security.UnconstrainedUse())
		bobDelegateBad, _     = pbob.Bless(pche.PublicKey(), bob, "delegate:badman", security.UnconstrainedUse())
		bobDelegateExpired, _ = pbob.Bless(pche.PublicKey(), bob, "delegate:che", expired)

		bobUnion, _    = security.UnionOfBlessings(bobDelegate, bobDelegateExpired)
		bobBadUnion, _ = security.UnionOfBlessings(bobDelegateBad, bobDelegateExpired)

		acl = access.AccessList{
			In:    []security.BlessingPattern{"bob:delegate", "bob:self"},
			NotIn: []string{"bob:delegate:badman"},
		}

		tests = []struct {
			B         security.Blessings
			Authorize bool
		}{
			{bob, false},
			{bobSelf, true},
			{bobDelegate, true},
			{bobDelegateBad, false},
			{bobDelegateExpired, false},
			{bobUnion, true},
			{bobBadUnion, false},
		}
	)
	for _, test := range tests {
		err := authorize(acl, &security.CallParams{
			LocalPrincipal:  pali,
			LocalBlessings:  ali,
			RemoteBlessings: test.B,
		})
		if test.Authorize && err != nil {
			t.Errorf("%v: Got error %v", test.B, err)
		} else if errid := verror.ErrorID(err); !test.Authorize && errid != access.ErrAccessListMatch.ID {
			t.Errorf("%v: Got error %v (errorid=%v) want errorid %v", test.B, err, errid, access.ErrAccessListMatch.ID)
		}
	}
}

func TestAccessListEnforceable(t *testing.T) {
	p := newPrincipal(t)
	if key, err := p.PublicKey().MarshalBinary(); err != nil {
		t.Fatal(err)
	} else {
		for _, pattern := range []security.BlessingPattern{"ali:spouse:$", "bob:friend"} {
			if err := p.Roots().Add(key, pattern); err != nil {
				t.Fatal(err)
			}
		}
	}

	type (
		bp []security.BlessingPattern // shorthand
		s  []string                   // shorthand
	)

	tests := []struct {
		al       access.AccessList
		errID    verror.ID
		rejected []security.BlessingPattern
	}{
		{
			al: access.AccessList{
				In:    bp{"$", "ali:spouse:$", "bob:friend:$", "bob:friend:colleague"},
				NotIn: s{"ali:spouse:friend", "bob"}, // NotIn patterns don't matter.
			},
		},
		{
			al: access.AccessList{
				In:    bp{"bob:friend:$", "ali:$:spouse", "bob::friend", "bob:..."}, // invalid patterns are rejected
				NotIn: s{"ali:spouse:friend", "bob"},
			},
			errID:    access.ErrUnenforceablePatterns.ID,
			rejected: bp{"ali:$:spouse", "bob::friend", "bob:..."},
		},
		{
			al: access.AccessList{
				In:    bp{"ali:spouse:$", "bob:friend:$", "ali", "ali:$", "ali:spouse", "ali:spouse:friend", "bob", "bob:$", "bob:spouse"}, // unrecognized patterns are rejected
				NotIn: s{"ali:spouse:friend", "bob"},
			},
			errID:    access.ErrUnenforceablePatterns.ID,
			rejected: bp{"ali", "ali:$", "ali:spouse", "ali:spouse:friend", "bob", "bob:$", "bob:spouse"},
		},
		{
			al: access.AccessList{
				In:    bp{"..."},
				NotIn: s{"bob:friend"},
			},
			errID: access.ErrInvalidOpenAccessList.ID,
		},
		{
			al: access.AccessList{
				In: bp{"...", "bob:friend"},
			},
			errID: access.ErrInvalidOpenAccessList.ID,
		},
	}
	for _, test := range tests {
		gotErr := enforceable(test.al, p)
		if (test.errID == "" && gotErr != nil) || (verror.ErrorID(gotErr) != test.errID) {
			t.Errorf("%v.Enforceable(...): got error %v, want error with ID %v", test.al, gotErr, test.errID)
		}
		if test.errID != access.ErrUnenforceablePatterns.ID {
			continue
		}

		gotRejected := access.IsUnenforceablePatterns(gotErr)
		sort.Sort(byPattern(gotRejected))
		sort.Sort(byPattern(test.rejected))
		if !reflect.DeepEqual(gotRejected, test.rejected) {
			t.Errorf("IsUnenforceablePatterns(%v): got rejected pattern %v, want %v", gotErr, gotRejected, test.rejected)
		}
	}
}

type byPattern []security.BlessingPattern

func (a byPattern) Len() int           { return len(a) }
func (a byPattern) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a byPattern) Less(i, j int) bool { return a[i] < a[j] }

// TestPermissionsAuthorizer is both a test and a demonstration of the use of
// the access.PermissionsAuthorizer and interaction with interface specification
// in VDL.
func TestPermissionsAuthorizer(t *testing.T) {
	type P []security.BlessingPattern
	type S []string
	// access.Permissions to test against.
	perms := access.Permissions{
		"R": {
			In: P{security.AllPrincipals},
		},
		"W": {
			In:    P{"ali:family", "bob", "che:$"},
			NotIn: S{"bob:acquaintances"},
		},
		"X": {
			In: P{"ali:family:boss:$", "superman:$"},
		},
	}
	type testcase struct {
		Method string
		Client security.Blessings
	}

	authorizer, err := access.PermissionsAuthorizer(perms, vdl.TypeOf(internal.Read))
	if err != nil {
		t.Fatalf("Could not create authorizer: %v", err)
	}

	var (
		// Two principals: The "server" and the "client"
		pserver   = newPrincipal(t)
		pclient   = newPrincipal(t)
		server, _ = pserver.BlessSelf("server")

		// B generates the provided blessings for the client and ensures
		// that the server will recognize them.
		B = func(names ...string) security.Blessings {
			var ret security.Blessings
			for _, name := range names {
				b, err := pclient.BlessSelf(name)
				if err != nil {
					t.Fatalf("%q: %v", name, err)
				}
				// Since this test uses trustAllRoots, no need
				// to call AddToRoots(pserver, b) to get the server
				// to recognize the client.
				if ret, err = security.UnionOfBlessings(ret, b); err != nil {
					t.Fatal(err)
				}
			}
			return ret
		}

		run = func(test testcase) error {
			return authorize(authorizer, &security.CallParams{
				LocalPrincipal:  pserver,
				LocalBlessings:  server,
				RemoteBlessings: test.Client,
				Method:          test.Method,
				MethodTags:      methodTags(test.Method),
			})
		}
	)

	// Test cases where access should be granted to methods with tags on
	// them.
	for _, test := range []testcase{
		{"Get", security.Blessings{}},
		{"Get", B("ali")},
		{"Get", B("bob:friend", "che:enemy")},

		{"Put", B("ali:family:mom")},
		{"Put", B("bob:friends")},
		{"Put", B("bob:acquantainces:carol", "che")}, // Access granted because of "che"

		{"Resolve", B("superman")},
		{"Resolve", B("ali:family:boss")},
	} {
		if err := run(test); err != nil {
			t.Errorf("Access denied to method %q to %v: %v", test.Method, test.Client, err)
		}
	}
	// Test cases where access should be denied.
	for _, test := range []testcase{
		// Nobody is denied access to "Get"
		{"Put", B("ali", "bob:acquaintances", "bob:acquaintances:dave", "che:friend", "dave")},
		{"Resolve", B("ali", "ali:friend", "ali:family", "ali:family:friend", "alice:family:boss:friend", "superman:friend")},
		// Since there are no tags on the NoTags method, it has an
		// empty AccessList.  No client will have access.
		{"NoTags", B("ali", "ali:family:boss", "bob", "che", "superman")},
	} {
		if err := run(test); err == nil {
			t.Errorf("Access to %q granted to %v", test.Method, test.Client)
		}
	}
}

func TestPermissionsAuthorizerSelfRPCs(t *testing.T) {
	var (
		// Client and server are the same principal, though have
		// different blessings.
		p         = newPrincipal(t)
		client, _ = p.BlessSelf("client")
		server, _ = p.BlessSelf("server")
		// Authorizer with a access.Permissions that grants read access to
		// anyone, write/execute access to noone.
		typ           internal.MyTag
		authorizer, _ = access.PermissionsAuthorizer(access.Permissions{"R": {In: []security.BlessingPattern{"nobody:$"}}}, vdl.TypeOf(typ))
	)
	for _, test := range []string{"Put", "Get", "Resolve", "NoTags"} {
		params := &security.CallParams{
			LocalPrincipal:  p,
			LocalBlessings:  server,
			RemoteBlessings: client,
			Method:          test,
			MethodTags:      methodTags(test),
		}
		if err := authorize(authorizer, params); err != nil {
			t.Errorf("Got error %v for method %q", err, test)
		}
	}
}

func TestPermissionsAuthorizerWithNilAccessList(t *testing.T) {
	var (
		authorizer, _ = access.PermissionsAuthorizer(nil, vdl.TypeOf(internal.Read))
		pserver       = newPrincipal(t)
		pclient       = newPrincipal(t)
		server, _     = pserver.BlessSelf("server")
		client, _     = pclient.BlessSelf("client")
	)
	for _, test := range []string{"Put", "Get", "Resolve", "NoTags"} {
		params := &security.CallParams{
			LocalPrincipal:  pserver,
			LocalBlessings:  server,
			RemoteBlessings: client,
			Method:          test,
			MethodTags:      methodTags(test),
		}
		if err := authorize(authorizer, params); err == nil {
			t.Errorf("nil access.Permissions authorized method %q, %v", test, err)
		}
	}
}

func TestPermissionsAuthorizerFromFile(t *testing.T) {
	file, err := ioutil.TempFile("", "TestPermissionsAuthorizerFromFile")
	if err != nil {
		t.Fatal(err)
	}
	filename := file.Name()
	file.Close()
	defer os.Remove(filename)

	var (
		authorizer, _  = access.PermissionsAuthorizerFromFile(filename, vdl.TypeOf(internal.Read))
		pserver        = newPrincipal(t)
		pclient        = newPrincipal(t)
		server, _      = pserver.BlessSelf("alice")
		alicefriend, _ = pserver.Bless(pclient.PublicKey(), server, "friend:bob", security.UnconstrainedUse())
		params         = &security.CallParams{
			LocalPrincipal:  pserver,
			LocalBlessings:  server,
			RemoteBlessings: alicefriend,
			Method:          "Get",
			MethodTags:      methodTags("Get"),
		}
	)
	// Since this test is using trustAllRoots{}, do not need
	// AddToRoots(pserver, server) to make pserver recognize itself as an
	// authority on blessings matching "alice".

	// "alice:friend:bob" should not have access to internal.Read methods like Get.
	if err := authorize(authorizer, params); err == nil {
		t.Fatalf("Expected authorization error as %v is not on the AccessList for Read operations", alicefriend)
	}
	// Rewrite the file giving access
	if err := ioutil.WriteFile(filename, []byte(`{"R": { "In":["alice:friend"] }}`), 0600); err != nil {
		t.Fatal(err)
	}
	// Now should have access
	if err := authorize(authorizer, params); err != nil {
		t.Fatal(err)
	}
}

func TestTagTypeMustBeString(t *testing.T) {
	type I int
	if auth, err := access.PermissionsAuthorizer(access.Permissions{}, vdl.TypeOf(I(0))); err == nil || auth != nil {
		t.Errorf("Got (%v, %v), wanted error since tag type is not a string", auth, err)
	}
	if auth, err := access.PermissionsAuthorizerFromFile("does_not_matter", vdl.TypeOf(I(0))); err == nil || auth != nil {
		t.Errorf("Got (%v, %v), wanted error since tag type is not a string", auth, err)
	}
}

// TestMultipleTags will fail if PermissionsAuthorizer authorizes a request to
// a method with multiple tags. Alternatives considered were "must be present
// in access list for *all* tags", "must be present in access list for *any*
// tag" and "must be present in access list for *first* tag". Cases can be made
// for any of them and until there is more mileage on the use of multiple tags,
// take the conservative approach of considering multiple tags an error.
func TestMultipleTags(t *testing.T) {
	var (
		allowAll = access.AccessList{In: []security.BlessingPattern{security.AllPrincipals}}
		perms    = access.Permissions{
			"R": allowAll,
			"W": allowAll,
		}
		authorizer, _ = access.PermissionsAuthorizer(perms, vdl.TypeOf(internal.Read))
		pserver       = newPrincipal(t)
		pclient       = newPrincipal(t)
		server, _     = pserver.BlessSelf("server")
		client, _     = pclient.BlessSelf("client")
		call          = &security.CallParams{
			LocalPrincipal:  pserver,
			LocalBlessings:  server,
			RemoteBlessings: client,
			Method:          "Get",
		}
		tags = []*vdl.Value{vdl.ValueOf(internal.Read), vdl.ValueOf(internal.Write)}
	)
	// Access should be granted if any of the two tags are present.
	for _, tag := range tags {
		call.MethodTags = []*vdl.Value{tag}
		if err := authorize(authorizer, call); err != nil {
			t.Errorf("%v: %v", tag, err)
		}
	}
	// But not if both the tags are present.
	call.MethodTags = tags
	if err := authorize(authorizer, call); err == nil {
		t.Errorf("Expected error since there are multiple tags on the method")
	}
}

func methodTags(name string) []*vdl.Value {
	server := internal.MyObjectServer(nil)
	for _, iface := range server.Describe__() {
		for _, method := range iface.Methods {
			if method.Name == name {
				return method.Tags
			}
		}
	}
	return nil
}

func newPrincipal(t *testing.T) security.Principal {
	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		t.Fatal(err)
	}
	p, err := security.CreatePrincipal(
		security.NewInMemoryECDSASigner(key),
		nil,
		&trustAllRoots{dump: make(map[security.BlessingPattern][]security.PublicKey)},
	)
	if err != nil {
		t.Fatal(err)
	}
	return p
}

type trustAllRoots struct {
	dump map[security.BlessingPattern][]security.PublicKey
}

func (r *trustAllRoots) Add(root []byte, pattern security.BlessingPattern) error {
	key, err := security.UnmarshalPublicKey(root)
	if err != nil {
		return err
	}
	r.dump[pattern] = append(r.dump[pattern], key)
	return nil
}
func (r *trustAllRoots) Recognized(root []byte, blessing string) error {
	return nil
}
func (r *trustAllRoots) Dump() map[security.BlessingPattern][]security.PublicKey {
	return r.dump
}
func (r *trustAllRoots) DebugString() string {
	return fmt.Sprintf("%v", r)
}
