mirror of https://github.com/grpc/grpc.git
Merge pull request #9632 from jtattermusch/csharp_server_side_auth
Expose AuthContext in C#pull/9899/merge
commit
efe7572c72
17 changed files with 765 additions and 21 deletions
@ -0,0 +1,86 @@ |
|||||||
|
#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 NUnit.Framework; |
||||||
|
using Grpc.Core; |
||||||
|
using System.Linq; |
||||||
|
|
||||||
|
namespace Grpc.Core.Tests |
||||||
|
{ |
||||||
|
public class AuthContextTest |
||||||
|
{ |
||||||
|
[Test] |
||||||
|
public void EmptyContext() |
||||||
|
{ |
||||||
|
var context = new AuthContext(null, new Dictionary<string, List<AuthProperty>>()); |
||||||
|
Assert.IsFalse(context.IsPeerAuthenticated); |
||||||
|
Assert.IsNull(context.PeerIdentityPropertyName); |
||||||
|
Assert.AreEqual(0, context.PeerIdentity.Count()); |
||||||
|
Assert.AreEqual(0, context.Properties.Count()); |
||||||
|
Assert.AreEqual(0, context.FindPropertiesByName("nonexistent").Count()); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void AuthenticatedContext() |
||||||
|
{ |
||||||
|
var property1 = AuthProperty.Create("abc", new byte[] { 68, 69, 70 }); |
||||||
|
var context = new AuthContext("some_identity", new Dictionary<string, List<AuthProperty>> |
||||||
|
{ |
||||||
|
{"some_identity", new List<AuthProperty> {property1}} |
||||||
|
}); |
||||||
|
Assert.IsTrue(context.IsPeerAuthenticated); |
||||||
|
Assert.AreEqual("some_identity", context.PeerIdentityPropertyName); |
||||||
|
Assert.AreEqual(1, context.PeerIdentity.Count()); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void FindPropertiesByName() |
||||||
|
{ |
||||||
|
var property1 = AuthProperty.Create("abc", new byte[] {68, 69, 70}); |
||||||
|
var property2 = AuthProperty.Create("abc", new byte[] {71, 72, 73 }); |
||||||
|
var property3 = AuthProperty.Create("abc", new byte[] {}); |
||||||
|
var context = new AuthContext(null, new Dictionary<string, List<AuthProperty>> |
||||||
|
{ |
||||||
|
{"existent", new List<AuthProperty> {property1, property2}}, |
||||||
|
{"foobar", new List<AuthProperty> {property3}}, |
||||||
|
}); |
||||||
|
Assert.AreEqual(3, context.Properties.Count()); |
||||||
|
Assert.AreEqual(0, context.FindPropertiesByName("nonexistent").Count()); |
||||||
|
|
||||||
|
var existentProperties = new List<AuthProperty>(context.FindPropertiesByName("existent")); |
||||||
|
Assert.AreEqual(2, existentProperties.Count); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,82 @@ |
|||||||
|
#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 NUnit.Framework; |
||||||
|
|
||||||
|
namespace Grpc.Core.Tests |
||||||
|
{ |
||||||
|
public class AuthPropertyTest |
||||||
|
{ |
||||||
|
[Test] |
||||||
|
public void Create_NameIsNotNull() |
||||||
|
{ |
||||||
|
Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.Create(null, new byte[0])); |
||||||
|
Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.CreateUnsafe(null, new byte[0])); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void Create_ValueIsNotNull() |
||||||
|
{ |
||||||
|
Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.Create("abc", null)); |
||||||
|
Assert.Throws(typeof(ArgumentNullException), () => AuthProperty.CreateUnsafe("abc", null)); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void Create() |
||||||
|
{ |
||||||
|
var valueBytes = new byte[] { 68, 69, 70 }; |
||||||
|
var authProperty = AuthProperty.Create("abc", valueBytes); |
||||||
|
|
||||||
|
Assert.AreEqual("abc", authProperty.Name); |
||||||
|
Assert.AreNotSame(valueBytes, authProperty.ValueBytesUnsafe); |
||||||
|
CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytes); |
||||||
|
CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytesUnsafe); |
||||||
|
Assert.AreEqual("DEF", authProperty.Value); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void CreateUnsafe() |
||||||
|
{ |
||||||
|
var valueBytes = new byte[] { 68, 69, 70 }; |
||||||
|
var authProperty = AuthProperty.CreateUnsafe("abc", valueBytes); |
||||||
|
|
||||||
|
Assert.AreEqual("abc", authProperty.Name); |
||||||
|
Assert.AreSame(valueBytes, authProperty.ValueBytesUnsafe); |
||||||
|
Assert.AreNotSame(valueBytes, authProperty.ValueBytes); |
||||||
|
CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytes); |
||||||
|
CollectionAssert.AreEqual(valueBytes, authProperty.ValueBytesUnsafe); |
||||||
|
Assert.AreEqual("DEF", authProperty.Value); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,128 @@ |
|||||||
|
#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.Linq; |
||||||
|
using Grpc.Core.Internal; |
||||||
|
using Grpc.Core.Utils; |
||||||
|
|
||||||
|
namespace Grpc.Core |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Authentication context for a call. |
||||||
|
/// AuthContext is the only reliable source of truth when it comes to authenticating calls. |
||||||
|
/// Using any other call/context properties for authentication purposes is wrong and inherently unsafe. |
||||||
|
/// Note: experimental API that can change or be removed without any prior notice. |
||||||
|
/// </summary> |
||||||
|
public class AuthContext |
||||||
|
{ |
||||||
|
string peerIdentityPropertyName; |
||||||
|
Dictionary<string, List<AuthProperty>> properties; |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the <see cref="T:Grpc.Core.AuthContext"/> class. |
||||||
|
/// </summary> |
||||||
|
/// <param name="peerIdentityPropertyName">Peer identity property name.</param> |
||||||
|
/// <param name="properties">Multimap of auth properties by name.</param> |
||||||
|
internal AuthContext(string peerIdentityPropertyName, Dictionary<string, List<AuthProperty>> properties) |
||||||
|
{ |
||||||
|
this.peerIdentityPropertyName = peerIdentityPropertyName; |
||||||
|
this.properties = GrpcPreconditions.CheckNotNull(properties); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Returns <c>true</c> if the peer is authenticated. |
||||||
|
/// </summary> |
||||||
|
public bool IsPeerAuthenticated |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return peerIdentityPropertyName != null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the name of the property that indicates the peer identity. Returns <c>null</c> |
||||||
|
/// if the peer is not authenticated. |
||||||
|
/// </summary> |
||||||
|
public string PeerIdentityPropertyName |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return peerIdentityPropertyName; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets properties that represent the peer identity (there can be more than one). Returns an empty collection |
||||||
|
/// if the peer is not authenticated. |
||||||
|
/// </summary> |
||||||
|
public IEnumerable<AuthProperty> PeerIdentity |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
if (peerIdentityPropertyName == null) |
||||||
|
{ |
||||||
|
return Enumerable.Empty<AuthProperty>(); |
||||||
|
} |
||||||
|
return properties[peerIdentityPropertyName]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the auth properties of this context. |
||||||
|
/// </summary> |
||||||
|
public IEnumerable<AuthProperty> Properties |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return properties.Values.SelectMany(v => v); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Returns the auth properties with given name (there can be more than one). |
||||||
|
/// If no properties of given name exist, an empty collection will be returned. |
||||||
|
/// </summary> |
||||||
|
public IEnumerable<AuthProperty> FindPropertiesByName(string propertyName) |
||||||
|
{ |
||||||
|
List<AuthProperty> result; |
||||||
|
if (!properties.TryGetValue(propertyName, out result)) |
||||||
|
{ |
||||||
|
return Enumerable.Empty<AuthProperty>(); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,126 @@ |
|||||||
|
#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.Linq; |
||||||
|
using Grpc.Core.Internal; |
||||||
|
using Grpc.Core.Utils; |
||||||
|
|
||||||
|
namespace Grpc.Core |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// A property of an <see cref="AuthContext"/>. |
||||||
|
/// Note: experimental API that can change or be removed without any prior notice. |
||||||
|
/// </summary> |
||||||
|
public class AuthProperty |
||||||
|
{ |
||||||
|
string name; |
||||||
|
byte[] valueBytes; |
||||||
|
Lazy<string> value; |
||||||
|
|
||||||
|
private AuthProperty(string name, byte[] valueBytes) |
||||||
|
{ |
||||||
|
this.name = GrpcPreconditions.CheckNotNull(name); |
||||||
|
this.valueBytes = GrpcPreconditions.CheckNotNull(valueBytes); |
||||||
|
this.value = new Lazy<string>(() => MarshalUtils.GetStringUTF8(this.valueBytes)); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the name of the property. |
||||||
|
/// </summary> |
||||||
|
public string Name |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return name; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the string value of the property. |
||||||
|
/// </summary> |
||||||
|
public string Value |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return value.Value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the binary value of the property. |
||||||
|
/// </summary> |
||||||
|
public byte[] ValueBytes |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
var valueCopy = new byte[valueBytes.Length]; |
||||||
|
Buffer.BlockCopy(valueBytes, 0, valueCopy, 0, valueBytes.Length); |
||||||
|
return valueCopy; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Creates an instance of <c>AuthProperty</c>. |
||||||
|
/// </summary> |
||||||
|
/// <param name="name">the name</param> |
||||||
|
/// <param name="valueBytes">the binary value of the property</param> |
||||||
|
public static AuthProperty Create(string name, byte[] valueBytes) |
||||||
|
{ |
||||||
|
GrpcPreconditions.CheckNotNull(valueBytes); |
||||||
|
var valueCopy = new byte[valueBytes.Length]; |
||||||
|
Buffer.BlockCopy(valueBytes, 0, valueCopy, 0, valueBytes.Length); |
||||||
|
return new AuthProperty(name, valueCopy); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the binary value of the property (without making a defensive copy). |
||||||
|
/// </summary> |
||||||
|
internal byte[] ValueBytesUnsafe |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return valueBytes; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Creates and instance of <c>AuthProperty</c> without making a defensive copy of <c>valueBytes</c>. |
||||||
|
/// </summary> |
||||||
|
internal static AuthProperty CreateUnsafe(string name, byte[] valueBytes) |
||||||
|
{ |
||||||
|
return new AuthProperty(name, valueBytes); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,119 @@ |
|||||||
|
#region Copyright notice and license |
||||||
|
|
||||||
|
// Copyright 2017, 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.Runtime.InteropServices; |
||||||
|
using System.Text; |
||||||
|
using Grpc.Core; |
||||||
|
using Grpc.Core.Utils; |
||||||
|
|
||||||
|
namespace Grpc.Core.Internal |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// grpc_auth_context |
||||||
|
/// </summary> |
||||||
|
internal class AuthContextSafeHandle : SafeHandleZeroIsInvalid |
||||||
|
{ |
||||||
|
static readonly NativeMethods Native = NativeMethods.Get(); |
||||||
|
|
||||||
|
private AuthContextSafeHandle() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Copies contents of the native auth context into a new <c>AuthContext</c> instance. |
||||||
|
/// </summary> |
||||||
|
public AuthContext ToAuthContext() |
||||||
|
{ |
||||||
|
if (IsInvalid) |
||||||
|
{ |
||||||
|
return new AuthContext(null, new Dictionary<string, List<AuthProperty>>()); |
||||||
|
} |
||||||
|
|
||||||
|
var peerIdentityPropertyName = Marshal.PtrToStringAnsi(Native.grpcsharp_auth_context_peer_identity_property_name(this)); |
||||||
|
|
||||||
|
var propertiesDict = new Dictionary<string, List<AuthProperty>>(); |
||||||
|
|
||||||
|
var it = Native.grpcsharp_auth_context_property_iterator(this); |
||||||
|
IntPtr authPropertyPtr = IntPtr.Zero; |
||||||
|
while ((authPropertyPtr = Native.grpcsharp_auth_property_iterator_next(ref it)) != IntPtr.Zero) |
||||||
|
{ |
||||||
|
var authProperty = PtrToAuthProperty(authPropertyPtr); |
||||||
|
|
||||||
|
if (!propertiesDict.ContainsKey(authProperty.Name)) |
||||||
|
{ |
||||||
|
propertiesDict[authProperty.Name] = new List<AuthProperty>(); |
||||||
|
} |
||||||
|
propertiesDict[authProperty.Name].Add(authProperty); |
||||||
|
} |
||||||
|
|
||||||
|
return new AuthContext(peerIdentityPropertyName, propertiesDict); |
||||||
|
} |
||||||
|
|
||||||
|
protected override bool ReleaseHandle() |
||||||
|
{ |
||||||
|
Native.grpcsharp_auth_context_release(handle); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private AuthProperty PtrToAuthProperty(IntPtr authPropertyPtr) |
||||||
|
{ |
||||||
|
var nativeAuthProperty = (NativeAuthProperty) Marshal.PtrToStructure(authPropertyPtr, typeof(NativeAuthProperty)); |
||||||
|
var name = Marshal.PtrToStringAnsi(nativeAuthProperty.Name); |
||||||
|
var valueBytes = new byte[(int) nativeAuthProperty.ValueLength]; |
||||||
|
Marshal.Copy(nativeAuthProperty.Value, valueBytes, 0, (int)nativeAuthProperty.ValueLength); |
||||||
|
return AuthProperty.CreateUnsafe(name, valueBytes); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// grpc_auth_property |
||||||
|
/// </summary> |
||||||
|
internal struct NativeAuthProperty |
||||||
|
{ |
||||||
|
public IntPtr Name; |
||||||
|
public IntPtr Value; |
||||||
|
public UIntPtr ValueLength; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// grpc_auth_property_iterator |
||||||
|
/// </summary> |
||||||
|
internal struct NativeAuthPropertyIterator |
||||||
|
{ |
||||||
|
public IntPtr AuthContext; |
||||||
|
public UIntPtr Index; |
||||||
|
public IntPtr Name; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
#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.Runtime.InteropServices; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace Grpc.Core.Internal |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Useful methods for native/managed marshalling. |
||||||
|
/// </summary> |
||||||
|
internal static class MarshalUtils |
||||||
|
{ |
||||||
|
static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; |
||||||
|
static readonly Encoding EncodingASCII = System.Text.Encoding.ASCII; |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Converts <c>IntPtr</c> pointing to a UTF-8 encoded byte array to <c>string</c>. |
||||||
|
/// </summary> |
||||||
|
public static string PtrToStringUTF8(IntPtr ptr, int len) |
||||||
|
{ |
||||||
|
var bytes = new byte[len]; |
||||||
|
Marshal.Copy(ptr, bytes, 0, len); |
||||||
|
return EncodingUTF8.GetString(bytes); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Returns byte array containing UTF-8 encoding of given string. |
||||||
|
/// </summary> |
||||||
|
public static byte[] GetBytesUTF8(string str) |
||||||
|
{ |
||||||
|
return EncodingUTF8.GetBytes(str); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Get string from a UTF8 encoded byte array. |
||||||
|
/// </summary> |
||||||
|
public static string GetStringUTF8(byte[] bytes) |
||||||
|
{ |
||||||
|
return EncodingUTF8.GetString(bytes); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Returns byte array containing ASCII encoding of given string. |
||||||
|
/// </summary> |
||||||
|
public static byte[] GetBytesASCII(string str) |
||||||
|
{ |
||||||
|
return EncodingASCII.GetBytes(str); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Get string from an ASCII encoded byte array. |
||||||
|
/// </summary> |
||||||
|
public static string GetStringASCII(byte[] bytes) |
||||||
|
{ |
||||||
|
return EncodingASCII.GetString(bytes); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue