Skip to content

Commit

Permalink
feat(api): added cors, jwt, user and issue management
Browse files Browse the repository at this point in the history
  • Loading branch information
GhostyJade committed May 11, 2023
1 parent 405b203 commit 7bb31c8
Show file tree
Hide file tree
Showing 12 changed files with 278 additions and 4 deletions.
30 changes: 30 additions & 0 deletions api/Controllers/IssuesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using TrackBEE.API.Data;

namespace TrackBEE.API.Controllers
{
[ApiController]
[Route("issues")]
public class IssuesController : ControllerBase
{
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> GetIssues()
{
try
{
var result = await NpgSQLDatabaseInterface.ExecuteStored("st_get_issues", null, null);
var issuesJson = JObject.Parse(result);
return StatusCode(200, issuesJson);
}
catch(Exception ex)
{
return StatusCode(500, ex.Message);
}
}
}
}

65 changes: 65 additions & 0 deletions api/Controllers/UsersController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using TrackBEE.API.Data;
using TrackBEE.API.Models.Users;
using TrackBEE.API.Managers;

using Swashbuckle.AspNetCore.Annotations;

namespace TrackBEE.API.Controllers
{
[ApiController]
[Route("api")]
[Produces("application/json")]
public class AuthController : ControllerBase
{
[AllowAnonymous]
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] UserModelRequest login)
{
IActionResult response = Unauthorized();
var user = await UsersManager.AuthenticateUser(login);
if (user != null)
{
var tokenString = await UsersManager.GenerateJSONWebToken(user, 120);
response = Ok(new { user = user.Data, access_token = tokenString });
}

return response;
}

[AllowAnonymous]
[HttpPost("register")]
[SwaggerResponse(200)]
public async Task<IActionResult> RegisterUser() {
try
{
var result = await NpgSQLDatabaseInterface.ExecuteStored("st_users_register", new { }, null);
return StatusCode(204);
}catch(Exception e)
{
return StatusCode(500, e.Message);
}
}

[Authorize]
[HttpGet("loginWithToken")]
public async Task<IActionResult> LoginWithToken()
{
try
{
var userUid = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
var result = await NpgSQLDatabaseInterface.ExecuteStored("st_users_get_details", new { user_uid = userUid }, null);

return StatusCode(200, JObject.Parse(result));
}
catch (Exception e)
{
return StatusCode(500, e.Message);
}
}
}
}

67 changes: 67 additions & 0 deletions api/Managers/UsersManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using Newtonsoft.Json.Linq;
using System.Security.Claims;
using System.Text;
using TrackBEE.API.Data;
using TrackBEE.API.Models.Users;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;

namespace TrackBEE.API.Managers
{
public static class UsersManager
{
public static async Task<string> GenerateJSONWebToken(UserModel userInfo, int validMinutes)
{
var tokenHandler = new JwtSecurityTokenHandler();
var claims = await CreateClaimsIdentitiesAsync(userInfo);

var token = tokenHandler.CreateJwtSecurityToken(
issuer: Startup.Configuration!["Jwt:Issuer"],
audience: Startup.Configuration!["Jwt:Audience"],
subject: claims,
notBefore: DateTime.UtcNow,
expires: DateTime.UtcNow.AddMinutes(validMinutes),
signingCredentials:
new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Startup.Configuration["Jwt:Key"])), SecurityAlgorithms.HmacSha256Signature)
);

return tokenHandler.WriteToken(token);
}

private static Task<ClaimsIdentity> CreateClaimsIdentitiesAsync(UserModel user)
{
ClaimsIdentity claimsIdentity = new();
claimsIdentity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
claimsIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Uid));
return Task.FromResult(claimsIdentity);
}

public static async Task<UserModel> AuthenticateUser(UserModelRequest login)
{
UserModel user = null;
try
{
var dbResult = await NpgSQLDatabaseInterface.ExecuteStored("st_users_login", new { user_mail = login.Email, user_password = login.Password }, null);
var result = JObject.Parse(dbResult);
if (result.ContainsKey("data"))
{
var userData = result.SelectToken("data");

user = new UserModel()
{
Uid = userData!.SelectToken("user_uid")!.ToString(),
Email = userData!.SelectToken("user_email")!.ToString(),
Data = userData
};
return user;
}
}
catch
{
return null;
}
return user;
}
}
}

