2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-05-06 11:32:59 +00:00
This commit is contained in:
Ahmed Zamil 2024-06-23 14:10:10 +03:00
parent c17191a7bf
commit 450ed5f905
9 changed files with 105 additions and 46 deletions

View File

@ -133,7 +133,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
= ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace; = ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace;
[Attribute] [Attribute]
public Func<Map<IIPAuthPacketIAuthHeader, object>, AsyncReply<object>> Authenticator { get; set; } public Func<AuthorizationRequest, AsyncReply<object>> Authenticator { get; set; }
//public Func<Map<IIPAuthPacketIAuthHeader, object>, AsyncReply<object>> Authenticator { get; set; }
[Attribute] [Attribute]
public bool AutoReconnect { get; set; } = false; public bool AutoReconnect { get; set; } = false;
@ -931,7 +932,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
var rt = (Map<byte, object>)parsed.Wait(); var rt = (Map<byte, object>)parsed.Wait();
var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value)); var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value));
//headers[IIPAuthPacketIAuthHeader.Reference] = rt; var iAuthRequest = new AuthorizationRequest(headers);
if (Authenticator == null) if (Authenticator == null)
{ {
@ -944,7 +945,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
} }
else else
{ {
Authenticator(headers).Then(response => Authenticator(iAuthRequest).Then(response =>
{ {
SendParams() SendParams()
.AddUInt8((byte)IIPAuthPacketAction.IAuthPlain) .AddUInt8((byte)IIPAuthPacketAction.IAuthPlain)
@ -952,8 +953,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
.AddUInt8Array(Codec.Compose(response, this)) .AddUInt8Array(Codec.Compose(response, this))
.Done(); .Done();
}) })
.Timeout(headers.ContainsKey(IIPAuthPacketIAuthHeader.Timeout) ? .Timeout(iAuthRequest.Timeout * 1000,
(ushort)headers[IIPAuthPacketIAuthHeader.Timeout] * 1000 : 30000,
() => { () => {
SendParams() SendParams()
.AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate) .AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate)
@ -972,7 +972,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value)); var headers = rt.Select(x => new KeyValuePair<IIPAuthPacketIAuthHeader, object>((IIPAuthPacketIAuthHeader)x.Key, x.Value));
//headers[IIPAuthPacketIAuthHeader.Reference] = rt; var iAuthRequest = new AuthorizationRequest(headers);
if (Authenticator == null) if (Authenticator == null)
{ {
@ -986,7 +986,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
else else
{ {
Authenticator(headers).Then(response => Authenticator(iAuthRequest).Then(response =>
{ {
var sha = SHA256.Create(); var sha = SHA256.Create();
var hash = sha.ComputeHash(new BinaryList() var hash = sha.ComputeHash(new BinaryList()
@ -1003,8 +1003,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
.AddUInt8Array(hash) .AddUInt8Array(hash)
.Done(); .Done();
}) })
.Timeout(headers.ContainsKey(IIPAuthPacketIAuthHeader.Timeout) ? .Timeout(iAuthRequest.Timeout * 1000,
(ushort)headers[IIPAuthPacketIAuthHeader.Timeout] * 1000 : 30000,
() => { () => {
SendParams() SendParams()
.AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate) .AddUInt8((byte)IIPAuthPacketEvent.ErrorTerminate)
@ -1432,7 +1431,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
{ {
[IIPAuthPacketIAuthHeader.Reference] = results.Reference, [IIPAuthPacketIAuthHeader.Reference] = results.Reference,
[IIPAuthPacketIAuthHeader.Destination] = results.Destination, [IIPAuthPacketIAuthHeader.Destination] = results.Destination,
[IIPAuthPacketIAuthHeader.Timeout] = results.Timeout, [IIPAuthPacketIAuthHeader.Trials] = results.Trials,
[IIPAuthPacketIAuthHeader.Clue] = results.Clue, [IIPAuthPacketIAuthHeader.Clue] = results.Clue,
[IIPAuthPacketIAuthHeader.RequiredFormat] = results.RequiredFormat, [IIPAuthPacketIAuthHeader.RequiredFormat] = results.RequiredFormat,
}.Select(m => new KeyValuePair<byte, object>((byte)m.Key, m.Value)); }.Select(m => new KeyValuePair<byte, object>((byte)m.Key, m.Value));
@ -1449,7 +1448,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
{ {
[IIPAuthPacketIAuthHeader.Reference] = results.Reference, [IIPAuthPacketIAuthHeader.Reference] = results.Reference,
[IIPAuthPacketIAuthHeader.Destination] = results.Destination, [IIPAuthPacketIAuthHeader.Destination] = results.Destination,
[IIPAuthPacketIAuthHeader.Timeout] = results.Timeout, [IIPAuthPacketIAuthHeader.Expire] = results.Expire,
//[IIPAuthPacketIAuthHeader.Issue] = results.Issue,
[IIPAuthPacketIAuthHeader.Clue] = results.Clue, [IIPAuthPacketIAuthHeader.Clue] = results.Clue,
[IIPAuthPacketIAuthHeader.RequiredFormat] = results.RequiredFormat, [IIPAuthPacketIAuthHeader.RequiredFormat] = results.RequiredFormat,
}.Select(m => new KeyValuePair<byte, object>((byte)m.Key, m.Value)); }.Select(m => new KeyValuePair<byte, object>((byte)m.Key, m.Value));
@ -1465,7 +1465,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
var args = new Map<IIPAuthPacketIAuthHeader, object>() var args = new Map<IIPAuthPacketIAuthHeader, object>()
{ {
[IIPAuthPacketIAuthHeader.Destination] = results.Destination, [IIPAuthPacketIAuthHeader.Destination] = results.Destination,
[IIPAuthPacketIAuthHeader.Timeout] = results.Timeout, [IIPAuthPacketIAuthHeader.Expire] = results.Expire,
[IIPAuthPacketIAuthHeader.Clue] = results.Clue, [IIPAuthPacketIAuthHeader.Clue] = results.Clue,
[IIPAuthPacketIAuthHeader.RequiredFormat] = results.RequiredFormat, [IIPAuthPacketIAuthHeader.RequiredFormat] = results.RequiredFormat,
}.Select(m => new KeyValuePair<byte, object>((byte)m.Key, m.Value)); }.Select(m => new KeyValuePair<byte, object>((byte)m.Key, m.Value));

View File

@ -1,6 +1,7 @@
using Esiur.Core; using Esiur.Core;
using Esiur.Data; using Esiur.Data;
using Esiur.Net.Packets; using Esiur.Net.Packets;
using Esiur.Security.Membership;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -12,7 +13,7 @@ namespace Esiur.Net.IIP
public ExceptionLevel ExceptionLevel { get; set; } public ExceptionLevel ExceptionLevel { get; set; }
= ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace; = ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace;
public Func<Map<IIPAuthPacketIAuthHeader, object>, AsyncReply<object>> Authenticator { get; set; } public Func<AuthorizationRequest, AsyncReply<object>> Authenticator { get; set; }
public bool AutoReconnect { get; set; } = false; public bool AutoReconnect { get; set; } = false;

View File

@ -38,6 +38,7 @@ using System.Threading.Tasks;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using Esiur.Misc; using Esiur.Misc;
using Esiur.Net.Packets; using Esiur.Net.Packets;
using System.Reflection.Metadata;
namespace Esiur.Net.IIP; namespace Esiur.Net.IIP;
@ -76,13 +77,15 @@ partial class DistributedConnection
/// <param name="action">Packet action.</param> /// <param name="action">Packet action.</param>
/// <param name="args">Arguments to send.</param> /// <param name="args">Arguments to send.</param>
/// <returns></returns> /// <returns></returns>
internal SendList SendRequest(IIPPacketAction action) SendList SendRequest(IIPPacketAction action)
{ {
var reply = new AsyncReply<object[]>(); var reply = new AsyncReply<object[]>();
var c = callbackCounter++; // avoid thread racing var c = callbackCounter++; // avoid thread racing
requests.Add(c, reply); requests.Add(c, reply);
return (SendList)SendParams(reply).AddUInt8((byte)(0x40 | (byte)action)).AddUInt32(c); return (SendList)SendParams(reply)
.AddUInt8((byte)(0x40 | (byte)action))
.AddUInt32(c);
} }
/* /*
@ -205,19 +208,18 @@ partial class DistributedConnection
return reply; return reply;
} }
internal AsyncReply<object[]> SendDetachRequest(uint instanceId) internal AsyncReply<object[]> SendSetProperty(uint instanceId, byte index, object value)
{ {
try var cv = Codec.Compose(value, this);
{
return SendRequest(IIPPacketAction.DetachResource).AddUInt32(instanceId).Done(); return SendRequest(IIPPacketAction.SetProperty)
} .AddUInt32(instanceId)
catch .AddUInt8(index)
{ .AddUInt8Array(cv)
return null; .Done();
}
} }
public async void DetachResource(uint instanceId) internal AsyncReply<object[]> SendDetachRequest(uint instanceId)
{ {
try try
{ {
@ -227,11 +229,13 @@ partial class DistributedConnection
if (suspendedResources.ContainsKey(instanceId)) if (suspendedResources.ContainsKey(instanceId))
suspendedResources.Remove(instanceId); suspendedResources.Remove(instanceId);
await SendDetachRequest(instanceId); return SendRequest(IIPPacketAction.DetachResource)
.AddUInt32(instanceId)
.Done();
} }
catch catch
{ {
return null;
} }
} }

View File

@ -120,7 +120,7 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
{ {
destroyed = true; destroyed = true;
attached = false; attached = false;
connection.DetachResource(instanceId); connection.SendDetachRequest(instanceId);
OnDestroy?.Invoke(this); OnDestroy?.Invoke(this);
} }
@ -459,12 +459,7 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
var reply = new AsyncReply<object>(); var reply = new AsyncReply<object>();
var parameters = Codec.Compose(value, connection); connection.SendSetProperty(instanceId, index, value)
connection.SendRequest(IIPPacketAction.SetProperty)
.AddUInt32(instanceId)
.AddUInt8(index)
.AddUInt8Array(parameters)
.Done()
.Then((res) => .Then((res) =>
{ {
// not really needed, server will always send property modified, // not really needed, server will always send property modified,

View File

@ -12,6 +12,8 @@ namespace Esiur.Net.Packets
RequiredFormat = 3, RequiredFormat = 3,
ContentFormat = 4, ContentFormat = 4,
Content = 5, Content = 5,
Timeout = 6, Trials = 6,
Issue = 7,
Expire = 8,
} }
} }

View File

@ -0,0 +1,50 @@
using Esiur.Data;
using Esiur.Net.Packets;
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Security.Membership
{
public class AuthorizationRequest
{
public uint Reference { get; set; }
public IIPAuthPacketIAuthDestination Destination { get; set; }
public string Clue { get; set; }
public IIPAuthPacketIAuthFormat? RequiredFormat { get; set; }
public IIPAuthPacketIAuthFormat? ContentFormat { get; set; }
public object? Content { get; set; }
public byte? Trials { get; set; }
public DateTime? Issue { get; set; }
public DateTime? Expire { get; set; }
public int Timeout => Expire.HasValue && Issue.HasValue ? (int)(Expire.Value - Issue.Value).TotalSeconds : 0;
public AuthorizationRequest(Map<IIPAuthPacketIAuthHeader, object> headers)
{
Reference = (uint)headers[IIPAuthPacketIAuthHeader.Reference];
Destination = (IIPAuthPacketIAuthDestination)headers[IIPAuthPacketIAuthHeader.Destination];
Clue = (string)headers[IIPAuthPacketIAuthHeader.Clue];
if (headers.ContainsKey(IIPAuthPacketIAuthHeader.RequiredFormat))
RequiredFormat = (IIPAuthPacketIAuthFormat)headers[IIPAuthPacketIAuthHeader.RequiredFormat];
if (headers.ContainsKey(IIPAuthPacketIAuthHeader.ContentFormat))
ContentFormat = (IIPAuthPacketIAuthFormat)headers[IIPAuthPacketIAuthHeader.ContentFormat];
if (headers.ContainsKey(IIPAuthPacketIAuthHeader.Content))
Content = headers[IIPAuthPacketIAuthHeader.Content];
if (headers.ContainsKey(IIPAuthPacketIAuthHeader.Trials))
Trials = (byte)headers[IIPAuthPacketIAuthHeader.Trials];
if (headers.ContainsKey(IIPAuthPacketIAuthHeader.Issue))
Issue = (DateTime)headers[IIPAuthPacketIAuthHeader.Issue];
if (headers.ContainsKey(IIPAuthPacketIAuthHeader.Expire))
Expire = (DateTime)headers[IIPAuthPacketIAuthHeader.Expire];
}
}
}

View File

@ -8,15 +8,22 @@ namespace Esiur.Security.Membership
public class AuthorizationResults public class AuthorizationResults
{ {
public AuthorizationResultsResponse Response { get; set; } public AuthorizationResultsResponse Response { get; set; }
public IIPAuthPacketIAuthDestination Destination { get; set; }
public IIPAuthPacketIAuthFormat RequiredFormat { get; set; }
public string Clue { get; set; }
public ushort Timeout { get; set; } // 0 means no timeout
public uint Reference { get; set; } public uint Reference { get; set; }
public IIPAuthPacketIAuthDestination Destination { get; set; }
public string Clue { get; set; }
public IIPAuthPacketIAuthFormat? RequiredFormat { get; set; }
public IIPAuthPacketIAuthFormat? ContentFormat { get; set; }
public object? Content { get; set; }
public DateTime Issue { get; set; } = DateTime.UtcNow; public byte? Trials { get; set; }
public bool Expired => Timeout == 0 ? false : (DateTime.UtcNow - Issue).TotalSeconds > Timeout; public DateTime? Issue { get; set; } = DateTime.UtcNow;
public DateTime? Expire { get; set; }
public int Timeout => Expire.HasValue && Issue.HasValue ? (int)(Expire.Value - Issue.Value).TotalSeconds : 0;
public bool Expired => DateTime.Now > Expire;
} }
} }

View File

@ -82,7 +82,7 @@ namespace Esiur.Security.Membership
Destination = IIPAuthPacketIAuthDestination.Self, Destination = IIPAuthPacketIAuthDestination.Self,
Reference = (uint)r.Next(), Reference = (uint)r.Next(),
RequiredFormat = format, RequiredFormat = format,
Timeout = 30, Expire = DateTime.Now.AddSeconds(60),
Response = q.Hashed ? AuthorizationResultsResponse.IAuthHashed : AuthorizationResultsResponse.IAuthPlain Response = q.Hashed ? AuthorizationResultsResponse.IAuthHashed : AuthorizationResultsResponse.IAuthPlain
}; };

View File

@ -127,12 +127,12 @@ namespace Test
} }
// AuthorizationRequest, AsyncReply<object>
static AsyncReply<object> Authenticator(Map<IIPAuthPacketIAuthHeader, object> x) static AsyncReply<object> Authenticator(AuthorizationRequest x)
{ {
Console.WriteLine($"Authenticator: {x[IIPAuthPacketIAuthHeader.Clue]}"); Console.WriteLine($"Authenticator: {x.Clue}");
var format = (IIPAuthPacketIAuthFormat)x[IIPAuthPacketIAuthHeader.RequiredFormat]; var format = x.RequiredFormat;
if (format == IIPAuthPacketIAuthFormat.Number) if (format == IIPAuthPacketIAuthFormat.Number)
return new AsyncReply<object>(Convert.ToInt32(Console.ReadLine())); return new AsyncReply<object>(Convert.ToInt32(Console.ReadLine()));