comments galore
This commit is contained in:
@@ -13,10 +13,11 @@ public class AuthController : ControllerBase {
|
||||
// identity things
|
||||
private readonly UserManager<User> userManager_;
|
||||
private readonly SignInManager<User> signInManager_;
|
||||
|
||||
// services
|
||||
private readonly JwtService jwt_;
|
||||
private readonly UserService userService_;
|
||||
|
||||
// class constructor (where are my initializer lists man)
|
||||
public AuthController(UserManager<User> userManager, SignInManager<User> signInManager, JwtService jwt, UserService userService) {
|
||||
|
||||
userManager_ = userManager;
|
||||
@@ -25,43 +26,49 @@ public class AuthController : ControllerBase {
|
||||
userService_ = userService;
|
||||
}
|
||||
|
||||
// register endpoint
|
||||
[HttpPost("register")]
|
||||
public async Task<ActionResult> Register(RegisterDto dto) {
|
||||
// create a new user out of the dto from the request
|
||||
User user = new User {
|
||||
UserName = dto.UserName,
|
||||
Email = dto.Email,
|
||||
CreatedAt = DateTime.UtcNow // yeah why not utc
|
||||
};
|
||||
|
||||
// assigning roles to user
|
||||
// assigning roles to user. create a user starting with x to give it permissions to read sensitive data
|
||||
if(dto.UserName.StartsWith("x")) {
|
||||
user.Permissions = new List<string> { Permission.SensitiveData_Read };
|
||||
} else if(dto.UserName == "bard") {
|
||||
user.Permissions = new List<string> { Permission.SensitiveData_Read, Permission.SensitiveData_Modify };
|
||||
}
|
||||
}
|
||||
|
||||
// use Identity's user manager to add to db; error check if failed
|
||||
var result = await userManager_.CreateAsync(user, dto.Password);
|
||||
if(!result.Succeeded) return BadRequest(result.Errors);
|
||||
|
||||
// respond to post as necessary
|
||||
return CreatedAtAction(
|
||||
nameof(Register),
|
||||
new { id = user.Id }
|
||||
);
|
||||
}
|
||||
|
||||
// login endpoint
|
||||
[HttpPost("login")]
|
||||
public async Task<ActionResult> Login(LoginDto dto)
|
||||
{
|
||||
// get the user from the database given the username
|
||||
var user = await userManager_.FindByNameAsync(dto.UserName);
|
||||
// user not found with that name
|
||||
if (user == null) return Unauthorized(); // unauthorized instead of not found to not give away info
|
||||
|
||||
if (user == null) return Unauthorized();
|
||||
|
||||
// use identity's password validation
|
||||
var result = await signInManager_.CheckPasswordSignInAsync(user, dto.Password, false);
|
||||
|
||||
// if failed then youre not real !
|
||||
if(!result.Succeeded) return Unauthorized();
|
||||
|
||||
// login sucess, give you an authentication token
|
||||
var accessToken = await jwt_.GenerateJwt(user);
|
||||
var refreshToken = jwt_.GenerateRefreshToken();
|
||||
var refreshToken = jwt_.GenerateRefreshToken(); // the refresh token is good enough to refresh your access token
|
||||
RefreshToken newTokenObject = new RefreshToken {
|
||||
Token = refreshToken,
|
||||
UserId = user.Id,
|
||||
@@ -70,43 +77,44 @@ public class AuthController : ControllerBase {
|
||||
IsRevoked = false
|
||||
};
|
||||
await jwt_.AddRefreshToken(newTokenObject);
|
||||
// the jwt says we trust who you are and can substitute it for login
|
||||
// contains permissions claims too
|
||||
|
||||
if(user.UserName == "bard") { // tempory because im silly
|
||||
await userManager_.AddToRoleAsync(user, "superuser");
|
||||
} // eventually ill have an endpoint for adding/removing roles
|
||||
|
||||
if(dto.UserName == "bard") {
|
||||
user.Permissions = new List<string> { Permission.SensitiveData_Read, Permission.SensitiveData_Modify };
|
||||
await userService_.Update(user.Id, user);
|
||||
}
|
||||
|
||||
// return both access and refresh token
|
||||
return Ok(new { accessToken, refreshToken });
|
||||
}
|
||||
|
||||
// logout endpoint
|
||||
[Authorize] // authorize is handled by middleware
|
||||
[HttpPost("logout")]
|
||||
public async Task<ActionResult> Logout(string refreshTokenString) {
|
||||
// revoke refresh token
|
||||
bool success = await jwt_.RevokeRefreshToken(refreshTokenString);
|
||||
if(!success) return NotFound();
|
||||
// frontend refreshes page and detects logout
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// refresh token endpoint
|
||||
[HttpPost("refresh")] // allow-anonymous by default
|
||||
public async Task<ActionResult> Refresh(TokenDto request) {
|
||||
// reached when the frontend gets an unauthorized response and autoattempts to refresh if available
|
||||
|
||||
// get token from request and check if its valid
|
||||
RefreshToken? storedToken = await jwt_.GetRefreshToken(request.RefreshToken);
|
||||
if (storedToken == null) return Unauthorized();
|
||||
bool valid = (storedToken.IsRevoked) ||
|
||||
(storedToken.ExpiresAt < DateTime.UtcNow);
|
||||
if(!valid) return Unauthorized(); // TODO: delete the invalid token
|
||||
|
||||
// get user from the token and give them new tokens
|
||||
User? user = await jwt_.GetUser(storedToken.UserId);
|
||||
if(user == null) return NotFound();
|
||||
string? newAccessToken = await jwt_.GenerateJwt(user);
|
||||
if(newAccessToken == null) return NotFound();
|
||||
string newRefreshToken = jwt_.GenerateRefreshToken();
|
||||
|
||||
// construct new token
|
||||
storedToken.IsRevoked = true;
|
||||
RefreshToken newTokenObject = new RefreshToken {
|
||||
Token = newRefreshToken,
|
||||
@@ -117,10 +125,9 @@ public class AuthController : ControllerBase {
|
||||
};
|
||||
|
||||
await jwt_.AddRefreshToken(newTokenObject);
|
||||
|
||||
// return new tokens
|
||||
return Ok(new { accessToken = newAccessToken, refreshToken = newRefreshToken });
|
||||
|
||||
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
Reference in New Issue
Block a user