syncbase: Get the login to work by adding a testLogin option

This change adds a testLogin option to the set of option we can pass
to Init in the high-level Syncbase API. When set to true the testLogin
will cause the call to login() to generate a 'root:o:app:user'
blessing which will set the app name to 'app' and the user name to
'user'. This also fixes the tests from internal/BlessingsTest.

Note: the author of the Swift code is Aaron Zinman <aaron@azinman.com>.

MultiPart: 1/3
Change-Id: I93552e7ed4737f16a052629e366f821aa03f3b38
diff --git a/services/syncbase/bridge/cgo/impl.go b/services/syncbase/bridge/cgo/impl.go
index 8c7d5d6..2d2faf5 100644
--- a/services/syncbase/bridge/cgo/impl.go
+++ b/services/syncbase/bridge/cgo/impl.go
@@ -47,6 +47,7 @@
 	_ "v.io/x/ref/runtime/factories/roaming"
 	"v.io/x/ref/services/syncbase/bridge"
 	"v.io/x/ref/services/syncbase/syncbaselib"
+	"v.io/x/ref/test/testutil"
 )
 
 /*
@@ -78,10 +79,14 @@
 	// itself does VOM encoding and decoding, and the client deals in byte
 	// arrays.
 	clientUnderstandsVOM bool
+	// testLogin indicates if the test login mode is used. This is triggered
+	// by using an empty identity provider.
+	testLogin bool
 )
 
+// TODO(razvanm): Replace the function arguments with an options struct.
 //export v23_syncbase_Init
-func v23_syncbase_Init(cClientUnderstandVom C.v23_syncbase_Bool, cRootDir C.v23_syncbase_String) {
+func v23_syncbase_Init(cClientUnderstandVom C.v23_syncbase_Bool, cRootDir C.v23_syncbase_String, cTestLogin C.v23_syncbase_Bool) {
 	if b != nil {
 		panic("v23_syncbase_Init called again before a v23_syncbase_Shutdown")
 	}
@@ -92,16 +97,18 @@
 	b = &bridge.Bridge{Ctx: ctx, Shutdown: shutdown}
 	rootDir = cRootDir.extract()
 	clientUnderstandsVOM = cClientUnderstandVom.extract()
+	testLogin = cTestLogin.extract()
+	var cErr C.v23_syncbase_VError
+	if isLoggedIn() {
+		v23_syncbase_Serve(&cErr)
+	}
 }
 
 //export v23_syncbase_Serve
 func v23_syncbase_Serve(cErr *C.v23_syncbase_VError) {
-	// TODO(razvanm): Uncomment the check from below after logging is
-	// plumbed through and we have a solution for tests.
-	//
-	//if !isLoggedIn() {
-	//	cErr.init(verror.New(verror.ErrInternal, nil, "not logged in"))
-	//}
+	if !isLoggedIn() {
+		cErr.init(verror.New(verror.ErrInternal, nil, "not logged in"))
+	}
 	srv, disp, cleanup := syncbaselib.Serve(b.Ctx, syncbaselib.Opts{
 		// TODO(sadovsky): Make and pass a subdir of rootDir here, so
 		// that rootDir can also be used for credentials persistence.
@@ -125,6 +132,7 @@
 
 	b.Shutdown()
 	b = nil
+	testLogin = false
 }
 
 ////////////////////////////////////////
@@ -142,11 +150,23 @@
 
 //export v23_syncbase_Login
 func v23_syncbase_Login(cOAuthProvider C.v23_syncbase_String, cOAuthToken C.v23_syncbase_String, cErr *C.v23_syncbase_VError) {
-	err := bridge.SeekAndSetBlessings(b.Ctx, cOAuthProvider.extract(), cOAuthToken.extract())
-	if err != nil {
-		cErr.init(err)
+	if isLoggedIn() {
 		return
 	}
+
+	if testLogin {
+		ctx, err := v23.WithPrincipal(b.Ctx, testutil.NewPrincipal("root:o:app:user"))
+		if err != nil {
+			panic(err)
+		}
+		b.Ctx = ctx
+	} else {
+		err := bridge.SeekAndSetBlessings(b.Ctx, cOAuthProvider.extract(), cOAuthToken.extract())
+		if err != nil {
+			cErr.init(err)
+			return
+		}
+	}
 	v23_syncbase_Serve(cErr)
 }
 
diff --git a/services/syncbase/bridge/cgo/jni.go b/services/syncbase/bridge/cgo/jni.go
index 3c8a6e9..dd7fd2a 100644
--- a/services/syncbase/bridge/cgo/jni.go
+++ b/services/syncbase/bridge/cgo/jni.go
@@ -96,9 +96,9 @@
 }
 
 //export Java_io_v_syncbase_internal_Service_Init
-func Java_io_v_syncbase_internal_Service_Init(env *C.JNIEnv, cls C.jclass, initRoot C.jstring) {
+func Java_io_v_syncbase_internal_Service_Init(env *C.JNIEnv, cls C.jclass, initRoot C.jstring, testLogin C.jboolean) {
 	cInitRoot := newVStringFromJava(env, initRoot)
-	v23_syncbase_Init(C.v23_syncbase_Bool(1), cInitRoot)
+	v23_syncbase_Init(C.v23_syncbase_Bool(1), cInitRoot, C.v23_syncbase_Bool(testLogin))
 }
 
 //export Java_io_v_syncbase_internal_Service_Serve