Admin panel login system is working.

This commit is contained in:
Michael 2017-02-11 20:40:40 -05:00
parent 263ee283de
commit 118174ec13
8 changed files with 244 additions and 29 deletions

View file

@ -7,9 +7,11 @@ using Nancy;
using Nancy.Authentication.Forms;
using Nancy.Bootstrapper;
using Nancy.Hosting.Self;
using Nancy.ModelBinding;
using Nancy.Security;
using Nancy.TinyIoc;
using Newtonsoft.Json;
using ShiftOS.Objects;
namespace ShiftOS.Server.WebAdmin
{
@ -20,7 +22,7 @@ namespace ShiftOS.Server.WebAdmin
var HostConf = new HostConfiguration();
HostConf.UrlReservations.CreateAutomatically = true;
using(var nancy = new NancyHost(HostConf, new Uri("http://localhost:13371/mudadmin")))
using(var nancy = new NancyHost(HostConf, new Uri("http://localhost:13371/mudadmin/")))
{
nancy.Start();
Console.WriteLine($"[{DateTime.Now}] <AdminPanel/NancyInit> Initiating on localhost:13371...");
@ -31,15 +33,37 @@ namespace ShiftOS.Server.WebAdmin
public static class PageBuilder
{
public static string Build(string page)
public static string Build(string page, Dictionary<string, string> templateParams = null)
{
string templatehtml = Properties.Resources.HtmlTemplate;
if (templateParams == null)
{
templateParams = new Dictionary<string, string>();
}
if (!templateParams.ContainsKey("{logout}"))
{
templateParams.Add("{logout}", "<li><a href=\"/mudadmin/logout\">Log out</a></li>");
}
switch (page)
{
case "status":
templatehtml = templatehtml.Replace("{body}", Properties.Resources.Status);
break;
case "login":
templatehtml = templatehtml.Replace("{body}", Properties.Resources.LoginView);
break;
case "initialsetup":
templatehtml = templatehtml.Replace("{body}", Properties.Resources.SetupView);
break;
}
try
{
foreach (var param in templateParams)
{
templatehtml = templatehtml.Replace(param.Key, param.Value);
}
}
catch { }
return templatehtml;
}
}
@ -98,6 +122,40 @@ namespace ShiftOS.Server.WebAdmin
return false;
}
public static string GetCPWorth()
{
if (System.IO.Directory.Exists("saves"))
{
int cp = 0;
foreach(var file in System.IO.Directory.GetFiles("saves"))
{
if (file.EndsWith(".save"))
{
var save = JsonConvert.DeserializeObject<Save>(Server.Program.ReadEncFile(file));
cp += save.Codepoints;
}
}
return cp.ToString();
}
else
{
return "0";
}
}
public static string GetUserCount()
{
if (System.IO.Directory.Exists("saves"))
{
return System.IO.Directory.GetFiles("saves").Length.ToString();
}
else
{
return "0";
}
}
public static MudUserIdentity GetIdentity(Guid id)
{
foreach (var user in JsonConvert.DeserializeObject<List<MudUser>>(ShiftOS.Server.Program.ReadEncFile("users.json")))
@ -146,7 +204,20 @@ namespace ShiftOS.Server.WebAdmin
{
Get["/login"] = parameters =>
{
return PageBuilder.Build("login");
if (System.IO.File.Exists("users.json"))
{
return PageBuilder.Build("login", new Dictionary<string, string>
{
{"{logout}", "" }
});
}
else
{
return PageBuilder.Build("initialsetup", new Dictionary<string, string>
{
{"{logout}", "" }
});
}
};
Get["/logout"] = parameters =>
@ -156,28 +227,53 @@ namespace ShiftOS.Server.WebAdmin
Post["/login"] = parameters =>
{
var p = this.Bind<LoginRequest>();
Guid id = new Guid();
if (SystemManager.Login(parameters.username, parameters.password, out id) == true)
if (System.IO.File.Exists("users.json"))
{
return this.Login(id);
if (SystemManager.Login(p.username, p.password, out id) == true)
{
return this.Login(id);
}
else
{
return PageBuilder.Build("loginFailed", new Dictionary<string, string>
{
{"{logout}", "" }
});
}
}
else
{
return PageBuilder.Build("loginFailed");
var mudUser = new MudUser();
mudUser.Username = p.username;
mudUser.Password = Encryption.Encrypt(p.password);
mudUser.Claims = new List<string>(new[] { "Admin" });
mudUser.ID = Guid.NewGuid();
id = mudUser.ID;
List<MudUser> users = new List<MudUser>(new[] { mudUser });
ShiftOS.Server.Program.WriteEncFile("users.json", JsonConvert.SerializeObject(users, Formatting.Indented));
return this.Login(id);
}
};
}
}
public class UserModule : NancyModule
{
public UserModule()
{
this.RequiresAuthentication();
this.RequiresClaims("User");
this.RequiresClaims("Admin");
Get["/"] = _ =>
{
return PageBuilder.Build("status");
return PageBuilder.Build("status", new Dictionary<string, string>{
{ "{cp_worth}", SystemManager.GetCPWorth() },
{ "{user_count}", SystemManager.GetUserCount() },
{ "{system_time}", DateTime.Now.ToString() },
});
};
Get["/status"] = _ =>
{
@ -185,4 +281,10 @@ namespace ShiftOS.Server.WebAdmin
};
}
}
public class LoginRequest
{
public string username { get; set; }
public string password { get; set; }
}
}

