Add ApplicationContext, AuthenticatedUser

This commit is contained in:
Harald Wolff 2019-09-02 07:21:16 +02:00
parent 0eb79e7cf1
commit 33e0cf1616
4 changed files with 171 additions and 2 deletions

View file

@ -8,6 +8,7 @@ using ln.types;
using System.Net;
using ln.application.service;
using ln.http.resources;
using ln.types.btree;
namespace ln.application
{
@ -21,6 +22,11 @@ namespace ln.application
public MemoryLogger MemoryLogger { get; }
public int ApplicationContextTimeout { get; set; } = 1200;
MappingBTree<Guid, ApplicationContext> applicationContexts = new MappingBTree<Guid, ApplicationContext>((x)=>x.ContextID);
public Application()
{
MemoryLogger = new MemoryLogger(8192);
@ -89,12 +95,53 @@ namespace ln.application
HttpServer.Stop();
}
public virtual ApplicationContext CreateApplicationContext() => new ApplicationContext(this);
public ApplicationContext GetApplicationContext() => GetApplicationContext(Guid.Empty);
public ApplicationContext GetApplicationContext(Guid contextID)
{
ApplicationContext applicationContext;
if (Guid.Empty.Equals(contextID))
{
while (true)
{
applicationContext = CreateApplicationContext();
if (!applicationContexts.ContainsKey(applicationContext.ContextID))
{
applicationContexts.Add(applicationContext);
break;
}
}
}
else
{
if (!applicationContexts.ContainsKey(contextID))
throw new KeyNotFoundException();
applicationContext = applicationContexts[contextID];
}
return applicationContext;
}
public virtual AuthenticatedUser AuthenticateUser(string username,object prove)
{
return null;
}
public void CleanupApplicationContexts()
{
foreach (ApplicationContext applicationContext in applicationContexts.ToArray())
{
if (applicationContext.Untouched > TimeSpan.FromSeconds(ApplicationContextTimeout))
applicationContexts.RemoveKey(applicationContext.ContextID);
}
}
/*
/*
* Plugin Classes
*/
Dictionary<Type, List<object>> pluginInstances = new Dictionary<Type, List<object>>();
Dictionary<Type, List<object>> pluginInstances = new Dictionary<Type, List<object>>();
public void RegisterPluginInstance<PC>(PC pluginInstance) => RegisterPluginInstance(typeof(PC),pluginInstance);
public void RegisterPluginInstance(Type type,object pluginInstance)

56
ApplicationContext.cs Normal file
View file

@ -0,0 +1,56 @@
using System;
using System.Threading;
namespace ln.application
{
public class ApplicationContext
{
static ThreadLocal<ApplicationContext> currentApplicationContext = new ThreadLocal<ApplicationContext>();
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;
}
}
}

64
AuthenticatedUser.cs Normal file
View file

@ -0,0 +1,64 @@
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<string> roles = new HashSet<string>();
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<string> 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;
}
}
}

View file

@ -37,6 +37,8 @@
<Compile Include="service\ServiceContainer.cs" />
<Compile Include="service\ApplicationServiceBase.cs" />
<Compile Include="ApplicationWebSocket.cs" />
<Compile Include="ApplicationContext.cs" />
<Compile Include="AuthenticatedUser.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ln.types\ln.types.csproj">