156 lines
5.7 KiB
C#
156 lines
5.7 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Http;
|
|
using System;
|
|
using System.Web;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using SecureCore.Services;
|
|
using SecureCore.Authentication;
|
|
|
|
namespace SecureCore.Controllers
|
|
{
|
|
[Route("[controller]")]
|
|
[ApiController]
|
|
public class AuthController : Controller
|
|
{
|
|
//TODO: Login will only ever return messages like "Wrong username / password." whereas register can return messages like "User exists.", "Password to weak", or "Password in top 100 most used.".
|
|
[HttpPost("login")]
|
|
[AcceptVerbs("POST")]
|
|
public IActionResult Login([FromBody] LoginInfo info)
|
|
{
|
|
//NOTE: password length should be at most 64 - 128 characters long.
|
|
//Very the user has login data.
|
|
//if (!UserDataService.UserHasLoginData(info.UserName)) return Unauthorized("User doesn't have login creds");
|
|
var result = UserDataService.UserNameIsValid(info.UserName);
|
|
|
|
if (!result.IsValid) return Unauthorized(result.Message);
|
|
|
|
//if (HttpContext.Request.Cookies.ContainsKey("Session"))
|
|
//{
|
|
// if(UserDataService.IsSessionTokenValid(HttpContext.Request.Cookies["Session"]))//, info.UserName))
|
|
// return Ok($"Session is live{Environment.NewLine}");
|
|
//}
|
|
|
|
var (password, salt) = UserDataService.GetUserPasswordHash(info.UserName);
|
|
var agent = HttpContext.Request.Headers[Microsoft.Net.Http.Headers.HeaderNames.UserAgent];
|
|
var ip = PasswordManager.HashStringData(Request.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString(), salt);
|
|
result = PasswordManager.PasswordIsValid(info.Password, salt, password);
|
|
|
|
if (result.IsValid)
|
|
{
|
|
var session = new SessionManager();
|
|
|
|
var sessionToken = session.CreateSessionToken();
|
|
|
|
UserDataService.SetUserSessionToken(info.UserName, sessionToken, DateTime.Now.AddDays(7), agent, ip);
|
|
|
|
HttpContext.Response.Cookies.Append("Session", sessionToken, GetCookieOptions());
|
|
|
|
return Ok($"Logged in success{Environment.NewLine}");
|
|
}
|
|
else
|
|
{
|
|
return Unauthorized(result.Message);
|
|
}
|
|
}
|
|
|
|
[HttpPost("Register")]
|
|
[AcceptVerbs("POST")]
|
|
public IActionResult Register([FromBody] LoginInfo info)
|
|
{
|
|
var (hash, salt) = PasswordManager.HashPassword(info.Password);
|
|
var session = new SessionManager();
|
|
var sessionToken = session.CreateSessionToken();
|
|
var agent = HttpContext.Request.Headers[Microsoft.Net.Http.Headers.HeaderNames.UserAgent];
|
|
var ip = PasswordManager.HashStringData(Request.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString(), salt);
|
|
|
|
try
|
|
{
|
|
var i = UserDataService.RegisterNewUser(info.UserName, info.Email, hash, salt, sessionToken, DateTime.Now.AddDays(7),agent, ip);
|
|
|
|
HttpContext.Response.Cookies.Append("Session", sessionToken, GetCookieOptions());
|
|
|
|
return Ok($"New User ID: {i}");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return Unauthorized(e.Message);
|
|
}
|
|
}
|
|
|
|
[HttpPost("Logout")]
|
|
[AcceptVerbs("POST")]
|
|
public IActionResult Logout()
|
|
{
|
|
UserDataService.DestroySession(HttpContext.Request.Cookies["Session"]);
|
|
|
|
HttpContext.Response.Cookies.Delete("Session");
|
|
|
|
return Ok();
|
|
}
|
|
|
|
[HttpGet("ResetPassword")]
|
|
//[AcceptVerbs("GET")]
|
|
public IActionResult ResetPassword([FromQuery] string token)
|
|
{
|
|
try
|
|
{
|
|
if (!UserDataService.IsResetTokenValid(token)) return Unauthorized("Token invalid");
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
|
|
}
|
|
return Ok("Done");
|
|
}
|
|
|
|
[HttpPost("CreatePasswordResetLink")]
|
|
[AcceptVerbs("POST")]
|
|
public IActionResult CreatePasswordResetLink([FromBody] string userName) //TODO: this sig should only accept an email, so the link can be sent there.
|
|
{
|
|
var sessionManager = new SessionManager();
|
|
var token = sessionManager.CreateSessionToken();
|
|
var agent = HttpContext.Request.Headers[Microsoft.Net.Http.Headers.HeaderNames.UserAgent];
|
|
var ip = PasswordManager.HashStringData(Request.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString());
|
|
|
|
try
|
|
{
|
|
UserDataService.SetUserSessionToken(userName, token, DateTime.Now.AddHours(1), agent, ip, true);
|
|
|
|
token = HttpUtility.UrlEncode(token);
|
|
|
|
return Ok($"192.168.255.200:5000/auth/ResetPassword?token={token}{Environment.NewLine}");
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
return Unauthorized($"{e.Message}{Environment.NewLine}");
|
|
}
|
|
}
|
|
|
|
private CookieOptions GetCookieOptions()
|
|
{
|
|
return new CookieOptions
|
|
{
|
|
//Domain = "copyrightcrusader.org",
|
|
Expires = DateTime.Now.AddDays(7),
|
|
//HttpOnly = true,
|
|
//Secure = true,
|
|
Path = "/",
|
|
SameSite = SameSiteMode.Strict
|
|
};
|
|
}
|
|
}
|
|
|
|
public class LoginInfo
|
|
{
|
|
public string UserName { get; set; }
|
|
public string Password { get; set; }
|
|
public string Email { get; set; }
|
|
}
|
|
|
|
//TODO: Read more https://www.valentinog.com/blog/cookies/
|
|
// And this https://blog.webf.zone/ultimate-guide-to-http-cookies-2aa3e083dbae
|
|
}
|