blob: f95af5008f1c30c75729ce55bef7b4e6c31eb530 [file] [log] [blame]
Jan Tattermusch5bd75d72015-09-08 10:55:20 -07001#region Copyright notice and license
2
Jan Tattermuschacb842c2016-03-25 16:54:14 -07003// Copyright 2015-2016, Google Inc.
Jan Tattermusch5bd75d72015-09-08 10:55:20 -07004// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32#endregion
33
34using System;
35using System.Collections.Generic;
36using System.IO;
37using System.Linq;
38using System.Threading;
39using System.Threading.Tasks;
40using Grpc.Core;
41using Grpc.Core.Utils;
42using Grpc.Testing;
Jan Tattermusch3ac49002015-12-09 16:48:16 -080043using Moq;
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070044using NUnit.Framework;
45
46namespace Grpc.IntegrationTesting
47{
48 public class MetadataCredentialsTest
49 {
50 const string Host = "localhost";
51 Server server;
52 Channel channel;
Jan Tattermuschd8f7c8a2016-03-21 19:02:58 -070053 TestService.TestServiceClient client;
Jan Tattermusch3ac49002015-12-09 16:48:16 -080054 List<ChannelOption> options;
Jan Tattermuschd8f7c8a2016-03-21 19:02:58 -070055 Mock<TestService.TestServiceBase> serviceMock;
Jan Tattermusch3ac49002015-12-09 16:48:16 -080056 AsyncAuthInterceptor asyncAuthInterceptor;
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070057
Jan Tattermusch3ac49002015-12-09 16:48:16 -080058 [SetUp]
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070059 public void Init()
60 {
Jan Tattermuschd8f7c8a2016-03-21 19:02:58 -070061 serviceMock = new Mock<TestService.TestServiceBase>();
Jan Tattermusch3ac49002015-12-09 16:48:16 -080062 serviceMock.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), It.IsAny<ServerCallContext>()))
63 .Returns(new Func<SimpleRequest, ServerCallContext, Task<SimpleResponse>>(UnaryCallHandler));
64
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070065 server = new Server
66 {
Jan Tattermusch3ac49002015-12-09 16:48:16 -080067 Services = { TestService.BindService(serviceMock.Object) },
68 Ports = { { Host, ServerPort.PickUnused, TestCredentials.CreateSslServerCredentials() } }
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070069 };
70 server.Start();
71
Jan Tattermusch3ac49002015-12-09 16:48:16 -080072 options = new List<ChannelOption>
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070073 {
74 new ChannelOption(ChannelOptions.SslTargetNameOverride, TestCredentials.DefaultHostOverride)
75 };
76
Jan Tattermusch3ac49002015-12-09 16:48:16 -080077 asyncAuthInterceptor = new AsyncAuthInterceptor(async (context, metadata) =>
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070078 {
Jan Tattermusch3ac49002015-12-09 16:48:16 -080079 await Task.Delay(100).ConfigureAwait(false); // make sure the operation is asynchronous.
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070080 metadata.Add("authorization", "SECRET_TOKEN");
81 });
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070082 }
83
Jan Tattermusch3ac49002015-12-09 16:48:16 -080084 [TearDown]
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070085 public void Cleanup()
86 {
87 channel.ShutdownAsync().Wait();
88 server.ShutdownAsync().Wait();
89 }
90
91 [Test]
92 public void MetadataCredentials()
93 {
Jan Tattermusch3ac49002015-12-09 16:48:16 -080094 var channelCredentials = ChannelCredentials.Create(TestCredentials.CreateSslCredentials(),
95 CallCredentials.FromInterceptor(asyncAuthInterceptor));
96 channel = new Channel(Host, server.Ports.Single().BoundPort, channelCredentials, options);
97 client = TestService.NewClient(channel);
98
99 client.UnaryCall(new SimpleRequest {});
100 }
101
102 [Test]
103 public void MetadataCredentials_PerCall()
104 {
105 channel = new Channel(Host, server.Ports.Single().BoundPort, TestCredentials.CreateSslCredentials(), options);
106 client = TestService.NewClient(channel);
107
108 var callCredentials = CallCredentials.FromInterceptor(asyncAuthInterceptor);
109 client.UnaryCall(new SimpleRequest { }, new CallOptions(credentials: callCredentials));
110 }
111
112 private Task<SimpleResponse> UnaryCallHandler(SimpleRequest request, ServerCallContext context)
113 {
114 var authToken = context.RequestHeaders.First((entry) => entry.Key == "authorization").Value;
115 Assert.AreEqual("SECRET_TOKEN", authToken);
116 return Task.FromResult(new SimpleResponse());
Jan Tattermusch5bd75d72015-09-08 10:55:20 -0700117 }
118 }
119}