JPHD-2021-backend/Pages/Account/Login.cshtml.cs

148 lines
5.5 KiB
C#

using _2021_backend.Data;
using _2021_backend.Models;
using _2021_backend.Utils;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Account
{
public class LoginModel : PageModel
{
private readonly string LoginURL = "https://xms.zjueva.net/api/auth/login";
private readonly IConfiguration config;
private readonly BackendContext context;
public LoginModel(IConfiguration configuration, BackendContext context)
{
config = configuration;
this.context = context;
}
public IActionResult OnGet(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return Page();
}
[BindProperty]
public string username { get; set; }
[BindProperty]
public string password { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
var NowSecret = EvaCryptoHelper.Password2Secret(password);
string stuID = username;
var query = from _user in context.Users
where _user.stuID == stuID
select _user;
var user = await query.AsNoTracking().FirstOrDefaultAsync();
//need use xms login service
if (user == null)
{
Login login_Stu = new Login(username, password);
//post login information to xms.zjueva.net and receive the response with string
string ansString = LoginHelper.PostMoths(LoginURL, login_Stu);
JObject ansJson = (JObject)JsonConvert.DeserializeObject(ansString);
//error and Denied
if (ansJson["status"].ToString() == "error")
{
return RedirectToPage("/Account/Denied");
}
else if (ansJson["status"].ToString() == "success")
{
User add_user = new User()
{
stuID = ansJson["data"]["stuid"].ToString(),
Name = ansJson["data"]["name"].ToString(),
Secret = login_Stu.GetSHASecret(),
isManager = login_Stu.isManager()
};
context.Users.Add(add_user);
await context.SaveChangesAsync();
//add new user to DB and now continue to create cookie;
user = add_user;
//this user is correct and don't use the follow "else"
}
}
if (user.Secret == NowSecret)
{
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
identity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
identity.AddClaim(new Claim(ClaimTypes.Sid, user.Guid.ToString()));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, username));
if (user.isManager)
{
identity.AddClaim(new Claim(EvaClaimTypes.IsManager, "true"));
identity.AddClaim(new Claim(ClaimTypes.Role, "manager"));
}
else
{
identity.AddClaim(new Claim(ClaimTypes.Role, "user"));
}
var Iprinciple = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
Iprinciple,
new AuthenticationProperties
{
IsPersistent = true,
AllowRefresh = true
}
);
return RedirectToPage("/Students/Index");
}
//if user change his secret in XMS
else
{
Login login_Stu = new Login(username, password);
//post login information to xms.zjueva.net and receive the response with string
string ansString = LoginHelper.PostMoths(LoginURL, login_Stu);
JObject ansJson = (JObject)JsonConvert.DeserializeObject(ansString);
//error and Denied
if (ansJson["status"].ToString() == "error")
{
return RedirectToPage("/Account/Denied");
}
else
{
//change the secret in DB
user = await context.Users.FirstOrDefaultAsync(r => r.stuID == stuID);
user.Secret = login_Stu.GetSHASecret();
context.Attach(user).State = EntityState.Modified;
try
{
await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
return NotFound();
}
return RedirectToPage("/Index");
}
}
}
}
}