2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-27 05:23:13 +00:00

ResourceTemplate 2.0

This commit is contained in:
2021-05-25 17:06:19 +03:00
parent c8683e17e9
commit 82cbe3b01c
26 changed files with 1105 additions and 272 deletions

View File

@ -458,7 +458,7 @@ namespace Esiur.Net.IIP
case IIPPacketAction.QueryLink:
IIPRequestQueryResources(packet.CallbackId, packet.ResourceLink);
break;
case IIPPacketAction.ResourceChildren:
IIPRequestResourceChildren(packet.CallbackId, packet.ResourceId);
break;
@ -470,6 +470,10 @@ namespace Esiur.Net.IIP
IIPRequestInquireResourceHistory(packet.CallbackId, packet.ResourceId, packet.FromDate, packet.ToDate);
break;
case IIPPacketAction.LinkTemplates:
IIPRequestLinkTemplates(packet.CallbackId, packet.ResourceLink);
break;
// Invoke
case IIPPacket.IIPPacketAction.InvokeFunctionArrayArguments:
IIPRequestInvokeFunctionArrayArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
@ -559,6 +563,7 @@ namespace Esiur.Net.IIP
case IIPPacketAction.ResourceChildren:
case IIPPacketAction.ResourceParents:
case IIPPacketAction.ResourceHistory:
case IIPPacketAction.LinkTemplates:
IIPReply(packet.CallbackId, packet.Content);
break;
@ -699,10 +704,12 @@ namespace Esiur.Net.IIP
else
{
//Console.WriteLine("User not found");
SendParams().AddUInt8(0xc0)
SendParams()
.AddUInt8(0xc0)
.AddUInt8((byte)ExceptionCode.UserOrTokenNotFound)
.AddUInt16(15)
.AddString("Token not found").Done();
.AddString("Token not found")
.Done();
}
});
}
@ -710,12 +717,49 @@ namespace Esiur.Net.IIP
{
var errMsg = DC.ToBytes(ex.Message);
SendParams()
.AddUInt8(0xc0)
.AddUInt8((byte)ExceptionCode.GeneralFailure)
.AddUInt16((ushort)errMsg.Length)
.AddUInt8Array(errMsg)
.Done();
}
}
else if (authPacket.RemoteMethod == AuthenticationMethod.None && authPacket.LocalMethod == AuthenticationMethod.None)
{
try
{
// Check if guests are allowed
if (Server.Membership.GuestsAllowed)
{
session.RemoteAuthentication.Username = "g-" + Global.GenerateCode();
session.RemoteAuthentication.Domain = authPacket.Domain;
readyToEstablish = true;
SendParams()
.AddUInt8(0x80)
.Done();
}
else
{
SendParams()
.AddUInt8(0xc0)
.AddUInt8((byte)ExceptionCode.AccessDenied)
.AddUInt16(18)
.AddString("Guests not allowed")
.Done();
}
}
catch (Exception ex)
{
var errMsg = DC.ToBytes(ex.Message);
SendParams().AddUInt8(0xc0)
.AddUInt8((byte)ExceptionCode.GeneralFailure)
.AddUInt16((ushort)errMsg.Length)
.AddUInt8Array(errMsg).Done();
}
}
}
else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Action)
{
@ -808,7 +852,7 @@ namespace Esiur.Net.IIP
Server?.Membership.Login(session);
loginDate = DateTime.Now;
}).Error(x =>
{
openReply?.TriggerError(x);
@ -832,22 +876,32 @@ namespace Esiur.Net.IIP
{
if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Acknowledge)
{
remoteNonce = authPacket.RemoteNonce;
if (authPacket.LocalMethod == AuthenticationMethod.None)
{
SendParams()
.AddUInt8(0x20)
.AddUInt16(0)
.Done();
}
else if (authPacket.LocalMethod == AuthenticationMethod.Credentials
|| authPacket.LocalMethod == AuthenticationMethod.Token)
{
remoteNonce = authPacket.RemoteNonce;
// send our hash
var hashFunc = SHA256.Create();
//var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localPassword, localNonce, remoteNonce));
var localHash = hashFunc.ComputeHash(new BinaryList()
.AddUInt8Array(localPasswordOrToken)
.AddUInt8Array(localNonce)
.AddUInt8Array(remoteNonce)
.ToArray());
SendParams()
.AddUInt8(0)
.AddUInt8Array(localHash)
.Done();
// send our hash
var hashFunc = SHA256.Create();
//var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localPassword, localNonce, remoteNonce));
var localHash = hashFunc.ComputeHash(new BinaryList()
.AddUInt8Array(localPasswordOrToken)
.AddUInt8Array(localNonce)
.AddUInt8Array(remoteNonce)
.ToArray());
SendParams()
.AddUInt8(0)
.AddUInt8Array(localHash)
.Done();
}
//SendParams((byte)0, localHash);
}
else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Action)
@ -867,7 +921,6 @@ namespace Esiur.Net.IIP
if (remoteHash.SequenceEqual(authPacket.Hash))
{
// send establish request
//SendParams((byte)0x20, (ushort)0);
SendParams()
.AddUInt8(0x20)
.AddUInt16(0)
@ -981,32 +1034,29 @@ namespace Esiur.Net.IIP
{
if (trigger == ResourceTrigger.Open)
{
if (this.Server != null)
return new AsyncReply<bool>(true);
var host = Instance.Name.Split(':');
var address = host[0];
var port = ushort.Parse(host[1]);
// assign domain from hostname if not provided
var domain = Domain != null ? Domain : address;
if (Username != null // Instance.Attributes.ContainsKey("username")
&& Password != null)/// Instance.Attributes.ContainsKey("password"))
{
// assign domain from hostname if not provided
var host = Instance.Name.Split(':');
var address = host[0];
var port = ushort.Parse(host[1]);
var domain = Domain != null ? Domain : address;
return Connect(AuthenticationMethod.Credentials, null, address, port, Username, 0, DC.ToBytes(Password), domain);
}
else if (Token != null)
{
var host = Instance.Name.Split(':');
var address = host[0];
var port = ushort.Parse(host[1]);
var domain = Domain != null ? Domain : address;
return Connect(AuthenticationMethod.Token, null, address, port, null, TokenIndex, DC.ToBytes(Token), domain);
}
else
{
return Connect(AuthenticationMethod.None, null, address, port, null, 0, null, domain);
}
}

View File

@ -498,8 +498,8 @@ namespace Esiur.Net.IIP
//r.Instance.CustomResourceEventOccurred -= Instance_CustomEventOccurred;
//r.Instance.ResourceModified -= Instance_PropertyModified;
//r.Instance.ResourceDestroyed -= Instance_ResourceDestroyed;
// r.Instance.Children.OnAdd -= Children_OnAdd;
// r.Instance.Children.OnRemoved -= Children_OnRemoved;
@ -800,16 +800,16 @@ namespace Esiur.Net.IIP
// create the resource
var resource = Activator.CreateInstance(type, args) as IResource;
Warehouse.Put( name, resource, store as IStore, parent).Then(ok =>
{
SendReply(IIPPacket.IIPPacketAction.CreateResource, callback)
.AddUInt32(resource.Instance.Id)
.Done();
Warehouse.Put(name, resource, store as IStore, parent).Then(ok =>
{
SendReply(IIPPacket.IIPPacketAction.CreateResource, callback)
.AddUInt32(resource.Instance.Id)
.Done();
}).Error(x =>
{
SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.AddToStoreFailed);
});
}).Error(x =>
{
SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.AddToStoreFailed);
});
});
});
@ -1077,6 +1077,50 @@ namespace Esiur.Net.IIP
}
void IIPRequestLinkTemplates(uint callback, string resourceLink)
{
Console.WriteLine("IIPRequestLinkTemplates " + DateTime.UtcNow);
Action<IResource[]> queryCallback = (r) =>
{
if (r == null)
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
else
{
var list = r.Where(x => x.Instance.Applicable(session, ActionType.ViewTemplate, null) != Ruling.Denied).ToArray();
if (list.Length == 0)
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
else
{
// get all templates related to this resource
var msg = new BinaryList();
var templates = new List<ResourceTemplate>();
foreach (var resource in list)
templates.AddRange(ResourceTemplate.GetRuntimeTypes(resource.Instance.Template).Where(x => !templates.Contains(x)));
foreach(var t in templates)
{
msg.AddInt32(t.Content.Length)
.AddUInt8Array(t.Content);
}
// digggg
SendReply(IIPPacket.IIPPacketAction.LinkTemplates, callback)
.AddInt32(msg.Length)
.AddUInt8Array(msg.ToArray())
.Done();
}
}
};
if (Server?.EntryPoint != null)
Server.EntryPoint.Query(resourceLink, this).Then(queryCallback);
else
Warehouse.Query(resourceLink).Then(queryCallback);
}
void IIPRequestTemplateFromClassName(uint callback, string className)
{
Warehouse.GetTemplate(className).Then((t) =>
@ -1096,19 +1140,18 @@ namespace Esiur.Net.IIP
void IIPRequestTemplateFromClassId(uint callback, Guid classId)
{
Warehouse.GetTemplate(classId).Then((t) =>
var t = Warehouse.GetTemplate(classId);
if (t != null)
SendReply(IIPPacket.IIPPacketAction.TemplateFromClassId, callback)
.AddInt32(t.Content.Length)
.AddUInt8Array(t.Content)
.Done();
else
{
if (t != null)
SendReply(IIPPacket.IIPPacketAction.TemplateFromClassId, callback)
.AddInt32(t.Content.Length)
.AddUInt8Array(t.Content)
.Done();
else
{
// reply failed
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.TemplateNotFound);
}
});
// reply failed
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.TemplateNotFound);
}
}
@ -1165,7 +1208,7 @@ namespace Esiur.Net.IIP
}
[Attribute]
public ExceptionLevel ExceptionLevel { get; set; }
public ExceptionLevel ExceptionLevel { get; set; }
= ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace;
private Tuple<ushort, string> SummerizeException(Exception ex)
@ -1477,17 +1520,17 @@ namespace Esiur.Net.IIP
.AddUInt8Array(Codec.Compose(res, this))
.Done();
}).Error(ex =>
{
var (code, msg) = SummerizeException(ex);
SendError(ErrorType.Exception, callback, code, msg);
}).Progress((pt, pv, pm) =>
{
SendProgress(callback, pv, pm);
}).Chunk(v =>
{
SendChunk(callback, v);
});
}).Error(ex =>
{
var (code, msg) = SummerizeException(ex);
SendError(ErrorType.Exception, callback, code, msg);
}).Progress((pt, pv, pm) =>
{
SendProgress(callback, pv, pm);
}).Chunk(v =>
{
SendChunk(callback, v);
});
}
else
{
@ -1539,7 +1582,7 @@ namespace Esiur.Net.IIP
}
else
{
lock(subscriptionsLock)
lock (subscriptionsLock)
{
if (!subscriptions.ContainsKey(r))
{
@ -1711,51 +1754,51 @@ namespace Esiur.Net.IIP
});
}
// void IIPRequestGetPropertyIfModifiedSince(uint callback, uint resourceId, byte index, ulong age)
// {
// Warehouse.GetById(resourceId).Then((r) =>
// {
// if (r != null)
// {
// var pt = r.Instance.Template.GetFunctionTemplateByIndex(index);
// if (pt != null)
// {
// if (r.Instance.GetAge(index) > age)
// {
//#if NETSTANDARD
// var pi = r.GetType().GetTypeInfo().GetProperty(pt.Name);
//#else
// var pi = r.GetType().GetProperty(pt.Name);
//#endif
// if (pi != null)
// {
// SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
// .AddUInt8Array(Codec.Compose(pi.GetValue(r), this))
// .Done();
// }
// else
// {
// // pt found, pi not found, this should never happen
// }
// }
// else
// {
// SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
// .AddUInt8((byte)DataType.NotModified)
// .Done();
// }
// }
// else
// {
// // pt not found
// }
// }
// else
// {
// // resource not found
// }
// });
// }
// void IIPRequestGetPropertyIfModifiedSince(uint callback, uint resourceId, byte index, ulong age)
// {
// Warehouse.GetById(resourceId).Then((r) =>
// {
// if (r != null)
// {
// var pt = r.Instance.Template.GetFunctionTemplateByIndex(index);
// if (pt != null)
// {
// if (r.Instance.GetAge(index) > age)
// {
//#if NETSTANDARD
// var pi = r.GetType().GetTypeInfo().GetProperty(pt.Name);
//#else
// var pi = r.GetType().GetProperty(pt.Name);
//#endif
// if (pi != null)
// {
// SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
// .AddUInt8Array(Codec.Compose(pi.GetValue(r), this))
// .Done();
// }
// else
// {
// // pt found, pi not found, this should never happen
// }
// }
// else
// {
// SendReply(IIPPacket.IIPPacketAction.GetPropertyIfModified, callback)
// .AddUInt8((byte)DataType.NotModified)
// .Done();
// }
// }
// else
// {
// // pt not found
// }
// }
// else
// {
// // resource not found
// }
// });
// }
void IIPRequestSetProperty(uint callback, uint resourceId, byte index, byte[] content)
{
@ -1791,7 +1834,7 @@ namespace Esiur.Net.IIP
var pi = r.GetType().GetProperty(pt.Name);
#endif*/
var pi = pt.Info;
var pi = pt.PropertyInfo;
if (pi != null)
{
@ -2091,6 +2134,43 @@ namespace Esiur.Net.IIP
return new AsyncReply<IResource>(null);
}
public AsyncReply<ResourceTemplate[]> GetLinkTemplates(string link)
{
var reply = new AsyncReply<ResourceTemplate[]>();
var l = DC.ToBytes(link);
SendRequest(IIPPacket.IIPPacketAction.LinkTemplates)
.AddUInt16((ushort)l.Length)
.AddUInt8Array(l)
.Done()
.Then((rt) =>
{
var templates = new List<ResourceTemplate>();
// parse templates
var data = (byte[])rt[0];
//var offset = 0;
for (uint offset = 0; offset < data.Length;)
{
var cs = data.GetUInt32(offset);
offset += 4;
templates.Add(ResourceTemplate.Parse(data, offset, cs));
offset += cs;
}
reply.Trigger(templates.ToArray());
}).Error((ex) =>
{
reply.TriggerError(ex);
});
return reply;
}
/// <summary>
/// Fetch a resource from the other end
/// </summary>
@ -2125,7 +2205,19 @@ namespace Esiur.Net.IIP
.Then((rt) =>
{
var dr = resource ?? new DistributedResource(this, id, (ulong)rt[1], (string)rt[2]);
DistributedResource dr;
if (resource == null)
{
var template = Warehouse.GetTemplate((Guid)rt[0]);
if (template?.RuntimeType != null)
dr = Activator.CreateInstance(template.RuntimeType, this, id, (ulong)rt[1], (string)rt[2]) as DistributedResource;
else
dr = new DistributedResource(this, id, (ulong)rt[1], (string)rt[2]);
}
else
dr = resource;
GetTemplate((Guid)rt[0]).Then((tmp) =>
{
@ -2140,7 +2232,7 @@ namespace Esiur.Net.IIP
resourceRequests.Remove(id);
reply.Trigger(dr);
});
}).Error(ex=>reply.TriggerError(ex));
}).Error(ex => reply.TriggerError(ex));
}
else
{
@ -2149,7 +2241,7 @@ namespace Esiur.Net.IIP
dr._Attach(ar);
resourceRequests.Remove(id);
reply.Trigger(dr);
}).Error(ex=>reply.TriggerError(ex));
}).Error(ex => reply.TriggerError(ex));
}
}).Error((ex) =>
@ -2422,9 +2514,9 @@ namespace Esiur.Net.IIP
private void UnsubscribeAll()
{
lock(subscriptionsLock)
lock (subscriptionsLock)
{
foreach(var resource in subscriptions.Keys)
foreach (var resource in subscriptions.Keys)
{
resource.Instance.ResourceEventOccurred -= Instance_EventOccurred;
resource.Instance.CustomResourceEventOccurred -= Instance_CustomEventOccurred;
@ -2491,7 +2583,7 @@ namespace Esiur.Net.IIP
if (resource.Instance.Applicable(this.session, ActionType.ReceiveEvent, et, issuer) == Ruling.Denied)
return;
// compose the packet
SendEvent(IIPPacket.IIPPacketEvent.EventOccurred)
.AddUInt32(resource.Instance.Id)

View File

@ -67,7 +67,7 @@ namespace Esiur.Net.IIP
string link;
//ulong age;
//ulong[] ages;
object[] properties;
protected object[] properties;
internal List<DistributedResource> parents = new List<DistributedResource>();
internal List<DistributedResource> children = new List<DistributedResource>();
@ -210,13 +210,16 @@ namespace Esiur.Net.IIP
return true;
}
internal void _EmitEventByIndex(byte index, object args)
protected internal virtual void _EmitEventByIndex(byte index, object args)
{
var et = Instance.Template.GetEventTemplateByIndex(index);
events[index]?.Invoke(this, args);
Instance.EmitResourceEvent(et.Name, args);
}
public AsyncReply<object> _InvokeByNamedArguments(byte index, Structure namedArgs)
{
if (destroyed)
@ -332,7 +335,7 @@ namespace Esiur.Net.IIP
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <returns>Value</returns>
internal object _Get(byte index)
protected internal object _Get(byte index)
{
if (index >= properties.Length)
return null;
@ -383,7 +386,7 @@ namespace Esiur.Net.IIP
/// <param name="index">Zero-based property index.</param>
/// <param name="value">Value</param>
/// <returns>Indicator when the property is set.</returns>
internal AsyncReply<object> _Set(byte index, object value)
protected internal AsyncReply<object> _Set(byte index, object value)
{
if (index >= properties.Length)
return null;

View File

@ -30,5 +30,5 @@ using System.Threading.Tasks;
namespace Esiur.Net.IIP
{
public delegate void DistributedResourceEvent(DistributedResource sender, object arguments);
public delegate void DistributedResourceEvent(DistributedResource sender, object argument);
}

View File

@ -344,12 +344,15 @@ namespace Esiur.Net.Packets
LocalMethod = (AuthenticationMethod)((data[offset] >> 2) & 0x3);
var encrypt = ((data[offset++] & 0x2) == 0x2);
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
if (RemoteMethod == AuthenticationMethod.Credentials
|| RemoteMethod == AuthenticationMethod.Token)
if (RemoteMethod == AuthenticationMethod.None)
{
if (LocalMethod == AuthenticationMethod.None)
{
// do nothing
}
}
else if (RemoteMethod == AuthenticationMethod.Credentials
|| RemoteMethod == AuthenticationMethod.Token)
{
if (LocalMethod == AuthenticationMethod.None)
{

View File

@ -107,6 +107,7 @@ namespace Esiur.Net.Packets
ResourceHistory,
ResourceChildren,
ResourceParents,
LinkTemplates,
// Request Invoke
InvokeFunctionArrayArguments = 0x10,
@ -484,7 +485,8 @@ namespace Esiur.Net.Packets
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.QueryLink)
else if (Action == IIPPacketAction.QueryLink
|| Action == IIPPacketAction.LinkTemplates)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
@ -691,6 +693,7 @@ namespace Esiur.Net.Packets
|| Action == IIPPacketAction.ResourceChildren
|| Action == IIPPacketAction.ResourceParents
|| Action == IIPPacketAction.ResourceHistory
|| Action == IIPPacketAction.LinkTemplates
// Attribute
|| Action == IIPPacketAction.GetAllAttributes
|| Action == IIPPacketAction.GetAttributes)