mirror of
https://github.com/EpinelPS/EpinelPS.git
synced 2025-12-15 08:24:52 +01:00
admin panel work
This commit is contained in:
@@ -83,7 +83,15 @@ namespace EpinelPS.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = new User() { ID = uid, Password = req.password, RegisterTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), Username = req.account, PlayerName = "Player_" + Rng.RandomString(8) };
|
var user = new User()
|
||||||
|
{
|
||||||
|
ID = uid,
|
||||||
|
Password = req.password,
|
||||||
|
RegisterTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
|
||||||
|
Username = req.account,
|
||||||
|
PlayerName = "Player_" + Rng.RandomString(8),
|
||||||
|
IsAdmin = JsonDb.Instance.Users.Count == 0
|
||||||
|
};
|
||||||
|
|
||||||
JsonDb.Instance.Users.Add(user);
|
JsonDb.Instance.Users.Add(user);
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ namespace EpinelPS.Controllers
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckAuth()
|
public static bool CheckAuth(HttpContext context)
|
||||||
{
|
{
|
||||||
string? token = HttpContext.Request.Cookies["token"];
|
string? token = context.Request.Cookies["token"];
|
||||||
if (token == null) return false;
|
if (token == null) return false;
|
||||||
|
|
||||||
|
|
||||||
@@ -26,45 +26,40 @@ namespace EpinelPS.Controllers
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("dashboard")]
|
[Route("dashboard")]
|
||||||
public IActionResult Dashboard()
|
public IActionResult Dashboard()
|
||||||
{
|
{
|
||||||
if (!CheckAuth()) return Redirect("/admin/");
|
if (!CheckAuth(HttpContext)) return Redirect("/admin/");
|
||||||
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
[Route("Events")]
|
[Route("Events")]
|
||||||
public IActionResult Events()
|
public IActionResult Events()
|
||||||
{
|
{
|
||||||
if (!CheckAuth()) return Redirect("/admin/");
|
if (!CheckAuth(HttpContext)) return Redirect("/admin/");
|
||||||
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
[Route("Configuration")]
|
[Route("Configuration")]
|
||||||
public IActionResult Configuration()
|
public IActionResult Configuration()
|
||||||
{
|
{
|
||||||
if (!CheckAuth()) return Redirect("/admin/");
|
if (!CheckAuth(HttpContext)) return Redirect("/admin/");
|
||||||
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
[Route("Users")]
|
|
||||||
public IActionResult Users()
|
|
||||||
{
|
|
||||||
if (!CheckAuth()) return Redirect("/admin/");
|
|
||||||
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
[Route("Mail")]
|
[Route("Mail")]
|
||||||
public IActionResult Mail()
|
public IActionResult Mail()
|
||||||
{
|
{
|
||||||
if (!CheckAuth()) return Redirect("/admin/");
|
if (!CheckAuth(HttpContext)) return Redirect("/admin/");
|
||||||
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
[Route("Database")]
|
[Route("Database")]
|
||||||
public IActionResult Database()
|
public IActionResult Database()
|
||||||
{
|
{
|
||||||
if (!CheckAuth()) return Redirect("/admin/");
|
if (!CheckAuth(HttpContext)) return Redirect("/admin/");
|
||||||
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
102
EpinelPS/Controllers/AdminPanel/UsersController.cs
Normal file
102
EpinelPS/Controllers/AdminPanel/UsersController.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace EpinelPS.Controllers
|
||||||
|
{
|
||||||
|
[Route("admin/Users")]
|
||||||
|
public class UsersController : Controller
|
||||||
|
{
|
||||||
|
private readonly ILogger<AdminController> _logger;
|
||||||
|
private static MD5 sha = MD5.Create();
|
||||||
|
|
||||||
|
public UsersController(ILogger<AdminController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
if (!AdminController.CheckAuth(HttpContext)) return Redirect("/admin/");
|
||||||
|
|
||||||
|
return View(JsonDb.Instance.Users);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("Modify/{id}")]
|
||||||
|
public IActionResult Modify(ulong id)
|
||||||
|
{
|
||||||
|
if (!AdminController.CheckAuth(HttpContext)) return Redirect("/admin/");
|
||||||
|
|
||||||
|
if (id == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = JsonDb.Instance.Users.Where(x => x.ID == id).FirstOrDefault();
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return View(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("SetPassword/{id}")]
|
||||||
|
public IActionResult SetPassword(ulong id)
|
||||||
|
{
|
||||||
|
if (!AdminController.CheckAuth(HttpContext)) return Redirect("/admin/");
|
||||||
|
|
||||||
|
if (id == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = JsonDb.Instance.Users.Where(x => x.ID == id).FirstOrDefault();
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
user.Password = ""; // do not return the password
|
||||||
|
|
||||||
|
return View(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
|
||||||
|
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
|
||||||
|
[Route("SetPassword")]
|
||||||
|
[HttpPost, ActionName("SetPassword")]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public async Task<IActionResult> SetPasswordConfirm(ulong? id)
|
||||||
|
{
|
||||||
|
if (!AdminController.CheckAuth(HttpContext)) return Redirect("/admin/");
|
||||||
|
|
||||||
|
if (id == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
string? newPw = Request.Form["PasswordHash"];
|
||||||
|
if (string.IsNullOrEmpty(newPw))
|
||||||
|
{
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use bcrypt
|
||||||
|
|
||||||
|
var userToUpdate = JsonDb.Instance.Users.Where(s => s.ID == id).FirstOrDefault();
|
||||||
|
if (userToUpdate == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
userToUpdate.Password = Convert.ToHexString(sha.ComputeHash(Encoding.ASCII.GetBytes(newPw))).ToLower(); ;
|
||||||
|
|
||||||
|
return View(userToUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
EpinelPS/Views/Admin/Configuration.cshtml
Normal file
8
EpinelPS/Views/Admin/Configuration.cshtml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Configuration";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-4">Configuration</h1>
|
||||||
|
<p>Coming soon!</p>
|
||||||
|
</div>
|
||||||
8
EpinelPS/Views/Admin/Database.cshtml
Normal file
8
EpinelPS/Views/Admin/Database.cshtml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Database configuration";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-4">Database configuration</h1>
|
||||||
|
<p>Coming soon!</p>
|
||||||
|
</div>
|
||||||
8
EpinelPS/Views/Admin/Events.cshtml
Normal file
8
EpinelPS/Views/Admin/Events.cshtml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Event configuration";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-4">Event configuration</h1>
|
||||||
|
<p>Coming soon!</p>
|
||||||
|
</div>
|
||||||
8
EpinelPS/Views/Admin/Mail.cshtml
Normal file
8
EpinelPS/Views/Admin/Mail.cshtml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Mail";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-4">In-game Mail</h1>
|
||||||
|
<p>Coming soon!</p>
|
||||||
|
</div>
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
@{
|
|
||||||
ViewData["Title"] = "Users";
|
|
||||||
}
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<h1 class="display-4">Users</h1>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<a class="nav-link text-dark" href="/admin/Events">Events</a>
|
<a class="nav-link text-dark" href="/admin/Events">Events</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text-dark" href="/admin/Users">Users</a>
|
<a class="nav-link text-dark" href="/admin/Users/">Users</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text-dark" href="/admin/Mail">Mail</a>
|
<a class="nav-link text-dark" href="/admin/Mail">Mail</a>
|
||||||
|
|||||||
57
EpinelPS/Views/Users/Delete.cshtml
Normal file
57
EpinelPS/Views/Users/Delete.cshtml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
@model EpinelPS.Database.User
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Delete user";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>Delete</h1>
|
||||||
|
<p class="text-danger">@ViewData["ErrorMessage"]</p>
|
||||||
|
<h3>Are you sure you want to delete this?</h3>
|
||||||
|
<div>
|
||||||
|
<h4>User</h4>
|
||||||
|
<hr />
|
||||||
|
<dl class="row">
|
||||||
|
<dt class = "col-sm-2">
|
||||||
|
@Html.DisplayNameFor(model => model.ID)
|
||||||
|
</dt>
|
||||||
|
<dd class = "col-sm-10">
|
||||||
|
@Html.DisplayFor(model => model.ID)
|
||||||
|
</dd>
|
||||||
|
<dt class = "col-sm-2">
|
||||||
|
@Html.DisplayNameFor(model => model.Username)
|
||||||
|
</dt>
|
||||||
|
<dd class = "col-sm-10">
|
||||||
|
@Html.DisplayFor(model => model.Username)
|
||||||
|
</dd>
|
||||||
|
<dt class = "col-sm-2">
|
||||||
|
@Html.DisplayNameFor(model => model.IsAdmin)
|
||||||
|
</dt>
|
||||||
|
<dd class = "col-sm-10">
|
||||||
|
@Html.DisplayFor(model => model.IsAdmin)
|
||||||
|
</dd>
|
||||||
|
<dt class = "col-sm-2">
|
||||||
|
@Html.DisplayNameFor(model => model.PlayerName)
|
||||||
|
</dt>
|
||||||
|
<dd class = "col-sm-10">
|
||||||
|
@Html.DisplayFor(model => model.PlayerName)
|
||||||
|
</dd>
|
||||||
|
<dt class = "col-sm-2">
|
||||||
|
@Html.DisplayNameFor(model => model.Nickname)
|
||||||
|
</dt>
|
||||||
|
<dd class = "col-sm-10">
|
||||||
|
@Html.DisplayFor(model => model.Nickname)
|
||||||
|
</dd>
|
||||||
|
<dt class = "col-sm-2">
|
||||||
|
@Html.DisplayNameFor(model => model.IsBanned)
|
||||||
|
</dt>
|
||||||
|
<dd class = "col-sm-10">
|
||||||
|
@Html.DisplayFor(model => model.IsBanned)
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<form asp-action="Delete">
|
||||||
|
<input type="hidden" asp-for="ID" />
|
||||||
|
<input type="submit" value="Delete" class="btn btn-danger" /> |
|
||||||
|
<a asp-action="Index">Back to List</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
46
EpinelPS/Views/Users/Index.cshtml
Normal file
46
EpinelPS/Views/Users/Index.cshtml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
@model IEnumerable<EpinelPS.Database.User>
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Users";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-4">Users</h1>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
@Html.DisplayNameFor(model => model.Username)
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
@Html.DisplayNameFor(model => model.IsAdmin)
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
@Html.DisplayNameFor(model => model.PlayerName)
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var item in Model) {
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
@Html.DisplayFor(modelItem => item.Username)
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@Html.DisplayFor(modelItem => item.IsAdmin)
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@Html.DisplayFor(modelItem => item.PlayerName)
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a asp-action="SetPassword" asp-route-id="@item.ID">Change Password</a> |
|
||||||
|
<a asp-action="Modify" asp-route-id="@item.ID">Modify</a> |
|
||||||
|
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
45
EpinelPS/Views/Users/Modify.cshtml
Normal file
45
EpinelPS/Views/Users/Modify.cshtml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
@model EpinelPS.Database.User
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Modify user";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>Modify</h1>
|
||||||
|
|
||||||
|
<h4>User</h4>
|
||||||
|
<hr />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form asp-action="Modify">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||||
|
<input type="hidden" asp-for="ID" />
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="Username" class="control-label col-sm-2"></label>
|
||||||
|
<div class="col-sm-10"><input asp-for="Username" class="form-control" /></div>
|
||||||
|
<span asp-validation-for="Username" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="IsAdmin" class="control-label"></label>
|
||||||
|
<input asp-for="IsAdmin" class="form-check-input" />
|
||||||
|
<span asp-validation-for="IsAdmin" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="IsBanned" class="control-label"></label>
|
||||||
|
<input asp-for="IsBanned" class="form-check-input" />
|
||||||
|
<span asp-validation-for="IsBanned" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="Nickname" class="control-label col-sm-2"></label>
|
||||||
|
<div class="col-sm-10"><input asp-for="Nickname" class="form-control" /></div>
|
||||||
|
<span asp-validation-for="Nickname" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="submit" value="Save" class="btn btn-primary" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a asp-action="Index">Back to List</a>
|
||||||
|
</div>
|
||||||
30
EpinelPS/Views/Users/SetPassword.cshtml
Normal file
30
EpinelPS/Views/Users/SetPassword.cshtml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
@model EpinelPS.Database.User
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Change user password";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1>Change password</h1>
|
||||||
|
|
||||||
|
<h4>User</h4>
|
||||||
|
<hr />
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<form asp-action="SetPassword">
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||||
|
<input type="hidden" asp-for="ID" />
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="Password" class="control-label"></label>
|
||||||
|
<input asp-for="Password" class="form-control" required />
|
||||||
|
<span asp-validation-for="Password" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="submit" value="Change password" class="btn btn-danger" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a asp-action="Index">Back to List</a>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user