From b7265f3b74a87b4fd17781bf152da2353ac8517d Mon Sep 17 00:00:00 2001
From: Mahdi Jafari <126339078+mahdijafariii@users.noreply.github.com>
Date: Tue, 13 Aug 2024 15:36:02 +0330
Subject: [PATCH] fix(User):fix login (#3)
---
.../AnalysisData.sln.DotSettings.user | 3 +
.../Controllers/UserController.cs | 22 ++++++
.../CookieService/CookieService.cs | 45 ++++++++++++
.../abstractions/ICookieService.cs | 8 +++
.../AnalysisData/JwtService/JwtService.cs | 2 +-
.../JwtService/abstractions/IJwtService.cs | 6 ++
.../AnalysisData/Resources.Designer.cs | 71 +++++++++++++++++++
AnalysisData/AnalysisData/Resources.resx | 24 +++++++
.../AnalysisData/Services/IUserService.cs | 8 +++
.../AnalysisData/Services/UserService.cs | 34 +++++----
10 files changed, 207 insertions(+), 16 deletions(-)
create mode 100644 AnalysisData/AnalysisData.sln.DotSettings.user
create mode 100644 AnalysisData/AnalysisData/Controllers/UserController.cs
create mode 100644 AnalysisData/AnalysisData/CookieService/CookieService.cs
create mode 100644 AnalysisData/AnalysisData/CookieService/abstractions/ICookieService.cs
create mode 100644 AnalysisData/AnalysisData/JwtService/abstractions/IJwtService.cs
create mode 100644 AnalysisData/AnalysisData/Resources.Designer.cs
create mode 100644 AnalysisData/AnalysisData/Resources.resx
create mode 100644 AnalysisData/AnalysisData/Services/IUserService.cs
diff --git a/AnalysisData/AnalysisData.sln.DotSettings.user b/AnalysisData/AnalysisData.sln.DotSettings.user
new file mode 100644
index 0000000..d864046
--- /dev/null
+++ b/AnalysisData/AnalysisData.sln.DotSettings.user
@@ -0,0 +1,3 @@
+
+ True
+ True
\ No newline at end of file
diff --git a/AnalysisData/AnalysisData/Controllers/UserController.cs b/AnalysisData/AnalysisData/Controllers/UserController.cs
new file mode 100644
index 0000000..8071e3f
--- /dev/null
+++ b/AnalysisData/AnalysisData/Controllers/UserController.cs
@@ -0,0 +1,22 @@
+using AnalysisData.Services;
+using AnalysisData.UserManage.LoginModel;
+using Microsoft.AspNetCore.Mvc;
+
+namespace AnalysisData.Controllers;
+[ApiController]
+[Route("api/[controller]")]
+public class UserController : ControllerBase
+{
+ private readonly IUserService _userService;
+
+ public UserController(IUserService userService)
+ {
+ _userService = userService;
+ }
+ [HttpPost("login")]
+ public IActionResult Login([FromBody] UserLoginModel userLoginModel)
+ {
+ var userRoles = _userService.Login(userLoginModel);
+ return Ok(new { roles = userRoles });
+ }
+}
\ No newline at end of file
diff --git a/AnalysisData/AnalysisData/CookieService/CookieService.cs b/AnalysisData/AnalysisData/CookieService/CookieService.cs
new file mode 100644
index 0000000..5719a64
--- /dev/null
+++ b/AnalysisData/AnalysisData/CookieService/CookieService.cs
@@ -0,0 +1,45 @@
+using AnalysisData.CookieSevice.abstractions;
+
+namespace AnalysisData.CookieSevice;
+
+public class CookieService : ICookieService
+{
+ private readonly IHttpContextAccessor _httpContextAccessor;
+
+ public CookieService(IHttpContextAccessor httpContextAccessor)
+ {
+ _httpContextAccessor = httpContextAccessor;
+ }
+
+ public void SetCookie(string name, string token,bool rememberMe)
+ {
+ var options = new CookieOptions
+ {
+ HttpOnly = true,
+ Secure = true,
+ SameSite = SameSiteMode.Strict
+ };
+
+ if (rememberMe)
+ {
+ options.Expires = DateTimeOffset.UtcNow.AddDays(7);
+ }
+ else
+ {
+ options.IsEssential = true;
+ }
+
+ _httpContextAccessor.HttpContext.Response.Cookies.Append(name, token, options);
+ }
+
+ public string GetCookie(string name)
+ {
+ _httpContextAccessor.HttpContext.Request.Cookies.TryGetValue(name, out var value);
+ return value;
+ }
+
+ public void RemoveCookie(string name)
+ {
+ _httpContextAccessor.HttpContext.Response.Cookies.Delete(name);
+ }
+}
\ No newline at end of file
diff --git a/AnalysisData/AnalysisData/CookieService/abstractions/ICookieService.cs b/AnalysisData/AnalysisData/CookieService/abstractions/ICookieService.cs
new file mode 100644
index 0000000..701f4e6
--- /dev/null
+++ b/AnalysisData/AnalysisData/CookieService/abstractions/ICookieService.cs
@@ -0,0 +1,8 @@
+namespace AnalysisData.CookieSevice.abstractions;
+
+public interface ICookieService
+{
+ void RemoveCookie(string name);
+ string GetCookie(string name);
+ void SetCookie(string name, string token,bool rememberMe);
+}
\ No newline at end of file
diff --git a/AnalysisData/AnalysisData/JwtService/JwtService.cs b/AnalysisData/AnalysisData/JwtService/JwtService.cs
index 93ec7ca..160df06 100644
--- a/AnalysisData/AnalysisData/JwtService/JwtService.cs
+++ b/AnalysisData/AnalysisData/JwtService/JwtService.cs
@@ -7,7 +7,7 @@
namespace Authentication;
-public class JwtService
+public class JwtService : IJwtService
{
private readonly IConfiguration _configuration;
private readonly IUserRepository _userRepository;
diff --git a/AnalysisData/AnalysisData/JwtService/abstractions/IJwtService.cs b/AnalysisData/AnalysisData/JwtService/abstractions/IJwtService.cs
new file mode 100644
index 0000000..c18da56
--- /dev/null
+++ b/AnalysisData/AnalysisData/JwtService/abstractions/IJwtService.cs
@@ -0,0 +1,6 @@
+namespace AnalysisData.JwtService;
+
+public interface IJwtService
+{
+ Task GenerateJwtToken(string userName);
+}
\ No newline at end of file
diff --git a/AnalysisData/AnalysisData/Resources.Designer.cs b/AnalysisData/AnalysisData/Resources.Designer.cs
new file mode 100644
index 0000000..959f03e
--- /dev/null
+++ b/AnalysisData/AnalysisData/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace AnalysisData {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AnalysisData.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to user not found ! .
+ ///
+ internal static string NotFoundUserException {
+ get {
+ return ResourceManager.GetString("NotFoundUserException", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/AnalysisData/AnalysisData/Resources.resx b/AnalysisData/AnalysisData/Resources.resx
new file mode 100644
index 0000000..ec6f011
--- /dev/null
+++ b/AnalysisData/AnalysisData/Resources.resx
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ user not found !
+
+
\ No newline at end of file
diff --git a/AnalysisData/AnalysisData/Services/IUserService.cs b/AnalysisData/AnalysisData/Services/IUserService.cs
new file mode 100644
index 0000000..04cf146
--- /dev/null
+++ b/AnalysisData/AnalysisData/Services/IUserService.cs
@@ -0,0 +1,8 @@
+using AnalysisData.UserManage.LoginModel;
+
+namespace AnalysisData.Services;
+
+public interface IUserService
+{
+ Task> Login(UserLoginModel userLoginModel);
+}
\ No newline at end of file
diff --git a/AnalysisData/AnalysisData/Services/UserService.cs b/AnalysisData/AnalysisData/Services/UserService.cs
index e0eab5f..32282f5 100644
--- a/AnalysisData/AnalysisData/Services/UserService.cs
+++ b/AnalysisData/AnalysisData/Services/UserService.cs
@@ -1,4 +1,7 @@
+using AnalysisData.CookieSevice.abstractions;
using AnalysisData.Data;
+using AnalysisData.JwtService;
+using AnalysisData.Repository.RoleRepository.Abstraction;
using AnalysisData.Repository.UserRepository.Abstraction;
using AnalysisData.UserManage.LoginModel;
using Microsoft.AspNetCore.Http.HttpResults;
@@ -6,35 +9,36 @@
namespace AnalysisData.Services;
-public class UserService : ControllerBase
+public class UserService : IUserService
{
private readonly IUserRepository _userRepository;
+ private readonly ICookieService _cookieService;
+ private readonly IJwtService _jwtService;
- public UserService(IUserRepository userRepository)
+ public UserService(IUserRepository userRepository, ICookieService cookieService,IJwtService jwtService)
{
_userRepository = userRepository;
+ _cookieService = cookieService;
+ _jwtService = jwtService;
}
- public async Task Login([FromBody] UserLoginModel userLoginModel)
+ public async Task> Login(UserLoginModel userLoginModel)
{
- var user = await _userRepository.GetUser(userLoginModel.userName);
- if (user is null)
+ if (userLoginModel.userName.Length > 255)
{
- return NotFound($"Unable to load user with username '{userLoginModel.userName}'");
+ return null;
}
-
- if (user.Password != userLoginModel.password)
+ var user = await _userRepository.GetUser(userLoginModel.userName);
+ if (user == null || user.Password != userLoginModel.password)
{
- return Unauthorized("Invalid username or password.");
+ return null;
}
+ var token = await _jwtService.GenerateJwtToken(userLoginModel.userName);
- return Ok(new
- {
- Massage = "welcome",
- Token = "سشی"
- });
-
+ _cookieService.SetCookie("AuthToken", token, userLoginModel.rememberMe);
+ var roles = user.UserRoles.Select(ur => ur.Role.RoleName).ToList();
+ return roles;
}
}
\ No newline at end of file