Skip to content

Commit 993d397

Browse files
committed
# Task - create a new usermanagement service and a new accounts controller
1 parent b329dc7 commit 993d397

15 files changed

+515
-299
lines changed

.vs/DristorApp/xs/UserPrefs.xml

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,66 @@
11
<Properties StartupConfiguration="{193AAE1D-F823-4C79-B325-4AB4EBA0DC37}|Default">
2-
<MonoDevelop.Ide.Workbench ActiveDocument="DristorApp/Controllers/AddressesController.cs">
2+
<MonoDevelop.Ide.Workbench ActiveDocument="DristorApp/Repositories/UserRepository/IUserRepository.cs">
33
<Files>
4-
<File FileName="DristorApp/Data/DTOs/Address/AddressCreateDTO.cs" Line="3" Column="2" />
5-
<File FileName="DristorApp/Migrations/20230201164137_InitialEntities.cs" Line="116" Column="20" />
6-
<File FileName="DristorApp/Migrations/20230201164137_InitialEntities.Designer.cs" Line="52" Column="40" />
7-
<File FileName="DristorApp/Migrations/20230201210706_EditingUserMode3.Designer.cs" Line="52" Column="40" />
8-
<File FileName="DristorApp/Migrations/AppDbContextModelSnapshot.cs" Line="49" Column="40" />
9-
<File FileName="DristorApp/Data/DTOs/Address/AddressUpdateDTO.cs" Line="10" Column="22" />
10-
<File FileName="DristorApp/Data/Models/Address.cs" Line="12" Column="22" />
11-
<File FileName="DristorApp/Controllers/ProductsController.cs" Line="49" Column="28" />
12-
<File FileName="DristorApp/Data/DTOs/Porduct/ProductUpdateDTO.cs" Line="4" Column="18" />
13-
<File FileName="DristorApp/Repositories/BaseRepository/IRepository.cs" Line="4" Column="19" />
14-
<File FileName="DristorApp/Controllers/ProductVariantsController.cs" Line="19" Column="13" />
15-
<File FileName="DristorApp/Controllers/CouponsController.cs" Line="13" Column="43" />
16-
<File FileName="DristorApp/Data/DTOs/Coupon/CouponUpdateDTO.cs" Line="5" Column="3" />
17-
<File FileName="DristorApp/Data/DTOs/Coupon/CouponCreateDTO.cs" Line="1" Column="1" />
18-
<File FileName="DristorApp/Repositories/CouponRepository/ICouponRepository.cs" Line="10" Column="6" />
19-
<File FileName="DristorApp/Repositories/CouponRepository/ImplCouponRepository.cs" Line="15" Column="31" />
20-
<File FileName="DristorApp/Repositories/CartItemRepository/ICartRepository.cs" Line="7" Column="37" />
21-
<File FileName="DristorApp/Repositories/CartItemRepository/ImplCartRepository.cs" Line="39" Column="26" />
22-
<File FileName="DristorApp/Repositories/Roles/ImplRoleRepository.cs" Line="1" Column="1" />
23-
<File FileName="DristorApp/Repositories/UserRepository/ImplUserRepository.cs" Line="1" Column="1" />
24-
<File FileName="DristorApp/Repositories/ProductRepository/ImplProductRepository.cs" Line="1" Column="1" />
25-
<File FileName="DristorApp/Repositories/OrderRepository/ImplOrderRepository.cs" Line="42" Column="2" />
26-
<File FileName="DristorApp/Repositories/OrderRepository/IOrderRepository.cs" Line="11" Column="2" />
27-
<File FileName="DristorApp/Controllers/IngredientsController.cs" Line="8" Column="68" />
28-
<File FileName="DristorApp/Controllers/OrderItemsController.cs" Line="48" Column="76" />
29-
<File FileName="DristorApp/Data/DTOs/Orderitem/OrderItemUpdateDTO.cs" Line="8" Column="42" />
30-
<File FileName="DristorApp/Data/DTOs/Orderitem/OrderItemCreateDTO.cs" Line="7" Column="33" />
31-
<File FileName="DristorApp/Controllers/OrderStatusUpdatesController.cs" Line="82" Column="2" />
32-
<File FileName="DristorApp/Controllers/OrdersController.cs" Line="104" Column="1" />
33-
<File FileName="DristorApp/Data/DTOs/CartItem/CartItemCreateDTO.cs" Line="8" Column="1" />
34-
<File FileName="DristorApp/Data/DTOs/CartItem/CartItemUpdateDTO.cs" Line="1" Column="1" />
35-
<File FileName="DristorApp/Controllers/AddressesController.cs" Line="70" Column="1" />
4+
<File FileName="DristorApp/Data/DTOs/Address/AddressCreateDTO.cs" />
5+
<File FileName="DristorApp/Data/DTOs/Address/AddressUpdateDTO.cs" />
6+
<File FileName="DristorApp/Data/DTOs/CartItem/CartItemCreateDTO.cs" />
7+
<File FileName="DristorApp/Data/DTOs/CartItem/CartItemUpdateDTO.cs" />
8+
<File FileName="DristorApp/Data/DTOs/Coupon/CouponCreateDTO.cs" />
9+
<File FileName="DristorApp/Data/DTOs/Coupon/CouponUpdateDTO.cs" />
10+
<File FileName="DristorApp/Data/DTOs/Order/OrderCreateDTO.cs" />
11+
<File FileName="DristorApp/Data/DTOs/Order/OrderUpdateDTO.cs" />
12+
<File FileName="DristorApp/Data/DTOs/Orderitem/OrderItemCreateDTO.cs" />
13+
<File FileName="DristorApp/Data/DTOs/Orderitem/OrderItemUpdateDTO.cs" />
14+
<File FileName="DristorApp/Data/DTOs/Porduct/ProductCreateDTO.cs" />
15+
<File FileName="DristorApp/Data/DTOs/Porduct/ProductUpdateDTO.cs" />
16+
<File FileName="DristorApp/Data/DTOs/ProductVariant/ProductVariantCreateDTO.cs" />
17+
<File FileName="DristorApp/Data/DTOs/ProductVariant/ProductVariantUpdateDTO.cs" />
18+
<File FileName="DristorApp/Data/DTOs/User/LoginUserDTO.cs" />
19+
<File FileName="DristorApp/Data/DTOs/User/RegisterUserDTO.cs" />
20+
<File FileName="DristorApp/Data/DTOs/User/UserDTO.cs" />
21+
<File FileName="DristorApp/Data/Models/Address.cs" />
22+
<File FileName="DristorApp/Data/Models/CartItem.cs" />
23+
<File FileName="DristorApp/Data/Models/Coupon.cs" />
24+
<File FileName="DristorApp/Data/Models/ErrorViewModel.cs" />
25+
<File FileName="DristorApp/Data/Models/Ingredient.cs" />
26+
<File FileName="DristorApp/Data/Models/Order.cs" />
27+
<File FileName="DristorApp/Data/Models/OrderItem.cs" />
28+
<File FileName="DristorApp/Data/Models/OrderStatusUpdate.cs" />
29+
<File FileName="DristorApp/Data/Models/Product.cs" />
30+
<File FileName="DristorApp/Data/Models/ProductVariant.cs" />
31+
<File FileName="DristorApp/Data/Models/Role.cs" />
32+
<File FileName="DristorApp/Data/Models/Token.cs" />
33+
<File FileName="DristorApp/Data/Models/User.cs" />
34+
<File FileName="DristorApp/Repositories/BaseRepository/ImplRepository.cs" />
35+
<File FileName="DristorApp/Repositories/BaseRepository/IRepository.cs" />
36+
<File FileName="DristorApp/Repositories/CartItemRepository/ICartRepository.cs" />
37+
<File FileName="DristorApp/Repositories/CartItemRepository/ImplCartRepository.cs" />
38+
<File FileName="DristorApp/Repositories/CouponRepository/ICouponRepository.cs" />
39+
<File FileName="DristorApp/Repositories/CouponRepository/ImplCouponRepository.cs" />
40+
<File FileName="DristorApp/Repositories/OrderRepository/ImplOrderRepository.cs" />
41+
<File FileName="DristorApp/Repositories/OrderRepository/IOrderRepository.cs" />
42+
<File FileName="DristorApp/Repositories/ProductRepository/ImplProductRepository.cs" />
43+
<File FileName="DristorApp/Repositories/ProductRepository/IProductRepository.cs" />
44+
<File FileName="DristorApp/Repositories/Roles/ImplRoleRepository.cs" />
45+
<File FileName="DristorApp/Repositories/Roles/IRoleRepository.cs" />
46+
<File FileName="DristorApp/Repositories/UserRepository/ImplUserRepository.cs" />
47+
<File FileName="DristorApp/Repositories/UserRepository/IUserRepository.cs" Line="10" Column="48" />
3648
</Files>
3749
<Pads>
3850
<Pad Id="ProjectPad">
3951
<State name="__root__">
4052
<Node name="DristorApp" expanded="True">
4153
<Node name="DristorApp" expanded="True">
42-
<Node name="Views" expanded="True" />
43-
<Node name="wwwroot" expanded="True" />
54+
<Node name="Controllers" expanded="True" />
55+
<Node name="Data" expanded="True">
56+
<Node name="db" expanded="True" />
57+
<Node name="DTOs" expanded="True">
58+
<Node name="Address" expanded="True" />
59+
</Node>
60+
</Node>
61+
<Node name="Repositories" expanded="True">
62+
<Node name="UserRepository" expanded="True" />
63+
</Node>
4464
</Node>
4565
</Node>
4666
</State>

