diff --git a/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs b/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs index 1c14c5bb5b4..f77e9c6573d 100644 --- a/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs +++ b/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs @@ -57,9 +57,9 @@ namespace Grpc.Auth /// The interceptor. public static AsyncAuthInterceptor FromCredential(ITokenAccess credential) { - return new AsyncAuthInterceptor(async (authUri, metadata) => + return new AsyncAuthInterceptor(async (context, metadata) => { - var accessToken = await credential.GetAccessTokenForRequestAsync(authUri, CancellationToken.None).ConfigureAwait(false); + var accessToken = await credential.GetAccessTokenForRequestAsync(context.ServiceUrl, CancellationToken.None).ConfigureAwait(false); metadata.Add(CreateBearerTokenHeader(accessToken)); }); } @@ -72,7 +72,7 @@ namespace Grpc.Auth public static AsyncAuthInterceptor FromAccessToken(string accessToken) { Preconditions.CheckNotNull(accessToken); - return new AsyncAuthInterceptor(async (authUri, metadata) => + return new AsyncAuthInterceptor(async (context, metadata) => { metadata.Add(CreateBearerTokenHeader(accessToken)); }); diff --git a/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs b/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs new file mode 100644 index 00000000000..5c9ab048120 --- /dev/null +++ b/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs @@ -0,0 +1,84 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core +{ + /// + /// Asynchronous authentication interceptor for . + /// + /// The interceptor context. + /// Metadata to populate with entries that will be added to outgoing call's headers. + /// + public delegate Task AsyncAuthInterceptor(AuthInterceptorContext context, Metadata metadata); + + /// + /// Context for an RPC being intercepted by . + /// + public class AuthInterceptorContext + { + readonly string serviceUrl; + readonly string methodName; + + /// + /// Initializes a new instance of AuthInterceptorContext. + /// + public AuthInterceptorContext(string serviceUrl, string methodName) + { + this.serviceUrl = Preconditions.CheckNotNull(serviceUrl); + this.methodName = Preconditions.CheckNotNull(methodName); + } + + /// + /// The fully qualified service URL for the RPC being called. + /// + public string ServiceUrl + { + get { return serviceUrl; } + } + + /// + /// The method name of the RPC being called. + /// + public string MethodName + { + get { return methodName; } + } + } +} diff --git a/src/csharp/Grpc.Core/CallCredentials.cs b/src/csharp/Grpc.Core/CallCredentials.cs index 5ea179dfea1..a71c8904fe7 100644 --- a/src/csharp/Grpc.Core/CallCredentials.cs +++ b/src/csharp/Grpc.Core/CallCredentials.cs @@ -40,14 +40,6 @@ using Grpc.Core.Utils; namespace Grpc.Core { - /// - /// Asynchronous authentication interceptor for . - /// - /// URL of a service to which current remote call needs to authenticate - /// Metadata to populate with entries that will be added to outgoing call's headers. - /// - public delegate Task AsyncAuthInterceptor(string authUri, Metadata metadata); - /// /// Client-side call credentials. Provide authorization with per-call granularity. /// diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 56a06f4a9bb..5b3da7c6c99 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -46,6 +46,7 @@ + @@ -148,8 +149,8 @@ - - - \ No newline at end of file + + + diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs index 4c086048d26..8bb646d303c 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs @@ -38,7 +38,7 @@ using Grpc.Core.Utils; namespace Grpc.Core.Internal { - internal delegate void NativeMetadataInterceptor(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy); + internal delegate void NativeMetadataInterceptor(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy); internal class NativeMetadataCredentialsPlugin { @@ -71,7 +71,7 @@ namespace Grpc.Core.Internal get { return credentials; } } - private void NativeMetadataInterceptorHandler(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy) + private void NativeMetadataInterceptorHandler(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy) { if (isDestroy) { @@ -81,8 +81,9 @@ namespace Grpc.Core.Internal try { - string serviceUrl = Marshal.PtrToStringAnsi(serviceUrlPtr); - StartGetMetadata(serviceUrl, callbackPtr, userDataPtr); + var context = new AuthInterceptorContext(Marshal.PtrToStringAnsi(serviceUrlPtr), + Marshal.PtrToStringAnsi(methodNamePtr)); + StartGetMetadata(context, callbackPtr, userDataPtr); } catch (Exception e) { @@ -91,12 +92,12 @@ namespace Grpc.Core.Internal } } - private async void StartGetMetadata(string serviceUrl, IntPtr callbackPtr, IntPtr userDataPtr) + private async void StartGetMetadata(AuthInterceptorContext context, IntPtr callbackPtr, IntPtr userDataPtr) { try { var metadata = new Metadata(); - await interceptor(serviceUrl, metadata).ConfigureAwait(false); + await interceptor(context, metadata).ConfigureAwait(false); using (var metadataArray = MetadataArraySafeHandle.Create(metadata)) { diff --git a/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs index 3d56678b990..35230f48c17 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs @@ -67,7 +67,7 @@ namespace Grpc.IntegrationTesting new ChannelOption(ChannelOptions.SslTargetNameOverride, TestCredentials.DefaultHostOverride) }; - var asyncAuthInterceptor = new AsyncAuthInterceptor(async (authUri, metadata) => + var asyncAuthInterceptor = new AsyncAuthInterceptor(async (context, metadata) => { await Task.Delay(100); // make sure the operation is asynchronous. metadata.Add("authorization", "SECRET_TOKEN"); diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index b8705c49d32..0ef9be33a6c 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -927,7 +927,8 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin( } typedef void(GPR_CALLTYPE *grpcsharp_metadata_interceptor_func)( - void *state, const char *service_url, grpc_credentials_plugin_metadata_cb cb, + void *state, const char *service_url, const char *method_name, + grpc_credentials_plugin_metadata_cb cb, void *user_data, gpr_int32 is_destroy); static void grpcsharp_get_metadata_handler( @@ -935,13 +936,13 @@ static void grpcsharp_get_metadata_handler( grpc_credentials_plugin_metadata_cb cb, void *user_data) { grpcsharp_metadata_interceptor_func interceptor = (grpcsharp_metadata_interceptor_func)(gpr_intptr)state; - interceptor(state, context.service_url, cb, user_data, 0); + interceptor(state, context.service_url, context.method_name, cb, user_data, 0); } static void grpcsharp_metadata_credentials_destroy_handler(void *state) { grpcsharp_metadata_interceptor_func interceptor = (grpcsharp_metadata_interceptor_func)(gpr_intptr)state; - interceptor(state, NULL, NULL, NULL, 1); + interceptor(state, NULL, NULL, NULL, NULL, 1); } GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_metadata_credentials_create_from_plugin( diff --git a/src/python/grpcio/tests/_loader.py b/src/python/grpcio/tests/_loader.py index 14b22b08460..6992029b5e8 100644 --- a/src/python/grpcio/tests/_loader.py +++ b/src/python/grpcio/tests/_loader.py @@ -34,14 +34,6 @@ import unittest import coverage -# Some global spooky-action-at-a-distance hackery to get around -# system-installation issues where the google namespace is defaulted to the -# system even though the egg is higher priority on sys.path. This inverts the -# path priority on package module paths thus giving any installed eggs higher -# priority and having little effect otherwise. -import google -google.__path__.reverse() - TEST_MODULE_REGEX = r'^.*_test$' diff --git a/src/python/grpcio/tox.ini b/src/python/grpcio/tox.ini index 0e3cae7861b..bfb1ca0cfad 100644 --- a/src/python/grpcio/tox.ini +++ b/src/python/grpcio/tox.ini @@ -15,8 +15,5 @@ commands = coverage html --include='grpc/*' --omit='grpc/framework/alpha/*','grpc/early_adopter/*','grpc/framework/base/*','grpc/framework/face/*','grpc/_adapter/fore.py','grpc/_adapter/rear.py' coverage report --include='grpc/*' --omit='grpc/framework/alpha/*','grpc/early_adopter/*','grpc/framework/base/*','grpc/framework/face/*','grpc/_adapter/fore.py','grpc/_adapter/rear.py' deps = - cython - coverage - oauth2client - protobuf + -rrequirements.txt passenv = * diff --git a/tools/jenkins/grpc_interop_python/Dockerfile b/tools/jenkins/grpc_interop_python/Dockerfile index 5850f5f321e..6034cbf9550 100644 --- a/tools/jenkins/grpc_interop_python/Dockerfile +++ b/tools/jenkins/grpc_interop_python/Dockerfile @@ -75,6 +75,7 @@ RUN ln -s /usr/bin/ccache /usr/local/bin/clang++ # Install Python requisites RUN /bin/bash -l -c "pip install --upgrade pip" RUN /bin/bash -l -c "pip install virtualenv" +RUN /bin/bash -l -c "pip install tox" # Define the default command. CMD ["bash"] diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh index 7db14ce9d12..57080ce9348 100755 --- a/tools/run_tests/build_python.sh +++ b/tools/run_tests/build_python.sh @@ -45,3 +45,5 @@ export GRPC_PYTHON_ENABLE_CYTHON_TRACING=1 cd $GRPCIO tox --notest + +$GRPCIO/.tox/py27/bin/python $GRPCIO/setup.py build diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 36b2dc06962..37b631bd0da 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -266,7 +266,7 @@ class PythonLanguage: def client_cmd(self, args): return [ - 'python2.7_virtual_environment/bin/python', + 'src/python/grpcio/.tox/py27/bin/python', 'src/python/grpcio/setup.py', 'run_interop', '--client', @@ -278,7 +278,7 @@ class PythonLanguage: def server_cmd(self, args): return [ - 'python2.7_virtual_environment/bin/python', + 'src/python/grpcio/.tox/py27/bin/python', 'src/python/grpcio/setup.py', 'run_interop', '--server',