View file

@ -66,10 +66,10 @@ namespace ShiftOS.Server.WebAdmin.Properties {
/// &lt;title&gt;Multi-user domain &amp;bull; ShiftOS&lt;/title&gt;
/// &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css&quot; integrity=&quot;sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u&quot; crossorigin=&quot;anonymous&quot;&gt;
///
/// &lt;link rel=&quot;stylesheet&quot; href=&quot;css/theme.css&quot;/&gt;
/// &lt;link rel=&quot;stylesheet&quot; href=&quot;http://getshiftos.ml/css/theme.css&quot;/&gt;
///
/// &lt;!-- Latest compiled and minified JavaScript --&gt;
/// &lt;script src=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js&quot; integrity=&quot;sha384-Tc5IQib027qvyjSMfHjOMaLkf [rest of string was truncated]&quot;;.
/// &lt;script src=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js&quot; integrity=&quot;sha384-Tc5I [rest of string was truncated]&quot;;.
/// </summary>
internal static string HtmlTemplate {
get {
@ -98,5 +98,50 @@ namespace ShiftOS.Server.WebAdmin.Properties {
return ResourceManager.GetString("LoginView", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;h1&gt;Initial setup&lt;/h1&gt;
///
///&lt;p&gt;Welcome to your multi-user domain. If you are seeing this screen, it means that the web administration panel is successfully running and listening for requests. Before you can start using the admin panel you must create an Admin account. This account will let you log in and manage other authorized users, manage saves, Shiftnet pages and other information.&lt;/p&gt;
///
///&lt;p&gt;To continue, type a username and password.&lt;/p&gt;
///
///&lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
/// &lt;table class=&quot;table&quot;&gt;
/// &lt;tr&gt;
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string SetupView {
get {
return ResourceManager.GetString("SetupView", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;h3&gt;System status&lt;/h3&gt;
///
///&lt;p&gt;Below is a summary of this multi-user domain&apos;s status.&lt;/p&gt;
///
///&lt;div class=&quot;row&quot;&gt;
/// &lt;div class=&quot;col-xs-6&quot;&gt;
/// &lt;h4&gt;MUD stats&lt;/h4&gt;
/// &lt;ul&gt;
/// &lt;li&gt;This server is worth &lt;strong&gt;{cp_worth}&lt;/strong&gt; Codepoints.&lt;/li&gt;
/// &lt;li&gt;This server has &lt;strong&gt;{user_count}&lt;/strong&gt; players registered.&lt;/li&gt;
/// &lt;/ul&gt;
/// &lt;/div&gt;
/// &lt;div class=&quot;col-xs-6&quot;&gt;
/// &lt;h4&gt;System environment&lt;/h4&gt;
/// &lt;ul&gt;
/// &lt;li&gt;&lt;strong&gt;Current system time:&lt;/strong&gt; {system_time}&lt;/li&gt;
/// &lt;/ul&gt;
/// &lt;/div&gt;
///&lt;/div&gt;.
/// </summary>
internal static string Status {
get {
return ResourceManager.GetString("Status", resourceCulture);
}
}
}
}

View file

@ -124,4 +124,10 @@
<data name="LoginView" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\LoginView.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="SetupView" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\SetupView.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="Status" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Status.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
</root>

View file

@ -3,42 +3,42 @@
<title>Multi-user domain &bull; ShiftOS</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="css/theme.css"/>
<link rel="stylesheet" href="http://getshiftos.ml/css/theme.css"/>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<!-- Sidebar -->
<div id="sidebar-wrapper">
<ul class="sidebar-nav">
<li class="sidebar-brand">
<a href="http://getshiftos.ml/">
<img src="https://cdn.discordapp.com/attachments/241613675545231360/280020406528901131/unknown.png"/>
</a>
<div class="navbar navbar-default">
<div class+"navbar-header">
<a class="navbar-brand" href="http://getshiftos.ml">ShiftOS</a>
</div>
<ul class="nav navbar-nav">
<li>
<a href="/webadmin/status">System status</a>
</li>
<li>
<a href="/status">System status</a>
<a href="/webadmin/saves">Test subjects</a>
</li>
<li>
<a href="/saves">Test subjects</a>
<a href="/webadmin/shiftnet">Shiftnet</a>
</li>
<li>
<a href="/shiftnet">Shiftnet</a>
<a href="/webadmin/scripts">Scripts</a>
</li>
<li>
<a href="/scripts">Scripts</a>
<a href="/webadmin/legions">Legions</a>
</li>
<li>
<a href="/legions">Legions</a>
<a href="/webadmin/shops">Shops</a>
</li>
<li>
<a href="/shops">Shops</a>
</li>
<li>
<a href="/help">Help</a>
<a href="/webadmin/help">Help</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
{logout}
</ul>
</div>
<!-- /#sidebar-wrapper -->

View file

@ -14,7 +14,18 @@
</tr>
<tr>
<td></td>
<td><input type="submit" class="btn btn-default">Login</input>
<td><input type="submit" class="btn btn-default"/></td>
</tr>
</table>
</form>
</form>
<div class="row">
<div class="col-xs-6">
<h4>What are my credentials?</h4>
<p>If you do not know your credentials, you are not a ShiftOS developer with write-access to the GitHub repository and authorized access to the multi-user domain's backend, so we ask that you get off this site and try to hack the MUD in-game. Thank you.</p>
</div>
<div class="col-xs-6">
<h4>I am a developer.</h4>
<p>Please contact Michael VanOverbeek if you are a developer and have not yet received your credentials.</p>
</div>
</div>

View file

@ -0,0 +1,22 @@
<h1>Initial setup</h1>
<p>Welcome to your multi-user domain. If you are seeing this screen, it means that the web administration panel is successfully running and listening for requests. Before you can start using the admin panel you must create an Admin account. This account will let you log in and manage other authorized users, manage saves, Shiftnet pages and other information.</p>
<p>To continue, type a username and password.</p>
<form method="post" action="">
<table class="table">
<tr>
<td><strong>Username:</strong></td>
<td><input class="form-control" type="text" name="username"/></td>
</tr>
<tr>
<td><strong>Password:</strong></td>
<td><input class="form-control" type="password" name="password"/></td>
</tr>
<tr>
<td></td>
<td><input type="submit" class="btn btn-default"/></td>
</tr>
</table>
</form>

View file

@ -0,0 +1,19 @@
<h3>System status</h3>
<p>Below is a summary of this multi-user domain's status.</p>
<div class="row">
<div class="col-xs-6">
<h4>MUD stats</h4>
<ul>
<li>This server is worth <strong>{cp_worth}</strong> Codepoints.</li>
<li>This server has <strong>{user_count}</strong> players registered.</li>
</ul>
</div>
<div class="col-xs-6">
<h4>System environment</h4>
<ul>
<li><strong>Current system time:</strong> {system_time}</li>
</ul>
</div>
</div>

View file

@ -76,6 +76,10 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ShiftOS.Objects\ShiftOS.Objects.csproj">
<Project>{A069089A-8962-4607-B2B2-4CF4A371066E}</Project>
<Name>ShiftOS.Objects</Name>
</ProjectReference>
<ProjectReference Include="..\ShiftOS.Server\ShiftOS.Server.csproj">
<Project>{226c63b4-e60d-4949-b4e7-7a2ddbb96776}</Project>
<Name>ShiftOS.Server</Name>
@ -93,6 +97,12 @@
<ItemGroup>
<None Include="Resources\LoginView.txt" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\SetupView.txt" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Status.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.