.vs/DristorApp/xs/project-cache/DristorApp-Debug.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using System;
2+
using System.Security.Claims;
3+
using DristorApp.Data.DTOs.User;
4+
using DristorApp.Data.Models;
5+
using DristorApp.Repositories.UserRepository;
6+
using DristorApp.UserManagementService;
7+
using Microsoft.AspNetCore.Authorization;
8+
using Microsoft.AspNetCore.Identity;
9+
using Microsoft.AspNetCore.Mvc;
10+
11+
namespace DristorApp.Controllers
12+
{
13+
[Route("api/[controller]")]
14+
[ApiController]
15+
public class AccountsController : ControllerBase
16+
{
17+
private readonly UserManager<User> _userManager;
18+
private readonly IUserManagementService _userService;
19+
private readonly IUserRepository _userRepository;
20+
public AccountsController(
21+
UserManager<User> userManager,
22+
IUserManagementService userService,
23+
IUserRepository userRepository)
24+
{
25+
_userManager = userManager;
26+
_userService = userService;
27+
_userRepository = userRepository;
28+
}
29+
30+
[HttpPost("register")]
31+
[AllowAnonymous]
32+
public async Task<IActionResult> Register([FromBody] RegisterUserDTO dto)
33+
{
34+
35+
var user = await _userManager.FindByEmailAsync(dto.Email);
36+
37+
if (user is not null)
38+
{
39+
return BadRequest("This email already in use");
40+
}
41+
42+
var result = await _userService.RegisterUserAsync(dto);
43+
if (result.Succeeded)
44+
{
45+
46+
return Ok(result);
47+
}
48+
return BadRequest(result.Errors.ToList());
49+
}
50+
[HttpPost("login")]
51+
[AllowAnonymous]
52+
public async Task<IActionResult> Login([FromBody] LoginUserDTO dto)
53+
{
54+
var token = await _userService.LoginUserAsync(dto);
55+
56+
if (token is null)
57+
{
58+
return Unauthorized();
59+
}
60+
61+
return Ok(token);
62+
}
63+
[HttpGet("me")]
64+
[Authorize]
65+
public async Task<ActionResult<UserDTO>> GetCurrentUser()
66+
{
67+
var id = User.FindFirstValue(ClaimTypes.NameIdentifier);
68+
var user = await _userRepository.GetByIdAsync(int.Parse(id));
69+
if (user is null)
70+
{
71+
return NotFound();
72+
}
73+
74+
return new UserDTO
75+
{
76+
Id = user.Id,
77+
Email = user.Email,
78+
FirstName = user.FirstName,
79+
LastName = user.LastName,
80+
Roles = user.Roles.Select(x => x.Name).ToList(),
81+
Addresses = user.Addresses.Select(x => x.Id).ToList()
82+
};
83+
}
84+
}
85+
}
86+