11 changes: 11 additions & 0 deletions api/Models/Users/UserModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
namespace TrackBEE.API.Models.Users
{
public class UserModel
{
public string Uid { get; set; }
public string Email { get; set; }
public object Data { get; set; }
}
}

10 changes: 10 additions & 0 deletions api/Models/Users/UserModelRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
namespace TrackBEE.API.Models.Users
{
public class UserModelRequest
{
public string Email { get; set; }
public string Password { get; set; }
}
}

1 change: 0 additions & 1 deletion api/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
"profiles": {
"TrackBEE_API": {
"commandName": "Project",
"launchBrowser": false,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7166;http://localhost:5166",
"environmentVariables": {
Expand Down
34 changes: 31 additions & 3 deletions api/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,41 @@
namespace TrackBEE.API
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

namespace TrackBEE.API
{
public class Startup
{
public static IConfiguration? Configuration { get; private set; }

public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
options.AddPolicy("CorsPolicy",
policy => policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader())
);

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration!["Jwt:Issuer"],
ValidAudience = Configuration!["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});

services.AddControllers().AddNewtonsoftJson();
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();
Expand All @@ -23,14 +48,17 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseDeveloperExceptionPage();
}

app.UseAuthentication();

// Add SwaggerUI
app.UseSwagger();
app.UseSwaggerUI();

app.UseHttpsRedirection();

app.UseRouting();
app.UseCors("CorsPolicy");

app.UseRouting();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
Expand Down
50 changes: 50 additions & 0 deletions api/Templates/ConfirmMail/ConfirmMail.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html
lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="x-apple-disable-message-reformatting">
<title></title>
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<![endif]-->
<style>
table,
td,
div,
h1,
p {
font-family: Arial, sans-serif;
}
table,
td {
border: 2px solid #cccccc !important;
}
</style>
</head>
<body>
<table role="presentation" style="width: 100%;border: 0;border-collapse: collapse;border-spacing: 0;">
<table role="presentation" style="width:602px;border: 0;border-collapse: collapse border-spacing: 0;">
<tr>
<td align="center" style="padding: 0;">
<img src="images/thank-you.png">
</td>
</tr>
<tr>
<td align="center" style="text-align: center;padding: 0;">
Hey! Welcome to Track BEE!
</td>
</tr>
</table>
</table>
</body>
</html>
Binary file added api/Templates/ConfirmMail/images/thank-you.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions api/Templates/ConfirmMail/images/thank-you.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions api/TrackBEE-API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.11" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.4.0" />
</ItemGroup>

<ItemGroup>
<None Remove="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
<None Remove="Models\Users\" />
<None Remove="Microsoft.AspNetCore.Authentication.JwtBearer" />
<None Remove="Swashbuckle.AspNetCore.Annotations" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\Users\" />
</ItemGroup>
</Project>
5 changes: 5 additions & 0 deletions api/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@
}
},
"AllowedHosts": "*",
"Urls": "http://0.0.0.0:8192",
"ConnectionStrings": {
"Default": "Host=127.0.0.1;Username=root;Password=root;Database=TrackBee"
},
"Jwt": {
"Key": "t7w!z%C*F-JaNdRgUkXp2s5u8x/A?D(G+KbPeShVmYq3t6w9y$B&E)H@McQfTjWnZr4u7x!A%C*F-JaNdRgUkXp2s5v8y/B?E(G+KbPeShVmYq3t6w9z$C&F)J@McQfTjWnZr4u7x!A%D*G-KaPdRgUkXp2s5v8y/B?E(H+MbQeThVmYq3t6w9z$C&F)J@NcRfUjXnZr4u7x!A%D*G-KaPdSgVkYp3s5v8y/B?E(H+MbQeThWmZq4t7w9z$C&F)J",
"Issuer": "noreply@track-bee.com"
},
"GithubVersion": {
"Repository": "GhostyJade/track-bee"
}
Expand Down

0 comments on commit 7bb31c8

Please sign in to comment.