blob: 68afdec7aae386a602acb5638e4493ac37f1fb8d [file] [log] [blame]
// 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 rpc
import (
"testing"
"v.io/v23"
"v.io/v23/options"
"v.io/v23/security"
"v.io/x/ref/runtime/internal/naming"
"v.io/x/ref/test/testutil"
)
func TestServerAuthorizer(t *testing.T) {
var (
pclient = testutil.NewPrincipal()
pserver = testutil.NewPrincipal()
pother = testutil.NewPrincipal()
ali, _ = pserver.BlessSelf("ali")
bob, _ = pserver.BlessSelf("bob")
che, _ = pserver.BlessSelf("che")
otherAli, _ = pother.BlessSelf("ali")
zero = security.Blessings{}
ctx, shutdown = initForTest()
U = func(blessings ...security.Blessings) security.Blessings {
u, err := security.UnionOfBlessings(blessings...)
if err != nil {
t.Fatal(err)
}
return u
}
)
defer shutdown()
ctx, _ = v23.WithPrincipal(ctx, pclient)
// Make client recognize ali, bob and otherAli blessings
for _, b := range []security.Blessings{ali, bob, otherAli} {
if err := pclient.AddToRoots(b); err != nil {
t.Fatal(err)
}
}
// All tests are run as if pclient is the client end and pserver is remote end.
tests := []struct {
serverBlessingNames []string
auth security.Authorizer
authorizedServers []security.Blessings
unauthorizedServers []security.Blessings
}{
{
// No blessings in the endpoint means that all servers are authorized.
nil,
newServerAuthorizer(""),
[]security.Blessings{ali, otherAli, bob, che},
[]security.Blessings{zero},
},
{
// Endpoint sets the expectations for "ali" and "bob".
[]string{"ali", "bob"},
newServerAuthorizer(""),
[]security.Blessings{ali, otherAli, bob, U(ali, che), U(bob, che)},
[]security.Blessings{che},
},
{
// Still only ali, otherAli and bob are authorized (che is not
// authorized since it is not recognized by the client)
[]string{"ali", "bob", "che"},
newServerAuthorizer(""),
[]security.Blessings{ali, otherAli, bob, U(ali, che), U(bob, che)},
[]security.Blessings{che},
},
{
// Only ali and otherAli are authorized (since there is an
// allowed-servers policy that does not allow "bob")
[]string{"ali", "bob", "che"},
newServerAuthorizer("", options.AllowedServersPolicy{"ali", "bob"}, options.AllowedServersPolicy{"ali"}),
[]security.Blessings{ali, otherAli, U(ali, che), U(ali, bob)},
[]security.Blessings{bob, che},
},
{
// Multiple AllowedServersPolicy are treated as an AND (and individual ones are "ORs")
nil,
newServerAuthorizer("", options.AllowedServersPolicy{"ali", "che"}, options.AllowedServersPolicy{"bob", "che"}),
[]security.Blessings{U(ali, bob)},
[]security.Blessings{ali, bob, che, U(ali, che), U(bob, che)},
},
{
// Only otherAli is authorized (since only pother's public key is
// authorized)
[]string{"ali"},
newServerAuthorizer("", options.ServerPublicKey{pother.PublicKey()}),
[]security.Blessings{otherAli},
[]security.Blessings{ali, bob, che},
},
{
// Blessings in endpoint can be ignored.
[]string{"ali"},
newServerAuthorizer("", options.SkipServerEndpointAuthorization{}),
[]security.Blessings{ali, bob, che, otherAli},
nil,
},
{
// Pattern specified is respected
nil,
newServerAuthorizer("bob"),
[]security.Blessings{bob, U(ali, bob)},
[]security.Blessings{ali, otherAli, che},
},
{
// And concatenated with any existing AllowedServersPolicy
[]string{"ali", "bob", "che"},
newServerAuthorizer("bob", options.AllowedServersPolicy{"bob", "che"}),
[]security.Blessings{bob, U(ali, bob), U(ali, bob, che)},
[]security.Blessings{ali, che},
},
{
// And if the intersection of AllowedServersPolicy and the pattern be empty, then so be it!
[]string{"ali", "bob", "che"},
newServerAuthorizer("bob", options.AllowedServersPolicy{"ali", "che"}),
[]security.Blessings{U(ali, bob), U(ali, bob, che)},
[]security.Blessings{ali, otherAli, bob, che, U(ali, che)},
},
}
for _, test := range tests {
for _, s := range test.authorizedServers {
if err := test.auth.Authorize(ctx, &mockCall{
p: pclient,
r: s,
rep: &naming.Endpoint{Blessings: test.serverBlessingNames},
}); err != nil {
t.Errorf("serverAuthorizer: %#v failed to authorize server: %v", test.auth, s)
}
}
for _, s := range test.unauthorizedServers {
if err := test.auth.Authorize(ctx, &mockCall{
p: pclient,
r: s,
rep: &naming.Endpoint{Blessings: test.serverBlessingNames},
}); err == nil {
t.Errorf("serverAuthorizer: %#v authorized server: %v", test.auth, s)
}
}
}
}