aboutsummaryrefslogtreecommitdiff
path: root/src/Common/DevHive.Common
diff options
context:
space:
mode:
authorKamen Mladenov <kamen.d.mladenov@protonmail.com>2021-04-09 19:51:35 +0300
committerGitHub <noreply@github.com>2021-04-09 19:51:35 +0300
commit233f38915ba0079079233eff55434ef349c05c45 (patch)
tree6c5f69017865bcab87355e910c87339453da1406 /src/Common/DevHive.Common
parentf4a70c6430db923af9fa9958a11c2d6612cb52cc (diff)
parenta992357efcf1bc1ece81b95ecee5e05a0b73bfdc (diff)
downloadDevHive-heroku/main.tar
DevHive-heroku/main.tar.gz
DevHive-heroku/main.zip
Merge pull request #28 from Team-Kaleidoscope/devHEADv0.2mainheroku/main
Second stage: Complete
Diffstat (limited to 'src/Common/DevHive.Common')
-rw-r--r--src/Common/DevHive.Common/Constants/ClassesConstants.cs22
-rw-r--r--src/Common/DevHive.Common/Constants/ErrorMessages.cs16
-rw-r--r--src/Common/DevHive.Common/DevHive.Common.csproj11
-rw-r--r--src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs28
-rw-r--r--src/Common/DevHive.Common/Jwt/JwtService.cs86
5 files changed, 163 insertions, 0 deletions
diff --git a/src/Common/DevHive.Common/Constants/ClassesConstants.cs b/src/Common/DevHive.Common/Constants/ClassesConstants.cs
new file mode 100644
index 0000000..825f737
--- /dev/null
+++ b/src/Common/DevHive.Common/Constants/ClassesConstants.cs
@@ -0,0 +1,22 @@
+namespace DevHive.Common.Constants
+{
+ public static class ClassesConstants
+ {
+ public const string Data = "Data";
+
+ public const string Post = "The Post";
+ public const string Comment = "The Comment";
+ public const string User = "The User";
+ public const string Language = "The Language";
+ public const string Picture = "The Picture";
+ public const string Files = "The Files";
+ public const string Rating = "The Rating";
+ public const string Role = "The Role";
+ public const string Technology = "The Technology";
+
+ public const string Username = "The Username";
+ public const string Email = "The Email";
+ public const string Password = "Password";
+ public const string OneOrMoreFriends = "One or more Friends";
+ }
+}
diff --git a/src/Common/DevHive.Common/Constants/ErrorMessages.cs b/src/Common/DevHive.Common/Constants/ErrorMessages.cs
new file mode 100644
index 0000000..30ca544
--- /dev/null
+++ b/src/Common/DevHive.Common/Constants/ErrorMessages.cs
@@ -0,0 +1,16 @@
+namespace DevHive.Common.Constants
+{
+ public static class ErrorMessages
+ {
+ public const string InvalidData = "Invalid {0}!";
+ public const string IncorrectData = "Incorrect {0}!";
+ public const string DoesNotExist = "{0} does not exist!";
+ public const string AlreadyExists = "{0} already exists!";
+
+ public const string CannotAdd = "Could not add {0}!";
+ public const string CannotCreate = "Could not create {0}!";
+ public const string CannotDelete = "Could not delete {0}!";
+ public const string CannotUpload = "Could not upload {0}!";
+ public const string CannotEdit = "Could not edit {0}!";
+ }
+}
diff --git a/src/Common/DevHive.Common/DevHive.Common.csproj b/src/Common/DevHive.Common/DevHive.Common.csproj
new file mode 100644
index 0000000..a5758f4
--- /dev/null
+++ b/src/Common/DevHive.Common/DevHive.Common.csproj
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <ItemGroup>
+ <ProjectReference Include="..\DevHive.Common.Models\DevHive.Common.Models.csproj"/>
+ </ItemGroup>
+ <PropertyGroup>
+ <TargetFramework>net5.0</TargetFramework>
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.10.0"/>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs b/src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs
new file mode 100644
index 0000000..352a7d5
--- /dev/null
+++ b/src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+
+namespace DevHive.Common.Jwt.Interfaces
+{
+ public interface IJwtService
+ {
+ /// <summary>
+ /// The generation of a JWT, when a new user registers or log ins
+ /// Tokens have an expiration time of 7 days.
+ /// </summary>
+ /// <param name="userId">User's Guid</param>
+ /// <param name="username">Users's username</param>
+ /// <param name="roleNames">List of user's roles</param>
+ /// <returns>Return a new JWT, containing the user id, username and roles.</returns>
+ string GenerateJwtToken(Guid userId, string username, List<string> roleNames);
+
+ /// <summary>
+ /// Checks whether the given user, gotten by the "id" property,
+ /// is the same user as the one in the token (unless the user in the token has the admin role)
+ /// and the roles in the token are the same as those in the user, gotten by the id in the token
+ /// </summary>
+ /// <param name="userId">Guid of the user being validated</param>
+ /// <param name="rawToken">The raw token coming from the request</param>
+ /// <returns>Bool result of is the user authenticated to do an action</returns>
+ bool ValidateToken(Guid userId, string rawToken);
+ }
+}
diff --git a/src/Common/DevHive.Common/Jwt/JwtService.cs b/src/Common/DevHive.Common/Jwt/JwtService.cs
new file mode 100644
index 0000000..9f316da
--- /dev/null
+++ b/src/Common/DevHive.Common/Jwt/JwtService.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+using System.Security.Claims;
+using System.Security.Principal;
+using DevHive.Common.Jwt.Interfaces;
+using Microsoft.IdentityModel.Tokens;
+
+namespace DevHive.Common.Jwt
+{
+ public class JwtService : IJwtService
+ {
+ private readonly string _validationIssuer;
+ private readonly string _audience;
+ private readonly byte[] _signingKey;
+
+ public JwtService(byte[] signingKey, string validationIssuer, string audience)
+ {
+ this._signingKey = signingKey;
+ this._validationIssuer = validationIssuer;
+ this._audience = audience;
+ }
+
+ public string GenerateJwtToken(Guid userId, string username, List<string> roleNames)
+ {
+ var securityKey = new SymmetricSecurityKey(this._signingKey);
+ var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
+
+ HashSet<Claim> claims = new()
+ {
+ new Claim("ID", $"{userId}"),
+ new Claim("Username", username)
+ };
+
+ foreach (var roleName in roleNames)
+ claims.Add(new Claim(ClaimTypes.Role, roleName));
+
+ SecurityTokenDescriptor securityTokenDescriptor = new()
+ {
+ Issuer = this._validationIssuer,
+ Audience = this._audience,
+ Subject = new ClaimsIdentity(claims),
+ Expires = DateTime.Today.AddDays(7),
+ SigningCredentials = credentials,
+ };
+
+ JwtSecurityTokenHandler tokenHandler = new();
+ SecurityToken token = tokenHandler.CreateToken(securityTokenDescriptor);
+
+ return tokenHandler.WriteToken(token);
+ }
+
+ public bool ValidateToken(Guid userId, string rawToken)
+ {
+ var tokenHandler = new JwtSecurityTokenHandler();
+ var validationParameters = GetValidationParameters();
+ string actualToken = rawToken.Remove(0, 7);
+
+ IPrincipal principal = tokenHandler.ValidateToken(actualToken, validationParameters, out SecurityToken validatedToken);
+ JwtSecurityToken jwtToken = tokenHandler.ReadJwtToken(actualToken);
+
+ if (!principal.Identity.IsAuthenticated)
+ return false;
+ else if (principal.IsInRole("Admin"))
+ return true;
+ else if (jwtToken.Claims.FirstOrDefault(x => x.Type == "ID").Value != userId.ToString())
+ return false;
+ else
+ return true;
+ }
+
+ private TokenValidationParameters GetValidationParameters()
+ {
+ return new TokenValidationParameters()
+ {
+ ValidateLifetime = true,
+ ValidateAudience = true,
+ ValidateIssuer = true,
+ ValidIssuer = this._validationIssuer,
+ ValidAudience = this._audience,
+ IssuerSigningKey = new SymmetricSecurityKey(this._signingKey)
+ };
+ }
+ }
+}