ln.provider/ProviderApplication.cs

179 lines
4.6 KiB
C#

using System;
using ln.application;
using ln.application.service;
using System.Threading;
using ln.http.resources;
using System.IO;
using ln.types.rpc;
using ln.types.odb.ng;
using ln.types.odb.ng.storage;
using System.Security.Cryptography;
using System.Linq;
using ln.types;
namespace ln.provider
{
public class ProviderApplication : Application
{
public String ServerString { get; private set; }
public String WWWPath { get; private set; } = "www";
public ResourceApplication WWWApplication { get; private set; }
public RPCContainer RPCContainer { get; private set; }
public ProviderApplication()
{
ServerString = "ln.provider(0.1)";
RPCContainer = new RPCContainer();
if (Directory.Exists("../../www"))
WWWPath = "../../www";
ServiceDefinition coreRPCService = new ServiceDefinition("ln.provider.CoreService");
coreRPCService.AutoStart = true;
ServiceContainer.Add(
coreRPCService
);
}
public override void PrepareStart()
{
DirectoryResource www = new DirectoryResource(new string[] { "../../www", "www" });
www.DefaultResource = www.GetResource("index.html");
ApplicationWebSocket applicationWebSocket = new ApplicationWebSocket(null, "socket", RPCContainer);
www.InjectResource(applicationWebSocket);
WWWApplication = new ResourceApplication();
WWWApplication.RootResource = www;
}
public override AuthenticatedUser AuthenticateUser(string username, object prove)
{
CoreService coreService = ServiceContainer[typeof(CoreService)].ServiceBase as CoreService;
String[] tokens = prove.ToString().Split(':');
int token = int.Parse(tokens[0]);
AuthenticatedUser authenticatedUser = coreService.Authenticate(username, token, tokens[1]);
return authenticatedUser;
}
}
public class CoreService : ApplicationServiceBase
{
public ProviderApplication Application => (ProviderApplication)base.CurrentApplicationInterface;
public IStorageContainer CoreStorageContainer { get; private set; }
public Session CoreStorageSession { get; private set; }
public Mapper CoreStorageMapper { get; private set; }
public CoreService()
:base(nameof(CoreService))
{
}
public override void ServiceMain(IApplicationInterface applicationInterface)
{
CoreStorageContainer = new FSStorageContainer("/var/cache/ln.provider");
CoreStorageContainer.Open();
CoreStorageSession = new Session(CoreStorageContainer);
CoreStorageMapper = new Mapper(CoreStorageSession);
CoreStorageMapper.EnsureIndex<AuthenticatedUser>("ID");
CoreStorageMapper.EnsureIndex<AuthenticatedUser>("Name");
Application.HttpServer.DefaultApplication = Application.WWWApplication;
Application.RPCContainer.Add("core",new RPC(Application));
while (!StopRequested)
{
lock (this)
{
Monitor.Wait(this);
}
}
CoreStorageMapper = null;
CoreStorageSession.Dispose();
CoreStorageSession = null;
CoreStorageContainer.Dispose();
CoreStorageContainer = null;
}
public AuthenticatedUser Authenticate(string username,int token,string secretHash)
{
AuthenticatedUser authenticatedUser = CoreStorageMapper.Load<AuthenticatedUser>(Query.Equals<AuthenticatedUser>("Name", username)).FirstOrDefault();
if (authenticatedUser != null)
{
if (token <= authenticatedUser.Token)
return null;
authenticatedUser.Token = token;
CoreStorageMapper.Save<AuthenticatedUser>(authenticatedUser);
byte[] secretHashBytes = Extensions.BytesFromHexString(secretHash);
SHA256 sha256 = SHA256.Create();
sha256.TransformBlock(token.GetBytes(), 0, 4, null, 0);
sha256.TransformFinalBlock(authenticatedUser.SecretHash, 0, authenticatedUser.SecretHash.Length);
if (sha256.Hash.AreEqual(secretHashBytes))
return authenticatedUser;
return null;
}
return null;
}
class RPC
{
ProviderApplication providerApplication;
public RPC(ProviderApplication providerApplication)
{
this.providerApplication = providerApplication;
}
public String GetServerString()
{
return providerApplication.ServerString;
}
public void Shutdown()
{
ThreadPool.QueueUserWorkItem((state) => providerApplication.Stop());
}
public bool Authenticate(string username,string secretHash)
{
return false;
}
public Guid GetApplicationContext(string contextID)
{
Guid id;
if (string.Empty.Equals(contextID))
id = Guid.Empty;
else
id = Guid.Parse(contextID);
ApplicationContext applicationContext = providerApplication.GetApplicationContext(id);
ApplicationContext.SetCurrentContext(applicationContext);
return applicationContext.ContextID;
}
}
}
}