// 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 perms_test

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"syscall"
	"testing"

	"v.io/v23"
	"v.io/v23/security"
	"v.io/v23/security/access"
	"v.io/v23/services/device"
	"v.io/v23/verror"

	"v.io/x/ref/services/device/internal/impl"
	"v.io/x/ref/services/device/internal/impl/utiltest"
	"v.io/x/ref/services/internal/servicetest"
	"v.io/x/ref/test/testutil"
)

// TestDeviceManagerClaim claims a devicemanager and tests AccessList permissions on
// its methods.
func TestDeviceManagerClaim(t *testing.T) {
	ctx, shutdown := utiltest.InitForTest()
	defer shutdown()

	// root blessing provider so that the principals of all the contexts
	// recognize each other.
	idp := testutil.NewIDProvider("root")
	if err := idp.Bless(v23.GetPrincipal(ctx), "ctx"); err != nil {
		t.Fatal(err)
	}

	sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, nil)
	defer deferFn()

	// Set up mock application and binary repositories.
	envelope, cleanup := utiltest.StartMockRepos(t, ctx)
	defer cleanup()

	root, cleanup := servicetest.SetupRootDir(t, "devicemanager")
	defer cleanup()
	if err := impl.SaveCreatorInfo(root); err != nil {
		t.Fatal(err)
	}

	// Create a script wrapping the test target that implements suidhelper.
	helperPath := utiltest.GenerateSuidHelperScript(t, root)

	// Set up the device manager.  Since we won't do device manager updates,
	// don't worry about its application envelope and current link.
	pairingToken := "abcxyz"
	dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link", pairingToken)
	pid := servicetest.ReadPID(t, dmh)
	defer syscall.Kill(pid, syscall.SIGINT)

	*envelope = utiltest.EnvelopeFromShell(sh, nil, utiltest.AppCmd, "google naps", 0, 0, "trapp")

	claimantCtx := utiltest.CtxWithNewPrincipal(t, ctx, idp, "claimant")
	octx, err := v23.WithPrincipal(ctx, testutil.NewPrincipal("other"))
	if err != nil {
		t.Fatal(err)
	}

	// Unclaimed devices cannot do anything but be claimed.
	// TODO(ashankar,caprita): The line below will currently fail with
	// ErrUnclaimedDevice != NotTrusted. NotTrusted can be avoided by
	// passing options.SkipServerEndpointAuthorization{} to the "Install" RPC.
	// Refactor the helper function to make this possible.
	//installAppExpectError(t, octx, impl.ErrUnclaimedDevice.ID)

	// Claim the device with an incorrect pairing token should fail.
	utiltest.ClaimDeviceExpectError(t, claimantCtx, "claimable", "mydevice", "badtoken", impl.ErrInvalidPairingToken.ID)
	// But succeed with a valid pairing token
	utiltest.ClaimDevice(t, claimantCtx, "claimable", "dm", "mydevice", pairingToken)

	// Installation should succeed since claimantRT is now the "owner" of
	// the devicemanager.
	appID := utiltest.InstallApp(t, claimantCtx)

	// octx will not install the app now since it doesn't recognize the
	// device's blessings. The error returned will be ErrNoServers as that
	// is what the IPC stack does when there are no authorized servers.
	utiltest.InstallAppExpectError(t, octx, verror.ErrNoServers.ID)
	// Even if it does recognize the device (by virtue of recognizing the
	// claimant), the device will not allow it to install.
	if err := v23.GetPrincipal(octx).AddToRoots(v23.GetPrincipal(claimantCtx).BlessingStore().Default()); err != nil {
		t.Fatal(err)
	}
	utiltest.InstallAppExpectError(t, octx, verror.ErrNoAccess.ID)

	// Create the local server that the app uses to let us know it's ready.
	pingCh, cleanup := utiltest.SetupPingServer(t, claimantCtx)
	defer cleanup()

	// Start an instance of the app.
	instanceID := utiltest.LaunchApp(t, claimantCtx, appID)

	// Wait until the app pings us that it's ready.
	pingCh.WaitForPingArgs(t)
	utiltest.Resolve(t, ctx, "trapp", 1)
	utiltest.KillApp(t, claimantCtx, appID, instanceID)

	// TODO(gauthamt): Test that AccessLists persist across devicemanager restarts
}

