veyron/services/mgmt/device/impl: Fix Claim test and Claim process

With this changes, all the device manager tests use their own temporary
credentials, even when VEYRON_CREDENTIALS is set.

The change also updates TestDeviceManagerClaim such that the
credentials of the unclaimed device manager are independent of the
credentials of the claimant. Without this, the test was rather
meaningless since the claimant already had access to the device.

Since there is no expectation that the unclaimed device's principal and the
claimant will have a common trusted root, the claiming process must also
include trusting the claimant's roots.

Change-Id: If0eff62ec388273d28bac84aedd96e1b90a5aacd
diff --git a/services/mgmt/device/impl/device_service.go b/services/mgmt/device/impl/device_service.go
index 7f72437..332699d 100644
--- a/services/mgmt/device/impl/device_service.go
+++ b/services/mgmt/device/impl/device_service.go
@@ -94,13 +94,8 @@
 	uat      BlessingSystemAssociationStore
 }
 
-func (i *deviceService) Claim(call ipc.ServerContext) error {
-	// Get the blessing to be used by the claimant.
-	blessings := call.Blessings()
-	if blessings == nil {
-		return verror2.Make(ErrInvalidBlessing, call)
-	}
-	return i.disp.claimDeviceManager(call.LocalPrincipal(), blessings.ForContext(call), blessings)
+func (i *deviceService) Claim(ctx ipc.ServerContext) error {
+	return i.disp.claimDeviceManager(ctx)
 }
 
 func (*deviceService) Describe(ipc.ServerContext) (device.Description, error) {
diff --git a/services/mgmt/device/impl/dispatcher.go b/services/mgmt/device/impl/dispatcher.go
index 237a0ca..1e5bcbb 100644
--- a/services/mgmt/device/impl/dispatcher.go
+++ b/services/mgmt/device/impl/dispatcher.go
@@ -158,15 +158,26 @@
 	return
 }
 
-func (d *dispatcher) claimDeviceManager(principal security.Principal, names []string, proof security.Blessings) error {
-	// TODO(gauthamt): Should we start trusting these identity providers?
+func (d *dispatcher) claimDeviceManager(ctx ipc.ServerContext) error {
 	// TODO(rjkroege): Scrub the state tree of installation and instance ACL files.
+
+	// Get the blessings to be used by the claimant.
+	blessings := ctx.Blessings()
+	if blessings == nil {
+		return verror2.Make(ErrInvalidBlessing, ctx)
+	}
+	principal := ctx.LocalPrincipal()
+	if err := principal.AddToRoots(blessings); err != nil {
+		vlog.Errorf("principal.AddToRoots(%s) failed: %v", blessings, err)
+		return verror2.Make(ErrInvalidBlessing, ctx)
+	}
+	names := blessings.ForContext(ctx)
 	if len(names) == 0 {
-		vlog.Errorf("No names for claimer(%v) are trusted", proof)
+		vlog.Errorf("No names for claimer(%v) are trusted", blessings)
 		return verror2.Make(ErrOperationFailed, nil)
 	}
-	principal.BlessingStore().Set(proof, security.AllPrincipals)
-	principal.BlessingStore().SetDefault(proof)
+	principal.BlessingStore().Set(blessings, security.AllPrincipals)
+	principal.BlessingStore().SetDefault(blessings)
 	// Create ACLs to transfer devicemanager permissions to the provided identity.
 	acl := make(access.TaggedACLMap)
 	for _, n := range names {
@@ -475,4 +486,7 @@
 // access.
 type allowEveryone struct{}
 
-func (allowEveryone) Authorize(security.Context) error { return nil }
+func (allowEveryone) Authorize(ctx security.Context) error {
+	vlog.Infof("Device manager is unclaimed. Allow %q.%s() from %q.", ctx.Suffix(), ctx.Method(), ctx.RemoteBlessings())
+	return nil
+}
diff --git a/services/mgmt/device/impl/impl_test.go b/services/mgmt/device/impl/impl_test.go
index 0bd4d5a..6ba121e 100644
--- a/services/mgmt/device/impl/impl_test.go
+++ b/services/mgmt/device/impl/impl_test.go
@@ -31,6 +31,7 @@
 	"veyron.io/veyron/veyron2/context"
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/naming"
+	"veyron.io/veyron/veyron2/options"
 	"veyron.io/veyron/veyron2/rt"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/services/mgmt/application"
@@ -75,14 +76,14 @@
 	if modules.IsModulesProcess() {
 		return
 	}
-	initRT()
+	initRT(options.RuntimePrincipal{tsecurity.NewPrincipal("test-principal")})
 }
 
 var globalRT veyron2.Runtime
 
-func initRT() {
+func initRT(opts ...veyron2.ROpt) {
 	var err error
-	if globalRT, err = rt.New(); err != nil {
+	if globalRT, err = rt.New(opts...); err != nil {
 		panic(err)
 	}
 
@@ -494,7 +495,7 @@
 func setupPingServer(t *testing.T) (<-chan string, func()) {
 	server, _ := newServer()
 	pingCh := make(chan string, 1)
-	if err := server.Serve("pingserver", pingServer(pingCh), nil); err != nil {
+	if err := server.Serve("pingserver", pingServer(pingCh), &openAuthorizer{}); err != nil {
 		t.Fatalf("Serve(%q, <dispatcher>) failed: %v", "pingserver", err)
 	}
 	return pingCh, func() {
@@ -726,8 +727,8 @@
 	dms.ExpectEOF()
 }
 
-func newRuntime(t *testing.T) veyron2.Runtime {
-	runtime, err := rt.New()
+func newRuntime(t *testing.T, opts ...veyron2.ROpt) veyron2.Runtime {
+	runtime, err := rt.New(opts...)
 	if err != nil {
 		t.Fatalf("rt.New() failed: %v", err)
 	}
@@ -807,9 +808,10 @@
 
 	*envelope = envelopeFromShell(sh, nil, appCmd, "google naps", "trapp")
 
-	deviceStub := device.DeviceClient("dm//device")
-	selfRT := globalRT
-	otherRT := newRuntime(t)
+	deviceStub := device.DeviceClient("dm/device")
+	claimantRT := newRuntime(t, options.RuntimePrincipal{tsecurity.NewPrincipal("claimant")})
+	defer claimantRT.Cleanup()
+	otherRT := newRuntime(t, options.RuntimePrincipal{tsecurity.NewPrincipal("other")})
 	defer otherRT.Cleanup()
 
 	octx := otherRT.NewContext()
@@ -817,16 +819,16 @@
 	// Devicemanager should have open ACLs before we claim it and so an
 	// Install from otherRT should succeed.
 	if err := tryInstall(octx); err != nil {
-		t.Fatalf("Failed to install: %s", err)
+		t.Errorf("Failed to install: %s", err)
 	}
-	// Claim the devicemanager with selfRT as <defaultblessing>/mydevice
-	if err := deviceStub.Claim(selfRT.NewContext(), &granter{p: selfRT.Principal(), extension: "mydevice"}); err != nil {
+	// Claim the devicemanager with claimantRT as <defaultblessing>/mydevice
+	if err := deviceStub.Claim(claimantRT.NewContext(), &granter{p: claimantRT.Principal(), extension: "mydevice"}); err != nil {
 		t.Fatal(err)
 	}
 
-	// Installation should succeed since globalRT (a.k.a. selfRT) is now the
-	// "owner" of the devicemanager.
-	appID := installApp(t)
+	// Installation should succeed since claimantRT is now the "owner" of
+	// the devicemanager.
+	appID := installApp(t, claimantRT)
 
 	// otherRT should be unable to install though, since the ACLs have
 	// changed now.
@@ -839,7 +841,7 @@
 	defer cleanup()
 
 	// Start an instance of the app.
-	instanceID := startApp(t, appID)
+	instanceID := startApp(t, appID, claimantRT)
 
 	// Wait until the app pings us that it's ready.
 	select {
@@ -848,7 +850,7 @@
 		t.Fatalf("failed to get ping")
 	}
 	resolve(t, "trapp", 1)
-	suspendApp(t, appID, instanceID)
+	suspendApp(t, appID, instanceID, claimantRT)
 
 	// TODO(gauthamt): Test that ACLs persist across devicemanager restarts
 }
diff --git a/services/mgmt/device/impl/mock_repo_test.go b/services/mgmt/device/impl/mock_repo_test.go
index 0c34ddc..58438b0 100644
--- a/services/mgmt/device/impl/mock_repo_test.go
+++ b/services/mgmt/device/impl/mock_repo_test.go
@@ -9,6 +9,7 @@
 	"testing"
 
 	"veyron.io/veyron/veyron2/ipc"
+	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/services/mgmt/application"
 	"veyron.io/veyron/veyron2/services/mgmt/binary"
 	"veyron.io/veyron/veyron2/services/mgmt/repository"
@@ -36,7 +37,7 @@
 	server, _ := newServer()
 	invoker := new(arInvoker)
 	name := mockApplicationRepoName
-	if err := server.Serve(name, repository.ApplicationServer(invoker), nil); err != nil {
+	if err := server.Serve(name, repository.ApplicationServer(invoker), &openAuthorizer{}); err != nil {
 		vlog.Fatalf("Serve(%v) failed: %v", name, err)
 	}
 	return &invoker.envelope, func() {
@@ -46,6 +47,10 @@
 	}
 }
 
+type openAuthorizer struct{}
+
+func (openAuthorizer) Authorize(security.Context) error { return nil }
+
 // arInvoker holds the state of an application repository invocation mock.  The
 // mock returns the value of the wrapped envelope, which can be subsequently be
 // changed at any time.  Client is responsible for synchronization if desired.
@@ -68,7 +73,7 @@
 func startBinaryRepository() func() {
 	server, _ := newServer()
 	name := mockBinaryRepoName
-	if err := server.Serve(name, repository.BinaryServer(new(brInvoker)), nil); err != nil {
+	if err := server.Serve(name, repository.BinaryServer(new(brInvoker)), &openAuthorizer{}); err != nil {
 		vlog.Fatalf("Serve(%q) failed: %v", name, err)
 	}
 	return func() {