diff --git a/README.md b/README.md index a908c63..b497ea0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# Esyur +# Esiur Distributed Object Framework ## Getting Started -For help getting started with Esyur, view our -[online documentation](http://www.esyur.com), which offers tutorials, +For help getting started with Esiur, view our +[online documentation](http://www.esiur.com), which offers tutorials, samples, guidance on mobile development, and a full API reference. diff --git a/lib/esyur.dart b/lib/esiur.dart similarity index 97% rename from lib/esyur.dart rename to lib/esiur.dart index 41ac774..5b8819f 100644 --- a/lib/esyur.dart +++ b/lib/esiur.dart @@ -62,7 +62,6 @@ export 'src/Net/IIP/DistributedResourceQueueItemType.dart'; export 'src/Net/Packets/IIPAuthPacket.dart'; export 'src/Net/Packets/IIPAuthPacketAction.dart'; export 'src/Net/Packets/IIPAuthPacketCommand.dart'; -export 'src/Net/Packets/IIPAuthPacketMethod.dart'; export 'src/Net/Packets/IIPPacket.dart'; export 'src/Net/Packets/IIPPacketAction.dart'; export 'src/Net/Packets/IIPPacketCommand.dart'; @@ -80,6 +79,7 @@ export 'src/Net/Sockets/TCPSocket.dart'; export 'src/Security/Authority/Authentication.dart'; export 'src/Security/Authority/AuthenticationState.dart'; export 'src/Security/Authority/AuthenticationType.dart'; +export 'src/Security/Authority/AuthenticationMethod.dart'; export 'src/Security/Authority/ClientAuthentication.dart'; export 'src/Security/Authority/CoHostAuthentication.dart'; export 'src/Security/Authority/HostAuthentication.dart'; diff --git a/lib/src/Core/AsyncQueue.dart b/lib/src/Core/AsyncQueue.dart index 18d1687..f4c3c0b 100644 --- a/lib/src/Core/AsyncQueue.dart +++ b/lib/src/Core/AsyncQueue.dart @@ -1,52 +1,42 @@ -library esyur; +library esiur; import 'AsyncReply.dart'; -class AsyncQueue extends AsyncReply -{ - List> _list = new List>(); +class AsyncQueue extends AsyncReply { + List> _list = new List>(); // object queueLock = new object(); - - add(AsyncReply reply) - { - //lock (queueLock) - _list.add(reply); - //super._resultReady = false; - super.setResultReady(false); + add(AsyncReply reply) { + //lock (queueLock) + _list.add(reply); - reply.then(processQueue); - } + //super._resultReady = false; + super.setResultReady(false); - remove(AsyncReply reply) - { - //lock (queueLock) - _list.remove(reply); - processQueue(null); - } - - void processQueue(T o) - { - //lock (queueLock) - for (var i = 0; i < _list.length; i++) - if (_list[i].ready) - { - super.trigger(_list[i].result); - super.ready = false; - _list.removeAt(i); - i--; - } - else - break; - - - //super._resultReady = (_list.length == 0); - super.setResultReady(_list.length == 0); - } - - AsyncQueue() - { - - } + reply.then(processQueue); } + + remove(AsyncReply reply) { + //lock (queueLock) + _list.remove(reply); + processQueue(null); + } + + void processQueue(T o) { + //lock (queueLock) + for (var i = 0; i < _list.length; i++) + if (_list[i].ready) { + super.trigger(_list[i].result); + super.ready = false; + _list.removeAt(i); + i--; + } else + break; + + //super._resultReady = (_list.length == 0); + super.setResultReady(_list.length == 0); + } + + AsyncQueue() {} +} diff --git a/lib/src/Core/ExceptionCode.dart b/lib/src/Core/ExceptionCode.dart index 5d610ec..4312b52 100644 --- a/lib/src/Core/ExceptionCode.dart +++ b/lib/src/Core/ExceptionCode.dart @@ -3,7 +3,7 @@ enum ExceptionCode { HostNotReachable, AccessDenied, - UserNotFound, + UserOrTokenNotFound, ChallengeFailed, ResourceNotFound, AttachDenied, @@ -29,5 +29,6 @@ enum ExceptionCode MethodNotFound, PropertyNotFound, SetPropertyDenied, - ReadOnlyProperty + ReadOnlyProperty, + GeneralFailure } \ No newline at end of file diff --git a/lib/src/Core/IDestructible.dart b/lib/src/Core/IDestructible.dart index 3bdbf0f..748d135 100644 --- a/lib/src/Core/IDestructible.dart +++ b/lib/src/Core/IDestructible.dart @@ -1,4 +1,4 @@ -// library esyur; +// library esiur; import 'IEventHandler.dart'; diff --git a/lib/src/Net/IIP/DistributedConnection.dart b/lib/src/Net/IIP/DistributedConnection.dart index 0f42a5a..a897dea 100644 --- a/lib/src/Net/IIP/DistributedConnection.dart +++ b/lib/src/Net/IIP/DistributedConnection.dart @@ -22,6 +22,10 @@ SOFTWARE. */ +import 'dart:ffi'; + +import 'package:esiur/src/Security/Authority/AuthenticationMethod.dart'; + import '../../Core/AsyncBag.dart'; import '../Sockets/TCPSocket.dart'; @@ -61,7 +65,6 @@ import '../Packets/IIPPacketAction.dart'; import '../Packets/IIPPacketCommand.dart'; import '../Packets/IIPPacketEvent.dart'; import '../Packets/IIPPacketReport.dart'; -import '../Packets/IIPAuthPacketMethod.dart'; import '../../Data/BinaryList.dart'; import '../NetworkConnection.dart'; import '../../Data/Guid.dart'; @@ -97,7 +100,7 @@ class DistributedConnection extends NetworkConnection with IStore Session _session; - DC _localPassword; + DC _localPasswordOrToken; DC _localNonce, _remoteNonce; String _hostname; @@ -181,7 +184,6 @@ class DistributedConnection extends NetworkConnection with IStore && instance.attributes.containsKey("password")) { - var host = instance.name.split(":"); // assign domain from hostname if not provided @@ -193,17 +195,29 @@ class DistributedConnection extends NetworkConnection with IStore var password = DC.stringToBytes(instance.attributes["password"].toString()); + return connect(method: AuthenticationMethod.Credentials, domain: domain, hostname: address, port: port, passwordOrToken: password, username: username); + } + else if (instance.attributes.containsKey("token")) + { + var host = instance.name.split(":"); + // assign domain from hostname if not provided - return connect(domain: domain, hostname: address, port: port, password: password, username: username); + var address = host[0]; + var port = int.parse(host[1]); + var domain = instance.attributes.containsKey("domain") ? instance.attributes["domain"] : address; + + var token = DC.stringToBytes(instance.attributes["token"].toString()); + var tokenIndex = instance.attributes["tokenIndex"] ?? 0; + return connect(method: AuthenticationMethod.Credentials, domain: domain, hostname: address, port: port, passwordOrToken: token, tokenIndex: tokenIndex); } } return new AsyncReply.ready(true); } - AsyncReply connect({ISocket socket, String hostname, int port, String username, DC password, String domain}) + AsyncReply connect({AuthenticationMethod method, ISocket socket, String hostname, int port, String username, int tokenIndex, DC passwordOrToken, String domain}) { if (_openReply != null) throw AsyncException(ErrorType.Exception, 0, "Connection in progress"); @@ -215,9 +229,11 @@ class DistributedConnection extends NetworkConnection with IStore _session = new Session(new ClientAuthentication() , new HostAuthentication()); + _session.localAuthentication.method = method; + _session.localAuthentication.tokenIndex = tokenIndex; _session.localAuthentication.domain = domain; _session.localAuthentication.username = username; - _localPassword = password; + _localPasswordOrToken = passwordOrToken; } if (_session == null) @@ -350,16 +366,35 @@ class DistributedConnection extends NetworkConnection with IStore { _session = new Session(new ClientAuthentication() , new HostAuthentication()); - + + _session.localAuthentication.method = AuthenticationMethod.Credentials; _session.localAuthentication.domain = domain; _session.localAuthentication.username = username; - _localPassword = DC.stringToBytes(password); + + _localPasswordOrToken = DC.stringToBytes(password); init(); assign(socket); } + DistributedConnection.connectWithToken(ISocket socket, String domain, int tokenIndex, String token) + { + _session = new Session(new ClientAuthentication() + , new HostAuthentication()); + + _session.localAuthentication.method = AuthenticationMethod.Token; + _session.localAuthentication.domain = domain; + _session.localAuthentication.tokenIndex = tokenIndex; + + _localPasswordOrToken = DC.stringToBytes(token); + + init(); + + assign(socket); + } + + /// /// Create a new instance of a distributed connection /// @@ -670,7 +705,7 @@ class DistributedConnection extends NetworkConnection with IStore { if (_authPacket.command == IIPAuthPacketCommand.Declare) { - if (_authPacket.remoteMethod == IIPAuthPacketMethod.Credentials && _authPacket.localMethod == IIPAuthPacketMethod.None) + if (_authPacket.remoteMethod == AuthenticationMethod.Credentials && _authPacket.localMethod == AuthenticationMethod.None) { /* @@ -768,7 +803,7 @@ class DistributedConnection extends NetworkConnection with IStore // send our hash var localHash = SHA256.compute(new BinaryList() - .addDC(_localPassword) + .addDC(_localPasswordOrToken) .addDC(_localNonce) .addDC(_remoteNonce) .toDC()); @@ -788,7 +823,7 @@ class DistributedConnection extends NetworkConnection with IStore var remoteHash = SHA256.compute(new BinaryList() .addDC(_remoteNonce) .addDC(_localNonce) - .addDC(_localPassword) + .addDC(_localPasswordOrToken) .toDC()); diff --git a/lib/src/Net/IIP/DistributedResource.dart b/lib/src/Net/IIP/DistributedResource.dart index 7f5ac34..3acc8bd 100644 --- a/lib/src/Net/IIP/DistributedResource.dart +++ b/lib/src/Net/IIP/DistributedResource.dart @@ -22,8 +22,8 @@ SOFTWARE. */ -import 'package:esyur/esyur.dart'; -import 'package:esyur/src/Data/KeyValuePair.dart'; +import 'package:esiur/esiur.dart'; +import 'package:esiur/src/Data/KeyValuePair.dart'; import '../../Resource/IResource.dart'; import '../../Core/AsyncReply.dart'; diff --git a/lib/src/Net/Packets/IIPAuthPacket.dart b/lib/src/Net/Packets/IIPAuthPacket.dart index 07f80d9..e1bf2a4 100644 --- a/lib/src/Net/Packets/IIPAuthPacket.dart +++ b/lib/src/Net/Packets/IIPAuthPacket.dart @@ -24,7 +24,7 @@ SOFTWARE. import '../../Data/DC.dart'; import 'IIPAuthPacketAction.dart'; import 'IIPAuthPacketCommand.dart'; -import 'IIPAuthPacketMethod.dart'; +import '../../Security/Authority/AuthenticationMethod.dart'; class IIPAuthPacket { @@ -35,7 +35,7 @@ class IIPAuthPacket int errorCode; String errorMessage; - int localMethod; + AuthenticationMethod localMethod; DC sourceInfo; @@ -43,7 +43,7 @@ class IIPAuthPacket DC sessionId; - int remoteMethod; + AuthenticationMethod remoteMethod; String domain; @@ -67,6 +67,8 @@ class IIPAuthPacket DC remoteNonce; + int remoteTokenIndex; + int _dataLengthNeeded; bool _notEnough(int offset, int ends, int needed) @@ -149,8 +151,8 @@ class IIPAuthPacket } else if (command == IIPAuthPacketCommand.Declare) { - remoteMethod = ((data[offset] >> 4) & 0x3); - localMethod = ((data[offset] >> 2) & 0x3); + remoteMethod = AuthenticationMethod.values[((data[offset] >> 4) & 0x3)]; + localMethod = AuthenticationMethod.values[((data[offset] >> 2) & 0x3)]; var encrypt = ((data[offset++] & 0x2) == 0x2); @@ -168,9 +170,9 @@ class IIPAuthPacket offset += domainLength; - if (remoteMethod == IIPAuthPacketMethod.Credentials) + if (remoteMethod == AuthenticationMethod.Credentials) { - if (localMethod == IIPAuthPacketMethod.None) + if (localMethod == AuthenticationMethod.None) { if (_notEnough(offset, ends, 33)) return -_dataLengthNeeded; @@ -191,7 +193,24 @@ class IIPAuthPacket offset += length; } } + else if (remoteMethod == AuthenticationMethod.Token) + { + if (localMethod == AuthenticationMethod.None) + { + if (_notEnough(offset, ends, 40)) + return -_dataLengthNeeded; + + remoteNonce = data.clip(offset, 32); + offset += 32; + + remoteTokenIndex = data.getUint64(offset); + offset += 8; + } + } + + + if (encrypt) { if (_notEnough(offset, ends, 2)) @@ -220,9 +239,10 @@ class IIPAuthPacket return -_dataLengthNeeded; - if (remoteMethod == IIPAuthPacketMethod.Credentials) + if (remoteMethod == AuthenticationMethod.Credentials + || remoteMethod == AuthenticationMethod.Token) { - if (localMethod == IIPAuthPacketMethod.None) + if (localMethod == AuthenticationMethod.None) { if (_notEnough(offset, ends, 32)) return -_dataLengthNeeded; diff --git a/lib/src/Net/Packets/IIPAuthPacketMethod.dart b/lib/src/Net/Packets/IIPAuthPacketMethod.dart deleted file mode 100644 index 34d4eb3..0000000 --- a/lib/src/Net/Packets/IIPAuthPacketMethod.dart +++ /dev/null @@ -1,8 +0,0 @@ - - class IIPAuthPacketMethod - { - static const int None = 0; - static const int Certificate = 1; - static const int Credentials = 2; - static const int Token = 3; - } \ No newline at end of file diff --git a/lib/src/Net/Sockets/TCPSocket.dart b/lib/src/Net/Sockets/TCPSocket.dart index 133b5f4..55eef07 100644 --- a/lib/src/Net/Sockets/TCPSocket.dart +++ b/lib/src/Net/Sockets/TCPSocket.dart @@ -23,7 +23,7 @@ SOFTWARE. */ import 'dart:io'; -import 'package:esyur/esyur.dart'; +import 'package:esiur/esiur.dart'; import 'ISocket.dart'; import '../../Data/DC.dart'; diff --git a/lib/src/Security/Authority/Authentication.dart b/lib/src/Security/Authority/Authentication.dart index 5e66256..85c90b0 100644 --- a/lib/src/Security/Authority/Authentication.dart +++ b/lib/src/Security/Authority/Authentication.dart @@ -22,12 +22,17 @@ SOFTWARE. */ +import 'AuthenticationMethod.dart'; + import 'AuthenticationType.dart'; import 'Source.dart'; class Authentication { + int tokenIndex; + AuthenticationMethod method; + String username; //Certificate certificate; String domain; diff --git a/lib/src/Security/Authority/AuthenticationMethod.dart b/lib/src/Security/Authority/AuthenticationMethod.dart new file mode 100644 index 0000000..6e6010f --- /dev/null +++ b/lib/src/Security/Authority/AuthenticationMethod.dart @@ -0,0 +1,16 @@ + + // class AuthenticationMethod + // { + // static const int None = 0; + // static const int Certificate = 1; + // static const int Credentials = 2; + // static const int Token = 3; + // } + + enum AuthenticationMethod + { + None, + Certificate, + Credentials, + Token, + } \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index ff67879..1b5ad85 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,8 @@ -name: esyur +name: esiur description: Distributed Object Framework. -version: 1.2.3 +version: 1.2.4 # author: Ahmed Zamil -homepage: https://github.com/esyur/esyur-dart +homepage: https://github.com/esiur/esiur-dart environment: sdk: ">=2.1.0 <3.0.0" diff --git a/test/main.dart b/test/main.dart index 1947c34..3c1924f 100644 --- a/test/main.dart +++ b/test/main.dart @@ -1,128 +1,42 @@ import "package:test/test.dart"; -import 'package:esyur/esyur.dart'; +import 'package:esiur/esiur.dart'; import 'dart:io'; -main() async -{ - //test("Connect to server", () async { - var now = DateTime.now(); +main() async { + test("Connect to server", () async { + // // // connect to the server + var x = await Warehouse.get("iip://localhost:5000/sys/su", + {"username": "admin", "password": "1234", "domain": "example.com"}); - // // // connect to the server - // var x = await Warehouse.get("iip://localhost:5000/sys/su", {"username": "admin", "password": "1234" - // , "domain": "example.com"}); - - - var x = await Warehouse.get("iip://gps.dijlh.com:2628/app", {"username": "delta", "password": "interactivereflection2020" - , "domain": "gps.dijlh.com"}); - - - // desc(x); - var date = DateTime.now(); - - var from =DateTime(date.year, date.month, date.day); - var to =DateTime(date.year, date.month, date.day + 1); - - List trackers = await x.getMyTrackers(); - - - - var rt = await x.getObjectTracks(trackers[0], from, to, 0, 0, 0); - - print("Time ${DateTime.now().difference(now).inSeconds}"); - - print(x.suspended); - - DistributedConnection con = x.connection; - //con.close(); - print(x.suspended); - - now = DateTime.now(); - - //await con.reconnect(); - - print("Time ${DateTime.now().difference(now).inSeconds}"); - print(x.suspended); - var u = await x.getMyTrackers(); - print(trackers[0].suspended); - - u[0].on("moved", (x){ - print("Movvvvvvvvvvvvvvvvved"); - }); - - Future.delayed(Duration(seconds: 100)); - // for(var i = 0; i < trackers.length; i++) - // print(trackers[i].name); - - // var arc = await x.getObjectTracks(trackers[1], DateTime.now().subtract(Duration(days: 6)), DateTime.now()); - - // x.instance.store.on("close", (x){ - // print("Closed"); - // }); - - // x.on("modified", (peoperty, value){ - - // }); - - // var users = await x.Users.Slice(0, 10); - - // print(users); - // await sleep(Duration(seconds: 10)); - - // get property - //print(x.Level); - // listen to event - //x.on("LevelUp", (v,y,z)=>print("Level up ${v} ${y}${z}")); - // use await - //print("Added successfully ${await x.Add(40)}"); - // use named arguments - //print(await x.Add(value: 20)); - // test chunks - //x.Stream(10).chunk((c)=>print(c)); - // property setter - //x.Level += 900; - - - //var msg = await stdin.readLineSync(); - - //print("Done"); - - //}); - - + print(x); + }); } - - // describe object - desc(dynamic x) { - if (x is List) - { - for(var i = 0; i < x.length; i++) - desc(x[i]); - } - else if (x is DistributedResource) - { - var y = x.instance.template; - print("Fucntions = ${y.functions.length}\n"); - for (var i = 0; i < y.functions.length; i++) { - print("Function ${y.functions[i].name} ${y.functions[i].expansion}"); - } - print("------------------------------\n"); - print("Events = ${y.events.length}\n"); - for (var i = 0; i < y.events.length; i++) { - print("Events ${y.events[i].name} ${y.events[i].expansion}"); - } +desc(dynamic x) { + if (x is List) { + for (var i = 0; i < x.length; i++) desc(x[i]); + } else if (x is DistributedResource) { + var y = x.instance.template; + print("Fucntions = ${y.functions.length}\n"); + for (var i = 0; i < y.functions.length; i++) { + print("Function ${y.functions[i].name} ${y.functions[i].expansion}"); + } + print("------------------------------\n"); + print("Events = ${y.events.length}\n"); + for (var i = 0; i < y.events.length; i++) { + print("Events ${y.events[i].name} ${y.events[i].expansion}"); + } - print("------------------------------\n"); - print("Properties = ${y.properties.length}\n"); - for (var i = 0; i < y.properties.length; i++) { - print("Property ${y.properties[i].name} ${y.properties[i].readExpansion}"); - // recursion - //print("value = ${desc(x.get(y.properties[i].index))}"); - } - } - else - { - print(x.toString()); - } -} \ No newline at end of file + print("------------------------------\n"); + print("Properties = ${y.properties.length}\n"); + for (var i = 0; i < y.properties.length; i++) { + print( + "Property ${y.properties[i].name} ${y.properties[i].readExpansion}"); + // recursion + //print("value = ${desc(x.get(y.properties[i].index))}"); + } + } else { + print(x.toString()); + } +}