DristorApp/DristorApp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<None Remove="Repositories\CartItemRepository\" />
4343

4444

45+
<None Remove="UserManagementService\" />
4546
</ItemGroup>
4647
<ItemGroup>
4748
<Folder Include="Data\" />
@@ -67,6 +68,7 @@
6768
<Folder Include="Repositories\CartItemRepository\" />
6869

6970

71+
<Folder Include="UserManagementService\" />
7072
</ItemGroup>
7173
<ItemGroup>
7274
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.2" />
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
using DristorApp.Data.DTOs.User;
3+
using Microsoft.AspNetCore.Identity;
4+
5+
namespace DristorApp.UserManagementService
6+
{
7+
8+
public interface IUserManagementService
9+
{
10+
public Task<IdentityResult> RegisterUserAsync(RegisterUserDTO dto);
11+
public Task<string?> LoginUserAsync(LoginUserDTO dto);
12+
}
13+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using System;
2+
using System.IdentityModel.Tokens.Jwt;
3+
using System.Security.Claims;
4+
using System.Text;
5+
using DristorApp.Data.DTOs.User;
6+
using DristorApp.Data.Models;
7+
using DristorApp.Repositories.BaseRepository;
8+
using DristorApp.Repositories.Roles;
9+
using DristorApp.Repositories.UserRepository;
10+
using Microsoft.AspNetCore.Identity;
11+
using Microsoft.IdentityModel.Tokens;
12+
13+
namespace DristorApp.UserManagementService
14+
{
15+
public class ImplUserManagementService : IUserManagementService
16+
{
17+
private readonly IConfiguration _configuration;
18+
private readonly UserManager<User> _userManager;
19+
private readonly IUserRepository _userRepository;
20+
private readonly IRepository<Token, string> _tokenRepository;
21+
private readonly IRoleRepository _roleRepository;
22+
23+
public ImplUserManagementService(
24+
IConfiguration configuration,
25+
UserManager<User> userManager,
26+
IUserRepository userRepository,
27+
IRepository<Token, string> tokenRepository,
28+
IRoleRepository roleRepository)
29+
{
30+
_configuration = configuration;
31+
_userManager = userManager;
32+
_userRepository = userRepository;
33+
_tokenRepository = tokenRepository;
34+
_roleRepository = roleRepository;
35+
}
36+
37+
public async Task<IdentityResult> RegisterUserAsync(RegisterUserDTO dto)
38+
{
39+
var customerRole = await _roleRepository.GetRoleByNameAsync("Customer");
40+
if (customerRole is null)
41+
{
42+
throw new Exception("Customer role not found.");
43+
}
44+
45+
var user = new User
46+
{
47+
Email = dto.Email,
48+
UserName = dto.Email,
49+
FirstName = dto.FirstName,
50+
LastName = dto.LastName,
51+
Roles = new List<Role> { customerRole }
52+
};
53+
54+
return await _userManager.CreateAsync(user, dto.Password);
55+
}
56+
57+
public async Task<string?> LoginUserAsync(LoginUserDTO dto)
58+
{
59+
var user = await _userManager.FindByEmailAsync(dto.Email);
60+
61+
if (user is null) return null;
62+
63+
if (!await _userManager.CheckPasswordAsync(user, dto.Password)) return null;
64+
65+
user = await _userRepository.GetUserByIdAndRolesAsync(user.Id);
66+
67+
var jti = Guid.NewGuid().ToString();
68+
var tokenHandler = new JwtSecurityTokenHandler();
69+
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.GetSection("Jwt:Secret").Value));
70+
71+
var token = GenerateJwtToken(signingKey, user, user.Roles, tokenHandler, jti);
72+
73+
var tokenModel = new Token
74+
{
75+
Jti = jti,
76+
User = user,
77+
ExpirationDate = token.ValidTo
78+
};
79+
await _tokenRepository.CreateAsync(tokenModel);
80+
81+
return tokenHandler.WriteToken(token);
82+
}
83+
84+
private SecurityToken GenerateJwtToken(SymmetricSecurityKey signingKey, User user, IEnumerable<Role> roles,
85+
JwtSecurityTokenHandler tokenHandler, string jti)
86+
{
87+
var subject = new ClaimsIdentity(new Claim[]
88+
{
89+
new(ClaimTypes.Email, user.Email),
90+
new(ClaimTypes.Name, $"{user.FirstName} {user.LastName}"),
91+
new(ClaimTypes.NameIdentifier, user.Id.ToString()),
92+
new(JwtRegisteredClaimNames.Jti, jti)
93+
});
94+
95+
foreach (var role in roles)
96+
{
97+
subject.AddClaim(new Claim(ClaimTypes.Role, role.Name));
98+
}
99+
100+
var tokenDescriptor = new SecurityTokenDescriptor
101+
{
102+
Subject = subject,
103+
Expires = DateTime.Now.AddDays(1),
104+
SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
105+
};
106+
107+
return tokenHandler.CreateToken(tokenDescriptor);
108+
}
109+
}
110+
}