func TestDeviceManagerUpdateAccessList(t *testing.T) {
	ctx, shutdown := utiltest.InitForTest()
	defer shutdown()

	// Identity provider to ensure that all processes recognize each
	// others' blessings.
	idp := testutil.NewIDProvider("root")
	ctx = utiltest.CtxWithNewPrincipal(t, ctx, idp, "self")

	sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, nil)
	defer deferFn()

	// Set up mock application and binary repositories.
	envelope, cleanup := utiltest.StartMockRepos(t, ctx)
	defer cleanup()

	root, cleanup := servicetest.SetupRootDir(t, "devicemanager")
	defer cleanup()
	if err := impl.SaveCreatorInfo(root); err != nil {
		t.Fatal(err)
	}

	selfCtx := ctx
	octx := utiltest.CtxWithNewPrincipal(t, selfCtx, idp, "other")

	// Set up the device manager.  Since we won't do device manager updates,
	// don't worry about its application envelope and current link.
	dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManagerCmd, "dm", root, "unused_helper", "unused_app_repo_name", "unused_curr_link")
	pid := servicetest.ReadPID(t, dmh)
	defer syscall.Kill(pid, syscall.SIGINT)
	defer utiltest.VerifyNoRunningProcesses(t)

	// Create an envelope for an app.
	*envelope = utiltest.EnvelopeFromShell(sh, nil, utiltest.AppCmd, "google naps", 0, 0)

	// On an unclaimed device manager, there will be no AccessLists.
	if _, _, err := device.DeviceClient("claimable").GetPermissions(selfCtx); err == nil {
		t.Fatalf("GetPermissions should have failed but didn't.")
	}

	// Claim the devicemanager as "root/self/mydevice"
	utiltest.ClaimDevice(t, selfCtx, "claimable", "dm", "mydevice", utiltest.NoPairingToken)
	expectedAccessList := make(access.Permissions)
	for _, tag := range access.AllTypicalTags() {
		expectedAccessList[string(tag)] = access.AccessList{In: []security.BlessingPattern{"root/$", "root/self/$", "root/self/mydevice/$"}}
	}
	var b bytes.Buffer
	if err := expectedAccessList.WriteTo(&b); err != nil {
		t.Fatalf("Failed to save AccessList:%v", err)
	}
	// Note, "version" below refers to the Permissions version, not the device
	// manager version.
	md5hash := md5.Sum(b.Bytes())
	expectedVersion := hex.EncodeToString(md5hash[:])
	deviceStub := device.DeviceClient("dm/device")
	perms, version, err := deviceStub.GetPermissions(selfCtx)
	if err != nil {
		t.Fatal(err)
	}
	if version != expectedVersion {
		t.Fatalf("getAccessList expected:%v(%v), got:%v(%v)", expectedAccessList, expectedVersion, perms, version)
	}
	// Install from octx should fail, since it does not match the AccessList.
	utiltest.InstallAppExpectError(t, octx, verror.ErrNoAccess.ID)

	newAccessList := make(access.Permissions)
	for _, tag := range access.AllTypicalTags() {
		newAccessList.Add("root/other", string(tag))
	}
	if err := deviceStub.SetPermissions(selfCtx, newAccessList, "invalid"); err == nil {
		t.Fatalf("SetPermissions should have failed with invalid version")
	}
	if err := deviceStub.SetPermissions(selfCtx, newAccessList, version); err != nil {
		t.Fatal(err)
	}
	// Install should now fail with selfCtx, which no longer matches the
	// AccessLists but succeed with octx, which does.
	utiltest.InstallAppExpectError(t, selfCtx, verror.ErrNoAccess.ID)
	utiltest.InstallApp(t, octx)
}
