From 0be67ce4a1b9bc68cf42df74beec8f567ad7d84e Mon Sep 17 00:00:00 2001 From: Harald Wolff Date: Fri, 15 Nov 2019 13:46:08 +0100 Subject: [PATCH] Authentication Alpha --- Application.cs | 69 +++++++++---- ApplicationContext.cs | 56 ----------- ApplicationSession.cs | 90 +++++++++++++++++ ApplicationWebSocket.cs | 96 +++++++++---------- AuthenticatedUser.cs | 64 ------------- ln.application.csproj | 7 +- ln.application.demo/ApplicationDemo.cs | 18 +++- ln.application.demo/DemoIdentityProvider.cs | 31 ++++++ .../ln.application.demo.csproj | 5 + ln.application.sln | 6 ++ service/ApplicationServiceBase.cs | 18 ++-- service/ServiceDefinition.cs | 4 +- www | 2 +- 13 files changed, 255 insertions(+), 211 deletions(-) delete mode 100644 ApplicationContext.cs create mode 100644 ApplicationSession.cs delete mode 100644 AuthenticatedUser.cs create mode 100644 ln.application.demo/DemoIdentityProvider.cs diff --git a/Application.cs b/Application.cs index 4785c60..3efe93d 100644 --- a/Application.cs +++ b/Application.cs @@ -11,16 +11,17 @@ using ln.http.resources; using ln.types.btree; using ln.types.rpc; using ln.application.slots; +using ln.identities; +using ln.http.session; namespace ln.application { - public class Application : IApplicationInterface + public class Application : ResourceApplication { public ArgumentContainer Arguments { get; protected set; } public HTTPServer HttpServer { get; private set; } public ServiceContainer ServiceContainer { get; } - public ResourceApplication HTTPApplication { get; private set; } public MemoryLogger MemoryLogger { get; } @@ -29,22 +30,30 @@ namespace ln.application public RPCContainer RPCContainer { get; } = new RPCContainer(); public BinarySlotContainer BinarySlots { get; } = new BinarySlotContainer(); + public IIdentityProvider IdentityProvider { get; protected set; } - MappingBTree applicationContexts = new MappingBTree((x)=>x.ContextID); + MappingBTree applicationSessions = new MappingBTree((x)=>x.SessionID); - public Application() + public Application(IIdentityProvider identityProvider,RPCContainer rpcContainer) { + IdentityProvider = identityProvider; + RPCContainer = rpcContainer; + MemoryLogger = new MemoryLogger(8192); Logger.Default.Backends.Add(MemoryLogger); Arguments = new ArgumentContainer() .Add((char)0, "log-level", "INFO") - .Add('l', "http-listen","0.0.0.0") + .Add('l', "http-listen", "0.0.0.0") .Add('p', "http-port", "8080"); ServiceContainer = new ServiceContainer(this); } + + public Application() :this(null,new RPCContainer()) { } + public Application(IIdentityProvider identityProvider) : this(identityProvider,new RPCContainer()) { } + public virtual void PrepareStart() { } @@ -68,8 +77,9 @@ namespace ln.application )); HttpServer.Start(); - HTTPApplication = new ResourceApplication(); - HttpServer.DefaultApplication = HTTPApplication; + HttpServer.DefaultApplication = this; + + RootResource = new BaseResource(""); /* Application Services */ @@ -100,45 +110,64 @@ namespace ln.application HttpServer.Stop(); } - public virtual ApplicationContext CreateApplicationContext() => new ApplicationContext(this); + public virtual ApplicationSession CreateApplicationSession() => new ApplicationSession(this); + public ApplicationSession GetApplicationSession(Session session) + { + ApplicationSession applicationSession = session.Get("LNApplicationSession"); + if (applicationSession == null) + { + applicationSession = CreateApplicationSession(); + applicationSessions.Add(applicationSession); + session["LNApplicationSession"] = applicationSession; + } - public ApplicationContext GetApplicationContext() => GetApplicationContext(Guid.Empty); - public ApplicationContext GetApplicationContext(Guid contextID) + return applicationSession; + } + + public ApplicationSession GetApplicationSession() => GetApplicationSession(Guid.Empty); + public ApplicationSession GetApplicationSession(Guid contextID) { - ApplicationContext applicationContext; + ApplicationSession applicationSession; if (Guid.Empty.Equals(contextID)) { while (true) { - applicationContext = CreateApplicationContext(); - if (!applicationContexts.ContainsKey(applicationContext.ContextID)) + applicationSession = CreateApplicationSession(); + if (!applicationSessions.ContainsKey(applicationSession.SessionID)) { - applicationContexts.Add(applicationContext); + applicationSessions.Add(applicationSession); break; } } } else { - if (!applicationContexts.ContainsKey(contextID)) + if (!applicationSessions.ContainsKey(contextID)) throw new KeyNotFoundException(); - applicationContext = applicationContexts[contextID]; + applicationSession = applicationSessions[contextID]; } - return applicationContext; + return applicationSession; } - public virtual AuthenticatedUser AuthenticateUser(string username,object prove) + public virtual object ProcessMessage(object message) + { + //Application.BinarySlots.RequestSlot(message as SlotRequest); + return null; + } + + + public virtual Identity Authenticate(string username,object prove) { return null; } public void CleanupApplicationContexts() { - foreach (ApplicationContext applicationContext in applicationContexts.ToArray()) + foreach (ApplicationSession applicationContext in applicationSessions.ToArray()) { if (applicationContext.Untouched > TimeSpan.FromSeconds(ApplicationContextTimeout)) - applicationContexts.RemoveKey(applicationContext.ContextID); + applicationSessions.RemoveKey(applicationContext.SessionID); } } diff --git a/ApplicationContext.cs b/ApplicationContext.cs deleted file mode 100644 index 2fd08c1..0000000 --- a/ApplicationContext.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Threading; -namespace ln.application -{ - public class ApplicationContext - { - static ThreadLocal currentApplicationContext = new ThreadLocal(); - public static void SetCurrentContext(ApplicationContext applicationContext) => currentApplicationContext.Value = applicationContext; - public static void ClearCurrentContext() => currentApplicationContext.Value = null; - - public Guid ContextID { get; } - public DateTime Created { get; } - public DateTime LastAccess { get; protected set; } - - public TimeSpan Age => LastAccess - Created; - public TimeSpan Untouched => DateTime.Now - LastAccess; - - public Application Application { get; } - public AuthenticatedUser CurrentUser { get; protected set; } - - - public ApplicationContext(Application application) - { - ContextID = Guid.NewGuid(); - Created = DateTime.Now; - LastAccess = Created; - - Application = application; - CurrentUser = AuthenticatedUser.Anonymous; - } - - protected void UpdateLastAccess() - { - LastAccess = DateTime.Now; - } - - public virtual bool AuthenticateUser(string username,object prove) - { - AuthenticatedUser authenticatedUser = Application.AuthenticateUser(username, prove); - if (authenticatedUser != null) - { - CurrentUser = authenticatedUser; - return true; - } - else - { - CurrentUser = AuthenticatedUser.Anonymous; - return false; - } - } - public virtual void DeauthenticateUser() - { - CurrentUser = AuthenticatedUser.Anonymous; - } - } -} diff --git a/ApplicationSession.cs b/ApplicationSession.cs new file mode 100644 index 0000000..3bc9ef8 --- /dev/null +++ b/ApplicationSession.cs @@ -0,0 +1,90 @@ +using System; +using System.Threading; +using ln.identities; +using ln.types.rpc; +using System.Collections.Generic; +using ln.logging; +using ln.json; +using ln.json.mapping; +namespace ln.application +{ + public class ApplicationSession : IDisposable + { + static ThreadLocal currentApplicationSession = new ThreadLocal(); + public static void SetCurrentSession(ApplicationSession applicationSession) => currentApplicationSession.Value = applicationSession; + public static void ClearCurrentSession() => currentApplicationSession.Value = null; + public static ApplicationSession CurrentSession => currentApplicationSession.Value; + + public Guid SessionID { get; } + public DateTime Created { get; } + public DateTime LastAccess { get; protected set; } + + public TimeSpan Age => LastAccess - Created; + public TimeSpan Untouched => DateTime.Now - LastAccess; + + public Application Application { get; } + public Identity SessionIdentity { get; protected set; } + + public ApplicationSession(Application application) + { + SessionID = Guid.NewGuid(); + Created = DateTime.Now; + LastAccess = Created; + + Application = application; + SessionIdentity = null; + + Logging.Log(LogLevel.DEBUG, "ApplicationSession created: {0}",SessionID); + } + + protected void UpdateLastAccess() + { + LastAccess = DateTime.Now; + } + + public virtual object ProcessMessage(object message) + { + if (message is RPCCall rpcCall) + { + return Application.RPCContainer.Invoke(rpcCall); + } else if (message is AuthenticationRequest authenticationRequest) + { + Identity identity = Application.IdentityProvider.GetIdentity(authenticationRequest.IdentityName); + SecureAttribute[] secureAttributes = identity.GetSecureAttributes(authenticationRequest.SecureAttributeTypeName); + AuthenticationChallenges authenticationChallenges = new AuthenticationChallenges(secureAttributes); + return authenticationChallenges; + } else if (message is AuthenticationProve authenticationProve) + { + Identity identity = Application.IdentityProvider.GetIdentity(authenticationProve.IdentityName); + SecureAttribute secureAttribute = identity.GetSecureAttribute(authenticationProve.SecureAttributeUniqueID); + if (secureAttribute.Authenticate(authenticationProve.Challenge, authenticationProve.Prove)) + { + SessionIdentity = identity; + JSONObject r = new JSONObject(); + r.Add("UniqueID", JSONMapper.DefaultMapper.ToJson(identity.UniqueID)); + r.Add("IdentityName", JSONMapper.DefaultMapper.ToJson(identity.IdentityName)); + return r; + } + else + { + throw new ArgumentException(); + } + + throw new KeyNotFoundException(); + } + + return null; + } + + public virtual void DeauthenticateUser() + { + SessionIdentity = null; + } + + public virtual void Dispose() + { + Logging.Log(LogLevel.DEBUG, "ApplicationSession disposing: {0}", SessionID); + DeauthenticateUser(); + } + } +} diff --git a/ApplicationWebSocket.cs b/ApplicationWebSocket.cs index 4e2e657..09f0e39 100644 --- a/ApplicationWebSocket.cs +++ b/ApplicationWebSocket.cs @@ -6,28 +6,33 @@ using ln.types.rpc; using ln.http; using System.Collections.Generic; using ln.application.slots; +using ln.json.mapping; +using ln.identities; namespace ln.application { public class ApplicationWebSocket : WebSocket { - public IApplicationInterface ApplicationInterface { get; } + static Dictionary> messageConverters = new Dictionary>(); + static public void RegisterMessageConverter(string messageType, Func converter) => messageConverters[messageType] = converter; + static public Func FindConverter(string messageType) => messageConverters[messageType]; - Dictionary> messageConverters = new Dictionary>(); + public Application Application { get; } + public ApplicationSession ApplicationSession => Application.GetApplicationSession(); - public ApplicationWebSocket(IApplicationInterface applicationInterface,HttpRequest httpRequest) - :base(httpRequest) - { - ApplicationInterface = applicationInterface; - } - public void AddMessageConverter(string messageType, Func converter) + static ApplicationWebSocket() { - messageConverters[messageType] = converter; + RegisterMessageConverter("RPCCall", (JSONValue json) => JSONMapper.DefaultMapper.FromJson(json, typeof(RPCCall))); + RegisterMessageConverter("SlotRequest", (JSONValue json) => JSONMapper.DefaultMapper.FromJson(json, typeof(SlotRequest))); + RegisterMessageConverter("AuthenticationProve", (JSONValue json) => JSONMapper.DefaultMapper.FromJson(json, typeof(AuthenticationProve))); + RegisterMessageConverter("AuthenticationRequest", (JSONValue json) => JSONMapper.DefaultMapper.FromJson(json, typeof(AuthenticationRequest))); } - public Func FindConverter(string messageType) + + public ApplicationWebSocket(Application application, HttpRequest httpRequest) + : base(httpRequest) { - return messageConverters[messageType]; + Application = application; } public override bool Received(string textMessage) @@ -59,27 +64,41 @@ namespace ln.application try { object convertedMessage = FindConverter(messageType)(message); - return ReceivedMessage(messageId, messageType, convertedMessage); + ReceivedMessage(messageId, messageType, convertedMessage); + + return true; } catch (Exception e) { Logging.Log(e); - SendError(messageId, e.ToString(), e.InnerException.ToString()); + SendError(messageId, e.ToString(), e.InnerException?.ToString()); return false; } } - public virtual bool ReceivedMessage(long messageId, string messageType, object message) + public virtual void ReceivedMessage(long messageId, string messageType, object message) { - switch (messageType) + ApplicationSession.SetCurrentSession(ApplicationSession); + + try { - case "RPCCall": - SendMessage(messageId, ApplicationInterface.RPCContainer.Invoke(message as RPCCall)); - return true; - case "SlotRequest": - SlotAllocation slotAllocation = ApplicationInterface.BinarySlots.RequestSlot(message as SlotRequest); - return true; - default: - return false; + object result = ApplicationSession?.ProcessMessage(message); + if (result is null) + { + result = Application.ProcessMessage(message); + } + if (result is null) + { + throw new NotImplementedException(); + } + + SendMessage(messageId, result); + } catch (Exception e) + { + SendError(messageId, e.ToString(), e.InnerException?.ToString()); + } + finally + { + ApplicationSession.ClearCurrentSession(); } } @@ -91,7 +110,7 @@ namespace ln.application public void SendMessage(long messageID, object message) { string messageType = message.GetType().Name; - JSONObject jsonMessage = JSONObject.From(message); + JSONObject jsonMessage = message is JSONObject ? message as JSONObject : JSONObject.From(message); SendMessage(messageID, messageType, jsonMessage); } @@ -117,35 +136,6 @@ namespace ln.application SendMessage(messageId, "error", failed); } - public void a() - { - try - { - Logging.Log(LogLevel.DEBUGDETAIL, "ApplicationWebSocket: Received: {0}",textMessage); - JSONObject json = (JSONObject)JSONParser.Parse(textMessage); - RPCCall rpcCall = json.ToObject(); - - requestContext.HttpRequest.HTTPServer.ThreadPool.Enqueue(() => - { - RPCResult rpcResult = Invoke(rpcCall); - string resultText = JSONObject.From(rpcResult).ToString(); - - Logging.Log(LogLevel.DEBUGDETAIL, "ApplicationWebSocket: Sending: {0}", resultText); - requestContext.WebSocket.Send(resultText); - }); - } - catch (Exception e) - { - Logging.Log(e); - } - } - - public virtual RPCResult Invoke(RPCCall call) - { - RPCResult result = null; - result = ApplicationInterface.RPCContainer.Invoke(call); - return result; - } } } diff --git a/AuthenticatedUser.cs b/AuthenticatedUser.cs deleted file mode 100644 index 7cbbaf3..0000000 --- a/AuthenticatedUser.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Security.Cryptography; -namespace ln.application -{ - public class AuthenticatedUser - { - public static AuthenticatedUser Anonymous { get; } = new AuthenticatedUser(); - - public Guid ID { get; } - public string Name { get; } - - public byte[] SecretHash { get; set; } - - public int Token { get; set; } - - public string[] Roles => Roles.ToArray(); - - - HashSet roles = new HashSet(); - - public AuthenticatedUser() - { - ID = Guid.Empty; - Name = "Anonymous"; - } - - public AuthenticatedUser(Guid userID, string name) : this(userID, name, new string[0]) { } - public AuthenticatedUser(Guid userID, string name, IEnumerable userRoles) - { - ID = userID; - Name = name; - foreach (string role in userRoles) - roles.Add(role); - } - - public bool HasRole(string role) => roles.Contains(role); - - public void SetSecret(string secret) - { - byte[] secretBytes = Encoding.UTF8.GetBytes(secret); - SHA256 sha256 = SHA256.Create(); - sha256.ComputeHash(secretBytes); - - SecretHash = sha256.Hash; - } - - public override int GetHashCode() - { - return ID.GetHashCode(); - } - public override bool Equals(object obj) - { - if (obj is AuthenticatedUser) - { - AuthenticatedUser other = obj as AuthenticatedUser; - return ID.Equals(other.ID); - } - return false; - } - } -} diff --git a/ln.application.csproj b/ln.application.csproj index fbd815e..1ff1246 100644 --- a/ln.application.csproj +++ b/ln.application.csproj @@ -37,8 +37,7 @@ - - + @@ -65,6 +64,10 @@ {D9342117-3249-4D8B-87C9-51A50676B158} ln.json + + {AA1F75AF-0AEC-4CC0-AC3B-209AE90781AC} + ln.identities + diff --git a/ln.application.demo/ApplicationDemo.cs b/ln.application.demo/ApplicationDemo.cs index 6988846..87582a2 100644 --- a/ln.application.demo/ApplicationDemo.cs +++ b/ln.application.demo/ApplicationDemo.cs @@ -12,10 +12,17 @@ using ln.http.resources; using ln.application.service; using ln.http; using ln.http.listener; +using ln.http.resources.websocket; namespace ln.application.demo { public class ApplicationDemo : Application { + + public ApplicationDemo() + :base(new DemoIdentityProvider()) + { + } + public override void PrepareStart() { base.PrepareStart(); @@ -29,17 +36,20 @@ namespace ln.application.demo public ApplicationService() : base("core") { } - public override void ServiceMain(IApplicationInterface applicationInterface) + public override void ServiceMain(Application application) { - DirectoryResource directoryResource = new DirectoryResource(new string[] { "../../www", "www" }); + DirectoryResource directoryResource = new DirectoryResource(new string[] { "../../../www", "www" }); directoryResource.DefaultResource = directoryResource.GetResource("demo.html"); directoryResource.FallBackResource = directoryResource.DefaultResource; - CurrentApplicationInterface.HTTPApplication.RootResource = directoryResource; + CurrentApplication.RootResource = directoryResource; + + WebsocketResource websocketResource = new WebsocketResource(null, "socket", (HttpRequest arg) => new ApplicationWebSocket((Application)this.CurrentApplication, arg)); + directoryResource.InjectResource(websocketResource); //applicationInterface.HttpServer.AddListener(new HttpsListener(8443)); - base.ServiceMain(applicationInterface); + base.ServiceMain(application); } diff --git a/ln.application.demo/DemoIdentityProvider.cs b/ln.application.demo/DemoIdentityProvider.cs new file mode 100644 index 0000000..e7e4805 --- /dev/null +++ b/ln.application.demo/DemoIdentityProvider.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using ln.identities; +using System.Linq; +namespace ln.application.demo +{ + public class DemoIdentityProvider : BaseIdentityProvider + { + Dictionary identities = new Dictionary(); + + public DemoIdentityProvider() + { + Identity demoIdentity = new Identity("demo"); + demoIdentity.AddSecureAttribute(new SeededPassword("demopass")); + + identities.Add(demoIdentity.UniqueID,demoIdentity); + } + + public override Identity CreateIdentity(string identityName) + { + Identity identity = new Identity(identityName); + identities.Add(identity.UniqueID, identity); + return identity; + } + + public override IEnumerable> GetIdentities() => identities.Select((arg) => new KeyValuePair(arg.Key,arg.Value.IdentityName)); + public override Identity GetIdentity(Guid uniqueID) => identities[uniqueID]; + + public override bool Save(Identity identity) => true; + } +} diff --git a/ln.application.demo/ln.application.demo.csproj b/ln.application.demo/ln.application.demo.csproj index 315b530..8401a21 100644 --- a/ln.application.demo/ln.application.demo.csproj +++ b/ln.application.demo/ln.application.demo.csproj @@ -33,6 +33,7 @@ + @@ -63,6 +64,10 @@ {8D9AB9A5-E513-4BA7-A450-534F6456BF28} ln.types + + {AA1F75AF-0AEC-4CC0-AC3B-209AE90781AC} + ln.identities + diff --git a/ln.application.sln b/ln.application.sln index 1528e81..37a80c5 100644 --- a/ln.application.sln +++ b/ln.application.sln @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.types", "..\ln.types\ln. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.application.demo", "ln.application.demo\ln.application.demo.csproj", "{2CBEE2D5-C4D4-4DBD-8AA4-B54E99812808}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.identities", "..\ln.identities\ln.identities.csproj", "{AA1F75AF-0AEC-4CC0-AC3B-209AE90781AC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -55,5 +57,9 @@ Global {2CBEE2D5-C4D4-4DBD-8AA4-B54E99812808}.Debug|Any CPU.Build.0 = Debug|Any CPU {2CBEE2D5-C4D4-4DBD-8AA4-B54E99812808}.Release|Any CPU.ActiveCfg = Release|Any CPU {2CBEE2D5-C4D4-4DBD-8AA4-B54E99812808}.Release|Any CPU.Build.0 = Release|Any CPU + {AA1F75AF-0AEC-4CC0-AC3B-209AE90781AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AA1F75AF-0AEC-4CC0-AC3B-209AE90781AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA1F75AF-0AEC-4CC0-AC3B-209AE90781AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AA1F75AF-0AEC-4CC0-AC3B-209AE90781AC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/service/ApplicationServiceBase.cs b/service/ApplicationServiceBase.cs index 306b74b..bb85322 100644 --- a/service/ApplicationServiceBase.cs +++ b/service/ApplicationServiceBase.cs @@ -22,7 +22,7 @@ namespace ln.application.service public string ServiceStateText { get; protected set; } - public IApplicationInterface CurrentApplicationInterface { get; protected set; } + public Application CurrentApplication { get; protected set; } public Type[] DependingServiceTypes => dependingServiceTypes.ToArray(); HashSet dependingServiceTypes = new HashSet(); @@ -42,14 +42,14 @@ namespace ln.application.service public T Dependency() where T : ApplicationServiceBase { - T serviceBase = (T)CurrentApplicationInterface.ServiceContainer[typeof(T)].ServiceBase; + T serviceBase = (T)CurrentApplication.ServiceContainer[typeof(T)].ServiceBase; if (serviceBase == null) throw new EntryPointNotFoundException(String.Format("depending service not found: {0}",typeof(T).ToString())); return serviceBase; } - public virtual void ServiceMain(IApplicationInterface applicationInterface) + public virtual void ServiceMain(Application application) { Ready(); while (!StopRequested) @@ -61,19 +61,19 @@ namespace ln.application.service } } - public virtual bool Start(IApplicationInterface applicationInterface, String[] arguments) + public virtual bool Start(Application application, String[] arguments) { if (IsAlive) throw new NotSupportedException("Service is already alive"); - CurrentApplicationInterface = applicationInterface; + CurrentApplication = application; foreach (Type dep in dependingServiceTypes) { - ServiceDefinition depService = CurrentApplicationInterface.ServiceContainer[dep]; + ServiceDefinition depService = CurrentApplication.ServiceContainer[dep]; if (!depService.IsAlive) { - CurrentApplicationInterface.ServiceContainer.Start(depService); + CurrentApplication.ServiceContainer.Start(depService); if (!depService.IsAlive) { Logging.Log(LogLevel.ERROR, "service {0} could not start depending service {1}", ServiceName, depService.ServiceClassName); @@ -97,7 +97,7 @@ namespace ln.application.service ready = false; StopRequested = false; - ServiceThread = new Thread(() => ServiceMain(applicationInterface)); + ServiceThread = new Thread(() => ServiceMain(application)); ServiceThread.Start(); return true; @@ -131,7 +131,7 @@ namespace ln.application.service } if (!ServiceThread.IsAlive) - CurrentApplicationInterface = null; + CurrentApplication = null; ready = false; return !ServiceThread.IsAlive; diff --git a/service/ServiceDefinition.cs b/service/ServiceDefinition.cs index 5e74ca3..9d73d54 100644 --- a/service/ServiceDefinition.cs +++ b/service/ServiceDefinition.cs @@ -75,14 +75,14 @@ namespace ln.application.service serviceType = null; serviceAssembly = null; } - public void Start(IApplicationInterface applicationInterface) + public void Start(Application application) { if (!IsLoaded) Load(); Logging.Log(LogLevel.INFO, "service: starting {0} [{1}]", ServiceClassName, FinalAssembly.GetName().Name); - if (ServiceBase.Start(applicationInterface,new string[0])) + if (ServiceBase.Start(application,new string[0])) Logging.Log(LogLevel.INFO, "service: started {0} [{1}]", ServiceClassName, FinalAssembly.GetName().Name); else Logging.Log(LogLevel.ERROR, "service: failed {0} [{1}]", ServiceClassName, FinalAssembly.GetName().Name); diff --git a/www b/www index d1663cb..6815c42 160000 --- a/www +++ b/www @@ -1 +1 @@ -Subproject commit d1663cbbbe0d91631c4bd6b7b0f7228621329705 +Subproject commit 6815c42b253152f120fd74a1f0cdc0bebf071547