DristorApp/obj/Debug/net7.0/DristorApp.AssemblyInfo.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//------------------------------------------------------------------------------
22
// <auto-generated>
33
// This code was generated by a tool.
4-
// Runtime Version:4.0.30319.42000
54
//
65
// Changes to this file may cause incorrect behavior and will be lost if
76
// the code is regenerated.

DristorApp/obj/Debug/net7.0/DristorApp.GeneratedMSBuildEditorConfig.editorconfig

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,37 @@ build_property.EnforceExtendedAnalyzerRules =
99
build_property._SupportedPlatformList = Linux,macOS,Windows
1010
build_property.RootNamespace = DristorApp
1111
build_property.RootNamespace = DristorApp
12-
build_property.ProjectDir = C:\Users\Dell\Source\Repos\DristorApp\DristorApp\
12+
build_property.ProjectDir = /Users/nabil.alhafez/Univeristetea/Anul_2/DristorApp/DristorApp/
1313
build_property.RazorLangVersion = 7.0
1414
build_property.SupportLocalizedComponentNames =
1515
build_property.GenerateRazorMetadataSourceChecksumAttributes =
16-
build_property.MSBuildProjectDirectory = C:\Users\Dell\Source\Repos\DristorApp\DristorApp
16+
build_property.MSBuildProjectDirectory = /Users/nabil.alhafez/Univeristetea/Anul_2/DristorApp/DristorApp
1717
build_property._RazorSourceGeneratorDebug =
1818

