Skip to content

Commit

Permalink
feat(user): structure of authentication User added (#1)
Browse files Browse the repository at this point in the history
* Feat(User): �Implement User classes and database migration

* Feat(User):change project architecture

* Feat(User):Implement logic to UserManager

* Feat(User): some changes were made in user classes and database.

* fix(User):add jwt class and service

* fix(User):add jwt class and service

* fix(User):add jwt class and service

* fix(User):add jwt class and service

* fix(User):add jwt class and service

* fix(User):add jwt class and service

* fix(User):add jwt class and service

* feat(User): Implement UserRoleRepository.

* feat(User):add sevices

---------

Co-authored-by: AmirReza <[email protected]>
Co-authored-by: K-Kabiri <[email protected]>
  • Loading branch information
3 people authored Aug 13, 2024
1 parent 7b07053 commit ace1ace
Show file tree
Hide file tree
Showing 28 changed files with 874 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea/
bin/
obj/
22 changes: 22 additions & 0 deletions AnalysisData/AnalysisData.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnalysisData", "AnalysisData\AnalysisData.csproj", "{1AC76299-2D1E-4438-B67B-AA6315B6B781}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "TestProject\TestProject.csproj", "{9AEC1F3F-B1B3-47C1-82D4-E432E2D77E0E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1AC76299-2D1E-4438-B67B-AA6315B6B781}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1AC76299-2D1E-4438-B67B-AA6315B6B781}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1AC76299-2D1E-4438-B67B-AA6315B6B781}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1AC76299-2D1E-4438-B67B-AA6315B6B781}.Release|Any CPU.Build.0 = Release|Any CPU
{9AEC1F3F-B1B3-47C1-82D4-E432E2D77E0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9AEC1F3F-B1B3-47C1-82D4-E432E2D77E0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9AEC1F3F-B1B3-47C1-82D4-E432E2D77E0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9AEC1F3F-B1B3-47C1-82D4-E432E2D77E0E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
29 changes: 29 additions & 0 deletions AnalysisData/AnalysisData/AnalysisData.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="JWT" Version="10.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.7" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.7" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
<Folder Include="Repository\" />
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions AnalysisData/AnalysisData/AnalysisData.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@AnalysisData_HostAddress = http://localhost:5000

GET {{AnalysisData_HostAddress}}/weatherforecast/
Accept: application/json

###
17 changes: 17 additions & 0 deletions AnalysisData/AnalysisData/Data/ApplicationDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using AnalysisData.UserManage.Model;
using Microsoft.EntityFrameworkCore;

namespace AnalysisData.Data;

public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}

public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<UserRole> UserRoles { get; set; }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Mvc;

namespace AnalysisData.JwtService.Controllers;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly JwtService _jwtService;

public AuthController(JwtService jwtService)
{
_jwtService = jwtService;
}
[HttpPost("token")]
public async Task<IActionResult> GenerateToken([FromBody] string username)

Check warning on line 16 in AnalysisData/AnalysisData/JwtService/Controllers/IdentifyControllers.cs

View workflow job for this annotation

GitHub Actions / test

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
var token = _jwtService.GenerateJwtToken(username);
return Ok(new { Token = token });
}

}
49 changes: 49 additions & 0 deletions AnalysisData/AnalysisData/JwtService/JwtService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using AnalysisData.Repository.RoleRepository.Abstraction;
using AnalysisData.Repository.UserRepository.Abstraction;
using Microsoft.IdentityModel.Tokens;

namespace AnalysisData.JwtService;

public class JwtService
{
private readonly IConfiguration _configuration;
private readonly IUserRepository _userRepository;
private readonly IRoleRepository _roleRepository;


public JwtService(IConfiguration configuration , IUserRepository userRepository,IRoleRepository roleRepository)
{
_configuration = configuration;
_userRepository = userRepository;
_roleRepository = roleRepository;
}

public async Task<string> GenerateJwtToken(string userName)
{
var user =await _userRepository.GetUser(userName);
var roles = user.UserRoles;
var claims = new List<Claim>
{
new Claim("Name", userName),
};
foreach (var role in roles)
{
var result = await _roleRepository.GetRole(role.Id);
claims.Add(new Claim("Roles", result.RoleName));
}

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));

Check warning on line 38 in AnalysisData/AnalysisData/JwtService/JwtService.cs

View workflow job for this annotation

GitHub Actions / test

Possible null reference argument for parameter 's' in 'byte[] Encoding.GetBytes(string s)'.
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var token = new JwtSecurityToken(
claims: claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);

return new JwtSecurityTokenHandler().WriteToken(token);
}

}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;

#nullable disable

namespace AnalysisData.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Roles",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RoleName = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Roles", x => x.Id);
});

migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Username = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
Password = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});

migrationBuilder.CreateTable(
name: "UserRoles",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
UserId = table.Column<int>(type: "integer", nullable: false),
RoleId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserRoles", x => x.Id);
table.ForeignKey(
name: "FK_UserRoles_Roles_RoleId",
column: x => x.RoleId,
principalTable: "Roles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_UserRoles_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});

migrationBuilder.CreateIndex(
name: "IX_UserRoles_RoleId",
table: "UserRoles",
column: "RoleId");

migrationBuilder.CreateIndex(
name: "IX_UserRoles_UserId",
table: "UserRoles",
column: "UserId");
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "UserRoles");

migrationBuilder.DropTable(
name: "Roles");

migrationBuilder.DropTable(
name: "Users");
}
}
}
Loading

0 comments on commit ace1ace

Please sign in to comment.