jni: Support specifying ServerAuthorizers from Java.
MultiPart: 1/2
Change-Id: I8a817f10da1025b2d41388a66e1acb7d6f87a426
diff --git a/impl/google/rpc/jni.go b/impl/google/rpc/jni.go
index eec488e..243cc28 100644
--- a/impl/google/rpc/jni.go
+++ b/impl/google/rpc/jni.go
@@ -13,7 +13,6 @@
"v.io/v23/context"
"v.io/v23/options"
"v.io/v23/rpc"
- "v.io/v23/security"
"v.io/v23/vdl"
"v.io/v23/vom"
@@ -242,21 +241,15 @@
return args, nil
}
-func doStartCall(ctx *context.T, cancel func(), name, method string, skipServerAuth bool, goPtr C.jlong, args []interface{}) (jutil.Object, error) {
- var opts []rpc.CallOpt
- if skipServerAuth {
- opts = append(opts,
- options.NameResolutionAuthorizer{security.AllowEveryone()},
- options.ServerAuthorizer{security.AllowEveryone()})
- }
+func doStartCall(context *context.T, cancel func(), name, method string, opts []rpc.CallOpt, goPtr C.jlong, args []interface{}) (jutil.Object, error) {
// Invoke StartCall
- call, err := (*(*rpc.Client)(jutil.NativePtr(goPtr))).StartCall(ctx, name, method, args, opts...)
+ call, err := (*(*rpc.Client)(jutil.NativePtr(goPtr))).StartCall(context, name, method, args, opts...)
if err != nil {
return jutil.NullObject, err
}
env, freeFunc := jutil.GetEnv()
defer freeFunc()
- jContext, err := jcontext.JavaContext(env, ctx, cancel)
+ jContext, err := jcontext.JavaContext(env, context, cancel)
if err != nil {
return jutil.NullObject, err
}
@@ -270,7 +263,7 @@
}
//export Java_io_v_impl_google_rpc_ClientImpl_nativeStartCall
-func Java_io_v_impl_google_rpc_ClientImpl_nativeStartCall(jenv *C.JNIEnv, jClient C.jobject, goPtr C.jlong, jContext C.jobject, jName C.jstring, jMethod C.jstring, jVomArgs C.jobjectArray, jSkipServerAuth C.jboolean, jCallbackObj C.jobject) {
+func Java_io_v_impl_google_rpc_ClientImpl_nativeStartCall(jenv *C.JNIEnv, jClient C.jobject, goPtr C.jlong, jContext C.jobject, jName C.jstring, jMethod C.jstring, jVomArgs C.jobjectArray, jNameResolutionAuthorizerObj, jServerAuthorizerObj C.jobject, jCallbackObj C.jobject) {
env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
name := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
method := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jMethod))))
@@ -285,9 +278,27 @@
jutil.CallbackOnFailure(env, jCallback, err)
return
}
- skipServerAuth := jSkipServerAuth == C.JNI_TRUE
+ var opts []rpc.CallOpt
+ jNameResolutionAuthorizer := jutil.Object(uintptr(unsafe.Pointer(jNameResolutionAuthorizerObj)))
+ if !jNameResolutionAuthorizer.IsNull() {
+ auth, err := jsecurity.GoAuthorizer(env, jNameResolutionAuthorizer)
+ if err != nil {
+ jutil.CallbackOnFailure(env, jCallback, err)
+ return
+ }
+ opts = append(opts, options.NameResolutionAuthorizer{auth})
+ }
+ jServerAuthorizer := jutil.Object(uintptr(unsafe.Pointer(jServerAuthorizerObj)))
+ if !jServerAuthorizer.IsNull() {
+ auth, err := jsecurity.GoAuthorizer(env, jServerAuthorizer)
+ if err != nil {
+ jutil.CallbackOnFailure(env, jCallback, err)
+ return
+ }
+ opts = append(opts, options.ServerAuthorizer{auth})
+ }
jutil.DoAsyncCall(env, jCallback, func() (jutil.Object, error) {
- return doStartCall(ctx, cancel, name, method, skipServerAuth, goPtr, args)
+ return doStartCall(ctx, cancel, name, method, opts, goPtr, args)
})
}
diff --git a/v23/security/authorizer.go b/v23/security/authorizer.go
index eb21f2a..15b1b3e 100644
--- a/v23/security/authorizer.go
+++ b/v23/security/authorizer.go
@@ -23,6 +23,13 @@
if jAuth.IsNull() {
return nil, nil
}
+ if jutil.IsInstanceOf(env, jAuth, jPermissionsAuthorizerClass) {
+ ptr, err := jutil.JLongField(env, jAuth, "nativePtr")
+ if err != nil {
+ return nil, err
+ }
+ return *(*security.Authorizer)(jutil.NativePtr(ptr)), nil
+ }
// Reference Java dispatcher; it will be de-referenced when the go
// dispatcher created below is garbage-collected (through the finalizer
// callback we setup below).
diff --git a/v23/security/jni.go b/v23/security/jni.go
index 9bfbf45..b6868e6 100644
--- a/v23/security/jni.go
+++ b/v23/security/jni.go
@@ -63,6 +63,8 @@
jDischargeClass jutil.Class
// Global reference for io.v.v23.security.DischargeImpetus class.
jDischargeImpetusClass jutil.Class
+ // Global reference for io.v.v23.security.access.PermissionsAuthorizer class.
+ jPermissionsAuthorizerClass jutil.Class
// Global reference for io.v.v23.uniqueid.Id class.
jIdClass jutil.Class
// Global reference for java.lang.Object class.
@@ -130,6 +132,10 @@
if err != nil {
return err
}
+ jPermissionsAuthorizerClass, err = jutil.JFindClass(env, "io/v/v23/security/access/PermissionsAuthorizer")
+ if err != nil {
+ return err
+ }
jIdClass, err = jutil.JFindClass(env, "io/v/v23/uniqueid/Id")
if err != nil {
return err
@@ -1042,3 +1048,33 @@
jutil.JThrowV(env, err)
}
}
+
+//export Java_io_v_v23_security_VSecurity_nativeCreateAuthorizer
+func Java_io_v_v23_security_VSecurity_nativeCreateAuthorizer(jenv *C.JNIEnv, jVSecurityClass C.jclass, kind C.jint, jKey C.jobject) C.jobject {
+ env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
+ var auth security.Authorizer
+ switch kind {
+ case 0:
+ auth = security.AllowEveryone()
+ case 1:
+ auth = security.EndpointAuthorizer()
+ case 2:
+ auth = security.DefaultAuthorizer()
+ case 3:
+ key, err := GoPublicKey(env, jutil.Object(uintptr(unsafe.Pointer(jKey))))
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ auth = security.PublicKeyAuthorizer(key)
+ default:
+ return nil
+ }
+ jutil.GoRef(&auth) // Un-refed when the Java PermissionsAuthorizer is finalized
+ jAuthorizer, err := jutil.NewObject(env, jutil.Class(uintptr(unsafe.Pointer(jPermissionsAuthorizerClass))), []jutil.Sign{jutil.LongSign}, int64(jutil.PtrValue(&auth)))
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ return C.jobject(unsafe.Pointer(jAuthorizer))
+}