19-
[C:/Users/Dell/Source/Repos/DristorApp/DristorApp/Views/Home/Index.cshtml]
20-
build_metadata.AdditionalFiles.TargetPath = Vmlld3NcSG9tZVxJbmRleC5jc2h0bWw=
19+
[/Users/nabil.alhafez/Univeristetea/Anul_2/DristorApp/DristorApp/Views/Home/Index.cshtml]
20+
build_metadata.AdditionalFiles.TargetPath = Vmlld3MvSG9tZS9JbmRleC5jc2h0bWw=
2121
build_metadata.AdditionalFiles.CssScope =
2222

23-
[C:/Users/Dell/Source/Repos/DristorApp/DristorApp/Views/Home/Privacy.cshtml]
24-
build_metadata.AdditionalFiles.TargetPath = Vmlld3NcSG9tZVxQcml2YWN5LmNzaHRtbA==
23+
[/Users/nabil.alhafez/Univeristetea/Anul_2/DristorApp/DristorApp/Views/Home/Privacy.cshtml]
24+
build_metadata.AdditionalFiles.TargetPath = Vmlld3MvSG9tZS9Qcml2YWN5LmNzaHRtbA==
2525
build_metadata.AdditionalFiles.CssScope =
2626

27-
[C:/Users/Dell/Source/Repos/DristorApp/DristorApp/Views/Shared/Error.cshtml]
28-
build_metadata.AdditionalFiles.TargetPath = Vmlld3NcU2hhcmVkXEVycm9yLmNzaHRtbA==
27+
[/Users/nabil.alhafez/Univeristetea/Anul_2/DristorApp/DristorApp/Views/Shared/Error.cshtml]
28+
build_metadata.AdditionalFiles.TargetPath = Vmlld3MvU2hhcmVkL0Vycm9yLmNzaHRtbA==
2929
build_metadata.AdditionalFiles.CssScope =
3030

