Update API to follow REST
This commit is contained in:
@@ -5,6 +5,8 @@ using System.Security.Claims;
|
|||||||
using BoredCareers.Services;
|
using BoredCareers.Services;
|
||||||
using BoredCareers.Services.DatabaseService;
|
using BoredCareers.Services.DatabaseService;
|
||||||
using BoredCareers.Entities;
|
using BoredCareers.Entities;
|
||||||
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
|
using System.Web.Http;
|
||||||
|
|
||||||
namespace BoredCareers.Controllers {
|
namespace BoredCareers.Controllers {
|
||||||
[ApiController]
|
[ApiController]
|
||||||
@@ -26,7 +28,7 @@ namespace BoredCareers.Controllers {
|
|||||||
if (test.EmailVerified == true) {
|
if (test.EmailVerified == true) {
|
||||||
if (test.FailedPasswordLock) {
|
if (test.FailedPasswordLock) {
|
||||||
if (test.CurrentPasswordAttempts >= test.PasswordAttempts) {
|
if (test.CurrentPasswordAttempts >= test.PasswordAttempts) {
|
||||||
return new Account() { ID = -1, UserName = "Too many failed password attempts. Please reset your password" };
|
return NotFound("Too many failed password attempts. Please reset your password");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (BCrypt.Net.BCrypt.Verify(PasswordHash, test.PasswordHash)) {
|
if (BCrypt.Net.BCrypt.Verify(PasswordHash, test.PasswordHash)) {
|
||||||
@@ -47,21 +49,20 @@ namespace BoredCareers.Controllers {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
return test;
|
return test;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
test.CurrentPasswordAttempts += 1;
|
test.CurrentPasswordAttempts += 1;
|
||||||
await _databaseService.SetAccount(test);
|
await _databaseService.SetAccount(test);
|
||||||
return new Account() { ID = -1, UserName = "Wrong Password" };
|
return Ok(new Account() { ID = -1, UserName = "Wrong Password" });
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
await SendVerify(test.UserName);
|
await SendVerify(test.UserName);
|
||||||
return new Account() { ID = -1, UserName = "A new verify email has been sent. \n Note only 1 email send every 5 mintes" };
|
return NotFound("A new verify email has been sent. \n Note only 1 email send every 5 mintes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new Account() { ID = -1, UserName = "User doesn't exist" };
|
return NotFound("Account Not Found");
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
return new Account() { ID = -1, UserName = ex.Message };
|
Console.WriteLine("Login Error: " + ex.Message);
|
||||||
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,37 +72,35 @@ namespace BoredCareers.Controllers {
|
|||||||
try {
|
try {
|
||||||
if (await _databaseService.GetAccount(UserName.ToLower()) == null) {
|
if (await _databaseService.GetAccount(UserName.ToLower()) == null) {
|
||||||
if (await _databaseService.GetAccount(Email.ToLower()) == null) {
|
if (await _databaseService.GetAccount(Email.ToLower()) == null) {
|
||||||
Account? created = new Account() {
|
Account created = new Account() {
|
||||||
UserName = UserName.ToLower(),
|
UserName = UserName.ToLower(),
|
||||||
Email = Email.ToLower(),
|
Email = Email.ToLower(),
|
||||||
EmailVerified = false,
|
EmailVerified = false,
|
||||||
PasswordHash = BCrypt.Net.BCrypt.HashPassword(PasswordHash),
|
PasswordHash = BCrypt.Net.BCrypt.HashPassword(PasswordHash),
|
||||||
};
|
};
|
||||||
await _databaseService.SetAccount(created);
|
await _databaseService.SetAccount(created);
|
||||||
created = await _databaseService.GetAccount(Email.ToLower());
|
Account? loadedAccount = await _databaseService.GetAccount(Email.ToLower());
|
||||||
if (created != null) {
|
if (loadedAccount != null) {
|
||||||
await SendVerify(created.UserName);
|
await SendVerify(loadedAccount.UserName);
|
||||||
return created;
|
return Ok(loadedAccount);
|
||||||
}
|
}
|
||||||
return new Account() { ID = -1, UserName = "Unknown Error" };
|
return NotFound("Unable to create the account");
|
||||||
|
} else {
|
||||||
|
return NotFound("Email is already in use");
|
||||||
}
|
}
|
||||||
else {
|
} else {
|
||||||
return new Account() { ID = -1, UserName = "Email is already in use" };
|
return NotFound("UserName is taken");
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new Account() { ID = -1, UserName = "UserName is taken" };
|
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Console.WriteLine("Error: " + ex.Message);
|
Console.WriteLine("Register Error: " + ex.Message);
|
||||||
return new Account() { ID = -1, UserName = ex.Message };
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("changepassword")]
|
[Route("changepassword")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<ActionResult<bool>> ChangePassword([FromForm] string OldPassword, [FromForm] string NewPassword) {
|
public async Task<ActionResult> ChangePassword([FromForm] string OldPassword, [FromForm] string NewPassword) {
|
||||||
try {
|
try {
|
||||||
if (isLoggedIn()) {
|
if (isLoggedIn()) {
|
||||||
Account user = await getLoggedInUser();
|
Account user = await getLoggedInUser();
|
||||||
@@ -109,12 +108,13 @@ namespace BoredCareers.Controllers {
|
|||||||
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(NewPassword);
|
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(NewPassword);
|
||||||
user.CurrentPasswordAttempts = 0;
|
user.CurrentPasswordAttempts = 0;
|
||||||
await _databaseService.SetAccount(user);
|
await _databaseService.SetAccount(user);
|
||||||
return true;
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return NotFound();
|
||||||
} catch {
|
} catch (Exception ex) {
|
||||||
return false;
|
Console.WriteLine("ChangePassword Error: " + ex.Message);
|
||||||
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,31 +127,37 @@ namespace BoredCareers.Controllers {
|
|||||||
user.FailedPasswordLock = AccountLock;
|
user.FailedPasswordLock = AccountLock;
|
||||||
user.CurrentPasswordAttempts = 0;
|
user.CurrentPasswordAttempts = 0;
|
||||||
await _databaseService.SetAccount(user);
|
await _databaseService.SetAccount(user);
|
||||||
return "Account Lock Status Updated";
|
return Ok();
|
||||||
}
|
}
|
||||||
return "Unknown Error Occurred";
|
return NotFound();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
return ex.Message;
|
Console.WriteLine("ToggleAccountLock Error: " + ex.Message);
|
||||||
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("get")]
|
[Route("get")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<ActionResult<Account?>> Get() {
|
public async Task<ActionResult<Account>> Get() {
|
||||||
try {
|
try {
|
||||||
if (isLoggedIn()) {
|
if (isLoggedIn()) {
|
||||||
return await getLoggedInUser();
|
return Ok(await getLoggedInUser());
|
||||||
}
|
}
|
||||||
return Ok();
|
return NotFound();
|
||||||
} catch {
|
} catch (Exception ex) {
|
||||||
return Ok();
|
Console.WriteLine("Get Error: " + ex);
|
||||||
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("logout")]
|
[Route("logout")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task Logout() {
|
public async Task<ActionResult> Logout() {
|
||||||
await HttpContext.SignOutAsync();
|
if (isLoggedIn()) {
|
||||||
|
await HttpContext.SignOutAsync();
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("sendverifyemail")]
|
[Route("sendverifyemail")]
|
||||||
@@ -267,18 +273,19 @@ namespace BoredCareers.Controllers {
|
|||||||
|
|
||||||
[Route("delete")]
|
[Route("delete")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<ActionResult<bool>> delete([FromForm] string Password) {
|
public async Task<ActionResult> delete([FromForm] string Password) {
|
||||||
try {
|
try {
|
||||||
if (isLoggedIn()) {
|
if (isLoggedIn()) {
|
||||||
Account user = await getLoggedInUser();
|
Account user = await getLoggedInUser();
|
||||||
if (BCrypt.Net.BCrypt.Verify(Password, user.PasswordHash)) {
|
if (BCrypt.Net.BCrypt.Verify(Password, user.PasswordHash)) {
|
||||||
await _databaseService.DeleteAccount(user.ID);
|
await _databaseService.DeleteAccount(user.ID);
|
||||||
return true;
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return NotFound();
|
||||||
} catch {
|
} catch (Exception ex) {
|
||||||
return false;
|
Console.WriteLine("Delete Error: " + ex.Message);
|
||||||
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,16 +5,15 @@ using System.Web.Http;
|
|||||||
|
|
||||||
namespace BoredCareers.Controllers {
|
namespace BoredCareers.Controllers {
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/company/")]
|
[Route("api/company")]
|
||||||
public class CompanyController : MistoxControllerBase {
|
public class CompanyController : MistoxControllerBase {
|
||||||
|
|
||||||
public CompanyController(DatabaseService db) : base(db) {}
|
public CompanyController(DatabaseService db) : base(db) {}
|
||||||
|
|
||||||
[Route("get")]
|
[HttpGet]
|
||||||
[HttpPost]
|
public async Task<IActionResult> GetCompany(int CompanyID) {
|
||||||
public async Task<IActionResult> GetCompany([FromForm] int companyID) {
|
|
||||||
if (isLoggedIn()) {
|
if (isLoggedIn()) {
|
||||||
Company? company = await _databaseService.GetCompany(companyID);
|
Company? company = await _databaseService.GetCompany(CompanyID);
|
||||||
if (company != null) {
|
if (company != null) {
|
||||||
return Ok(company);
|
return Ok(company);
|
||||||
}
|
}
|
||||||
@@ -22,7 +21,6 @@ namespace BoredCareers.Controllers {
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("set")]
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> SetCompany([FromBody] Company company) {
|
public async Task<IActionResult> SetCompany([FromBody] Company company) {
|
||||||
if (isLoggedIn()) {
|
if (isLoggedIn()) {
|
||||||
@@ -34,9 +32,8 @@ namespace BoredCareers.Controllers {
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("delete")]
|
[HttpDelete]
|
||||||
[HttpPost]
|
public async Task<IActionResult> DeleteCompany(int CompanyID) {
|
||||||
public async Task<IActionResult> DeleteCompany([FromForm] int CompanyID) {
|
|
||||||
if (isLoggedIn()) {
|
if (isLoggedIn()) {
|
||||||
if (await isLoggedInUserEmployeeOf(CompanyID)) {
|
if (await isLoggedInUserEmployeeOf(CompanyID)) {
|
||||||
await _databaseService.DeleteCompany(CompanyID);
|
await _databaseService.DeleteCompany(CompanyID);
|
||||||
|
|||||||
@@ -5,42 +5,38 @@ using System.Web.Http;
|
|||||||
|
|
||||||
namespace BoredCareers.Controllers {
|
namespace BoredCareers.Controllers {
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/joblisting/")]
|
[Route("api/joblisting")]
|
||||||
public class JobListingController : MistoxControllerBase {
|
public class JobListingController : MistoxControllerBase {
|
||||||
|
|
||||||
public JobListingController(DatabaseService db) : base(db) {}
|
public JobListingController(DatabaseService db) : base(db) {}
|
||||||
|
|
||||||
[Route("getpage")]
|
[HttpGet("{JobListingID}")]
|
||||||
[HttpPost]
|
public async Task<IActionResult> GetJobListing([FromRoute] int JobListingID) {
|
||||||
public async Task<IActionResult> GetJobListings([FromForm] int page) {
|
var jobListing = await _databaseService.GetJobListing(JobListingID);
|
||||||
JobListing[] jobListings = await _databaseService.GetJobListingPage(page, 25); // 10 items per page
|
if (jobListing != null) {
|
||||||
return Ok(jobListings);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("get")]
|
|
||||||
[HttpPost]
|
|
||||||
public async Task<IActionResult> GetJobListing([FromForm] int JobListingID) {
|
|
||||||
JobListing? jobListing = await _databaseService.GetJobListing(JobListingID);
|
|
||||||
if (jobListing == null) {
|
|
||||||
return Ok(jobListing);
|
return Ok(jobListing);
|
||||||
}
|
}
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("set")]
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetJobListings(int Page = 1, int PageQuantity = 25) {
|
||||||
|
JobListing[] jobListings = await _databaseService.GetJobListingPage(Page, PageQuantity);
|
||||||
|
return Ok(jobListings);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> SetJobListing([FromBody] JobListing jobListing) {
|
public async Task<IActionResult> SetJobListing([FromBody] JobListing JobListing) {
|
||||||
if (isLoggedIn()) {
|
if (isLoggedIn()) {
|
||||||
if (await isLoggedInUserEmployeeOf(jobListing.CompanyID)) {
|
if (await isLoggedInUserEmployeeOf(JobListing.CompanyID)) {
|
||||||
await _databaseService.SetJobListing(jobListing);
|
await _databaseService.SetJobListing(JobListing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("delete")]
|
[HttpDelete]
|
||||||
[HttpPost]
|
public async Task<IActionResult> DeleteJobListing(int JobListingID) {
|
||||||
public async Task<IActionResult> DeleteJobListing([FromForm] int JobListingID) {
|
|
||||||
if (isLoggedIn()) {
|
if (isLoggedIn()) {
|
||||||
JobListing? jobListing = await _databaseService.GetJobListing(JobListingID);
|
JobListing? jobListing = await _databaseService.GetJobListing(JobListingID);
|
||||||
if (jobListing != null) {
|
if (jobListing != null) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using BoredCareers.Services.DatabaseService;
|
|||||||
|
|
||||||
namespace BoredCareers.Controllers {
|
namespace BoredCareers.Controllers {
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/payment/")]
|
[Route("api/payment")]
|
||||||
public class PaymentController : MistoxControllerBase {
|
public class PaymentController : MistoxControllerBase {
|
||||||
|
|
||||||
IPayment _paymentService;
|
IPayment _paymentService;
|
||||||
@@ -19,17 +19,11 @@ namespace BoredCareers.Controllers {
|
|||||||
// Add new payment plugins here
|
// Add new payment plugins here
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("getpublickey")]
|
[HttpGet]
|
||||||
[HttpPost]
|
|
||||||
public IActionResult GetPublicKey() {
|
public IActionResult GetPublicKey() {
|
||||||
try {
|
return Ok(IPayment._PublicKey);
|
||||||
return Ok(IPayment._PublicKey);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
return NotFound(ex.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("response")]
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> paymentWebhook() {
|
public async Task<IActionResult> paymentWebhook() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -5,33 +5,28 @@ using System.Web.Http;
|
|||||||
|
|
||||||
namespace BoredCareers.Controllers {
|
namespace BoredCareers.Controllers {
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/resume/")]
|
[Route("api/resume")]
|
||||||
public class ResumeController : MistoxControllerBase {
|
public class ResumeController : MistoxControllerBase {
|
||||||
|
|
||||||
public ResumeController(DatabaseService db) : base(db) {}
|
public ResumeController(DatabaseService db) : base(db) {}
|
||||||
|
|
||||||
[Route("getall")]
|
[HttpGet]
|
||||||
[HttpPost]
|
public async Task<IActionResult> GetResume(int? ResumeID) {
|
||||||
public async Task<IActionResult> GetResumes() {
|
if (ResumeID != null) {
|
||||||
if (isLoggedIn()) {
|
Resume? resume = await _databaseService.GetResume(ResumeID.Value);
|
||||||
int accountID = getLoggedInUserID();
|
if (resume != null) {
|
||||||
Resume[] resumes = await _databaseService.GetResumes(accountID);
|
return Ok(resume);
|
||||||
return Ok(resumes);
|
}
|
||||||
|
}else{
|
||||||
|
if (isLoggedIn()) {
|
||||||
|
int accountID = getLoggedInUserID();
|
||||||
|
Resume[] resumes = await _databaseService.GetResumes(accountID);
|
||||||
|
return Ok(resumes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("get")]
|
|
||||||
[HttpPost]
|
|
||||||
public async Task<IActionResult> GetResume([FromForm] int ResumeID) {
|
|
||||||
Resume? resume = await _databaseService.GetResume(ResumeID);
|
|
||||||
if (resume == null) {
|
|
||||||
return Ok(resume);
|
|
||||||
}
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Route("set")]
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> SetResume([FromBody] Resume resume) {
|
public async Task<IActionResult> SetResume([FromBody] Resume resume) {
|
||||||
if (isLoggedIn()) {
|
if (isLoggedIn()) {
|
||||||
@@ -44,9 +39,8 @@ namespace BoredCareers.Controllers {
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("delete")]
|
[HttpDelete]
|
||||||
[HttpPost]
|
public async Task<IActionResult> DeleteResume(int ResumeID) {
|
||||||
public async Task<IActionResult> DeleteResume([FromForm] int ResumeID) {
|
|
||||||
if (isLoggedIn()){
|
if (isLoggedIn()){
|
||||||
int accountID = getLoggedInUserID();
|
int accountID = getLoggedInUserID();
|
||||||
Resume? resume = await _databaseService.GetResume(ResumeID);
|
Resume? resume = await _databaseService.GetResume(ResumeID);
|
||||||
@@ -59,5 +53,4 @@ namespace BoredCareers.Controllers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,6 @@ using BoredCareers.Controllers.Payment;
|
|||||||
using BoredCareers.Services;
|
using BoredCareers.Services;
|
||||||
using BoredCareers.Services.DatabaseService;
|
using BoredCareers.Services.DatabaseService;
|
||||||
using System.Threading.RateLimiting;
|
using System.Threading.RateLimiting;
|
||||||
using Microsoft.AspNetCore.RateLimiting;
|
|
||||||
using Stripe;
|
using Stripe;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
||||||
@@ -99,10 +98,9 @@ builder.Services.AddCors(o => o.AddDefaultPolicy(builder => {
|
|||||||
|
|
||||||
builder.Services.AddRateLimiter(options => {
|
builder.Services.AddRateLimiter(options => {
|
||||||
options.AddPolicy("PerUserPolicy", httpContext => {
|
options.AddPolicy("PerUserPolicy", httpContext => {
|
||||||
// Identify the user (assumes authenticated user with NameIdentifier claim)
|
|
||||||
var userId = httpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value
|
var userId = httpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value
|
||||||
?? httpContext.User.Identity?.Name
|
?? httpContext.User.Identity?.Name
|
||||||
?? httpContext.Connection.RemoteIpAddress?.ToString();
|
?? httpContext.Connection.RemoteIpAddress?.ToString();
|
||||||
|
|
||||||
return RateLimitPartition.GetTokenBucketLimiter(userId, key => new TokenBucketRateLimiterOptions {
|
return RateLimitPartition.GetTokenBucketLimiter(userId, key => new TokenBucketRateLimiterOptions {
|
||||||
TokenLimit = 10, // max 10 requests
|
TokenLimit = 10, // max 10 requests
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using BoredCareers.Entities;
|
using BoredCareers.Entities;
|
||||||
using MySql.Data.MySqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
// TODO: Fix Data type mangling. Such As DateTime
|
|
||||||
|
|
||||||
namespace BoredCareers.Services.DatabaseService {
|
namespace BoredCareers.Services.DatabaseService {
|
||||||
public partial class DatabaseService {
|
public partial class DatabaseService {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user