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 { [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"); 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); if (PasswordManager.PasswordIsValid(info.Password, salt, password)) { 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(); } } [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) { if (!UserDataService.IsResetTokenValid(token)) return Unauthorized("Token invalid"); return Ok("Done"); } [HttpPost("CreatePasswordResetLink")] [AcceptVerbs("POST")] public IActionResult CreatePasswordResetLink([FromBody] string userName) { 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 }