31-
[C:/Users/Dell/Source/Repos/DristorApp/DristorApp/Views/Shared/_ValidationScriptsPartial.cshtml]
32-
build_metadata.AdditionalFiles.TargetPath = Vmlld3NcU2hhcmVkXF9WYWxpZGF0aW9uU2NyaXB0c1BhcnRpYWwuY3NodG1s
31+
[/Users/nabil.alhafez/Univeristetea/Anul_2/DristorApp/DristorApp/Views/Shared/_ValidationScriptsPartial.cshtml]
32+
build_metadata.AdditionalFiles.TargetPath = Vmlld3MvU2hhcmVkL19WYWxpZGF0aW9uU2NyaXB0c1BhcnRpYWwuY3NodG1s
3333
build_metadata.AdditionalFiles.CssScope =
3434

35-
[C:/Users/Dell/Source/Repos/DristorApp/DristorApp/Views/_ViewImports.cshtml]
36-
build_metadata.AdditionalFiles.TargetPath = Vmlld3NcX1ZpZXdJbXBvcnRzLmNzaHRtbA==
35+
[/Users/nabil.alhafez/Univeristetea/Anul_2/DristorApp/DristorApp/Views/_ViewImports.cshtml]
36+
build_metadata.AdditionalFiles.TargetPath = Vmlld3MvX1ZpZXdJbXBvcnRzLmNzaHRtbA==
3737
build_metadata.AdditionalFiles.CssScope =
3838

39-
[C:/Users/Dell/Source/Repos/DristorApp/DristorApp/Views/_ViewStart.cshtml]
40-
build_metadata.AdditionalFiles.TargetPath = Vmlld3NcX1ZpZXdTdGFydC5jc2h0bWw=
39+
[/Users/nabil.alhafez/Univeristetea/Anul_2/DristorApp/DristorApp/Views/_ViewStart.cshtml]
40+
build_metadata.AdditionalFiles.TargetPath = Vmlld3MvX1ZpZXdTdGFydC5jc2h0bWw=
4141
build_metadata.AdditionalFiles.CssScope =
4242

43-
[C:/Users/Dell/Source/Repos/DristorApp/DristorApp/Views/Shared/_Layout.cshtml]
44-
build_metadata.AdditionalFiles.TargetPath = Vmlld3NcU2hhcmVkXF9MYXlvdXQuY3NodG1s
45-
build_metadata.AdditionalFiles.CssScope = b-v0yonmmaoi
43+
[/Users/nabil.alhafez/Univeristetea/Anul_2/DristorApp/DristorApp/Views/Shared/_Layout.cshtml]
44+
build_metadata.AdditionalFiles.TargetPath = Vmlld3MvU2hhcmVkL19MYXlvdXQuY3NodG1s
45+
build_metadata.AdditionalFiles.CssScope = b-8dyht51g8r
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)