(feature): user authentication init
This commit is contained in:
parent
4abe7718eb
commit
8fc1611d9b
@ -7,25 +7,26 @@
|
|||||||
"created": {
|
"created": {
|
||||||
"$date": "2022-01-01T00:00:00.000Z"
|
"$date": "2022-01-01T00:00:00.000Z"
|
||||||
},
|
},
|
||||||
"nickaName": "hailstrike",
|
"nickaName": "admin",
|
||||||
"passwords": {
|
"passwords": {
|
||||||
"pwHash": "",
|
"password": {
|
||||||
"pwSalt": "",
|
"hash": "pznndK3nv9bftf/qQxqBy4VjH7Ow9vx2Kd6376oJuqQ=",
|
||||||
|
"salt": "gkEl1zxGJSLue262mUu5VA==",
|
||||||
"created": {
|
"created": {
|
||||||
"$date": "2022-01-01T00:00:00.000Z"
|
"$date": "2022-01-01T00:00:00.000Z"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"expiration": {
|
"expiration": {
|
||||||
"$date": "2023-01-01T00:00:00.000Z"
|
"enabled": false,
|
||||||
|
"days": "180"
|
||||||
},
|
},
|
||||||
"expired": [
|
"expired": [
|
||||||
{
|
{
|
||||||
"pwHash": "",
|
"hash": "",
|
||||||
"pwSalt": "",
|
"salt": "",
|
||||||
"created": {
|
"created": {
|
||||||
"$date": "2022-01-01T00:00:00.000Z"
|
"$date": "2022-01-01T00:00:00.000Z"
|
||||||
},
|
|
||||||
"expiration": {
|
|
||||||
"$date": "2023-01-01T00:00:00.000Z"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -35,7 +36,7 @@
|
|||||||
"contacts": [
|
"contacts": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "john.doe@maks-it.com",
|
"value": "john.doe@contoso.com",
|
||||||
"confirmed": false
|
"confirmed": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -21,7 +21,7 @@ namespace Core.DomainObjects {
|
|||||||
|
|
||||||
public Address ShippingAddress { get; set; }
|
public Address ShippingAddress { get; set; }
|
||||||
|
|
||||||
public List<string> Tokens { get; set; }
|
public List<Token> Tokens { get; set; }
|
||||||
|
|
||||||
public override int GetHashCode() {
|
public override int GetHashCode() {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
24
webapi/Core/DomainObjects/Password.cs
Normal file
24
webapi/Core/DomainObjects/Password.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using Core.Abstractions.DomainObjects;
|
||||||
|
|
||||||
|
namespace Core.DomainObjects {
|
||||||
|
public class Password : DomainObjectBase<Password> {
|
||||||
|
|
||||||
|
public string Hash { get; set; }
|
||||||
|
|
||||||
|
public string Salt { get; set; }
|
||||||
|
|
||||||
|
public DateTime Created { get; set; }
|
||||||
|
|
||||||
|
public Password(string hash, string salt, DateTime? created) {
|
||||||
|
Hash = hash;
|
||||||
|
Salt = salt;
|
||||||
|
Created = created ?? DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Password Prototype() => new (Hash, Salt, Created);
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
webapi/Core/DomainObjects/PasswordExpiration.cs
Normal file
17
webapi/Core/DomainObjects/PasswordExpiration.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Core.Abstractions.DomainObjects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Core.DomainObjects {
|
||||||
|
public class PasswordExpiration : DomainObjectBase<PasswordExpiration> {
|
||||||
|
public bool Enabled { get; set; }
|
||||||
|
public int Days { get; set; }
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,17 +6,14 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Core.DomainObjects {
|
namespace Core.DomainObjects {
|
||||||
|
|
||||||
public class Passwords : DomainObjectBase<Passwords> {
|
public class Passwords : DomainObjectBase<Passwords> {
|
||||||
|
|
||||||
public string PwHash { get; set; }
|
public Password? Password { get; set; }
|
||||||
|
|
||||||
public string PwSalt { get; set; }
|
public PasswordExpiration Expiration { get; set; }
|
||||||
|
|
||||||
public DateTime Created { get; set; }
|
public List<Password> Expired { get; set; }
|
||||||
|
|
||||||
public DateTime? Expiration { get; set; }
|
|
||||||
|
|
||||||
public List<Passwords> Expired { get; set; }
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
public override int GetHashCode() {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
20
webapi/Core/DomainObjects/Token.cs
Normal file
20
webapi/Core/DomainObjects/Token.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using Core.Abstractions.DomainObjects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Core.DomainObjects {
|
||||||
|
public class Token : DomainObjectBase<Token> {
|
||||||
|
|
||||||
|
public string Value { get; set; }
|
||||||
|
|
||||||
|
public DateTime Created { get; set; }
|
||||||
|
public DateTime Expires { get; set; }
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,6 +21,7 @@ namespace DataProviders.Collections {
|
|||||||
|
|
||||||
public class ShopCartDataProvider : CollectionDataProviderBase<ShopCartItem>, IShopCartDataProvider {
|
public class ShopCartDataProvider : CollectionDataProviderBase<ShopCartItem>, IShopCartDataProvider {
|
||||||
private const string _collectionName = "shopcart";
|
private const string _collectionName = "shopcart";
|
||||||
|
|
||||||
public ShopCartDataProvider(
|
public ShopCartDataProvider(
|
||||||
ILogger<CollectionDataProviderBase<ShopCartItem>> logger,
|
ILogger<CollectionDataProviderBase<ShopCartItem>> logger,
|
||||||
IMongoClient client,
|
IMongoClient client,
|
||||||
|
|||||||
@ -1,4 +1,10 @@
|
|||||||
using System;
|
using Core.DomainObjects;
|
||||||
|
using DataProviders.Abstractions;
|
||||||
|
using DomainResults.Common;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MongoDB.Bson.Serialization;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -7,11 +13,38 @@ using System.Threading.Tasks;
|
|||||||
namespace DataProviders.Collections {
|
namespace DataProviders.Collections {
|
||||||
|
|
||||||
public interface IUserDataProvider {
|
public interface IUserDataProvider {
|
||||||
|
(User?, IDomainResult) Get(Guid userId);
|
||||||
|
|
||||||
|
(User?, IDomainResult) GetByNickName(string nickName);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class UserDataProvider : IUserDataProvider {
|
public class UserDataProvider : CollectionDataProviderBase<User>, IUserDataProvider {
|
||||||
|
|
||||||
|
private const string _collectionName = "users";
|
||||||
|
|
||||||
|
public UserDataProvider(
|
||||||
|
ILogger<UserDataProvider> logger,
|
||||||
|
IMongoClient client,
|
||||||
|
IIdGenerator idGenerator,
|
||||||
|
ISessionService sessionService) : base(logger, client, idGenerator, sessionService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public (User?, IDomainResult) Get( Guid userId) {
|
||||||
|
var (list, result) = GetWithPredicate(x => x.Id == userId, _collectionName);
|
||||||
|
|
||||||
|
if (!result.IsSuccess || list == null)
|
||||||
|
return (null, result);
|
||||||
|
|
||||||
|
return (list.First(), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public (User?, IDomainResult) GetByNickName(string nickName) {
|
||||||
|
var (list, result) = GetWithPredicate(x => x.NickName == nickName, _collectionName);
|
||||||
|
|
||||||
|
if (!result.IsSuccess || list == null)
|
||||||
|
return (null, result);
|
||||||
|
|
||||||
|
return (list.First(), result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,11 +7,11 @@ namespace JWTService {
|
|||||||
|
|
||||||
public interface IJwtConfig {
|
public interface IJwtConfig {
|
||||||
public string? Secret { get; set; }
|
public string? Secret { get; set; }
|
||||||
public double? Expires { get; set; }
|
public int? Expires { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class JwtConfig : IJwtConfig {
|
public class JwtConfig : IJwtConfig {
|
||||||
public string? Secret { get; set; }
|
public string? Secret { get; set; }
|
||||||
public double? Expires { get; set; }
|
public int? Expires { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,87 +1,66 @@
|
|||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using DomainResults.Common;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
|
||||||
namespace JWTService {
|
namespace JWTService {
|
||||||
|
|
||||||
public interface IJWTService {
|
public interface IJWTService {
|
||||||
string CreateJwtToken();
|
|
||||||
JwtSecurityToken ReadJwtToken(string token);
|
string CreateJwtToken(DateTime expires, List<KeyValuePair<string, string>>? claims);
|
||||||
|
(List<KeyValuePair<string, string>>?, IDomainResult) JwtTokenClaims(string token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class JWTService : IJWTService {
|
public class JWTService : IJWTService {
|
||||||
|
|
||||||
private readonly ILogger<JWTService> _logger;
|
private readonly ILogger<JWTService> _logger;
|
||||||
|
private readonly IJwtConfig _configuration;
|
||||||
|
|
||||||
private readonly JwtSecurityTokenHandler _tokenHandler;
|
|
||||||
private readonly IJwtConfig _serviceConfig;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="serviceConfig"></param>
|
|
||||||
public JWTService(
|
public JWTService(
|
||||||
ILogger<JWTService> logger,
|
ILogger<JWTService> logger,
|
||||||
IJwtConfig serviceConfig
|
IJwtConfig configuration
|
||||||
|
|
||||||
) {
|
) {
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_serviceConfig = serviceConfig;
|
_configuration = configuration;
|
||||||
_tokenHandler = new JwtSecurityTokenHandler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? CreateJwtToken() {
|
public string CreateJwtToken(DateTime expires, List<KeyValuePair<string, string>>? claims) =>
|
||||||
if (_serviceConfig.Secret == null)
|
CreateJwtToken(_configuration.Secret, expires, claims);
|
||||||
return null;
|
|
||||||
|
|
||||||
if (_serviceConfig.Expires == null)
|
public string CreateJwtToken(string secret, DateTime expires, List<KeyValuePair<string, string>>? claims) {
|
||||||
return null;
|
|
||||||
|
|
||||||
|
|
||||||
var key = Convert.FromBase64String(_serviceConfig.Secret);
|
|
||||||
|
|
||||||
// add roles to claims identity from database
|
// add roles to claims identity from database
|
||||||
var claims = new List<Claim>() {};
|
var tokenClaims = new List<Claim>();
|
||||||
|
|
||||||
|
if (claims != null)
|
||||||
|
foreach (var claim in claims)
|
||||||
|
tokenClaims.Add(new Claim(claim.Key, claim.Value));
|
||||||
|
|
||||||
var token = _tokenHandler.CreateToken(new SecurityTokenDescriptor {
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
|
||||||
|
var securityToken = tokenHandler.CreateToken(new SecurityTokenDescriptor {
|
||||||
IssuedAt = DateTime.UtcNow,
|
IssuedAt = DateTime.UtcNow,
|
||||||
Subject = new ClaimsIdentity(claims),
|
Subject = new ClaimsIdentity(tokenClaims),
|
||||||
Expires = DateTime.UtcNow.AddDays(_serviceConfig.Expires.Value),
|
Expires = expires,
|
||||||
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature),
|
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Convert.FromBase64String(secret)), SecurityAlgorithms.HmacSha512Signature),
|
||||||
});
|
});
|
||||||
|
_logger.LogInformation($"Creted new JWT {securityToken}");
|
||||||
|
|
||||||
return _tokenHandler.WriteToken(token);
|
return tokenHandler.WriteToken(securityToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public (List<KeyValuePair<string, string>>?, IDomainResult) JwtTokenClaims(string token) {
|
||||||
|
|
||||||
//public string CreateJwtToken(IEnumerable<string> issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable<string> userRoles) {
|
var securityToken = new JwtSecurityTokenHandler().ReadToken(token) as JwtSecurityToken;
|
||||||
// var key = Convert.FromBase64String(_serviceConfig.Secret);
|
var claims = securityToken?.Claims?.Select(x => new KeyValuePair<string, string>(x.Type, x.Value));
|
||||||
|
|
||||||
// // add roles to claims identity from database
|
if (claims == null)
|
||||||
// var claims = new List<Claim>() {
|
return IDomainResult.Failed<List<KeyValuePair<string, string>>?>();
|
||||||
// new Claim(ClaimTypes.Actor, userId),
|
|
||||||
// new Claim(ClaimTypes.Email, userEmail),
|
|
||||||
// new Claim(ClaimTypes.NameIdentifier, userName),
|
|
||||||
// // new Claim(ClaimTypes.Webpage, issuer)
|
|
||||||
// };
|
|
||||||
|
|
||||||
// foreach (var role in userRoles)
|
return claims.Count() > 0
|
||||||
// claims.Add(new Claim(ClaimTypes.Role, role));
|
? IDomainResult.Success(claims.ToList())
|
||||||
|
: IDomainResult.NotFound<List<KeyValuePair<string, string>>?>();
|
||||||
// foreach (var iss in issuer)
|
}
|
||||||
// claims.Add(new Claim(ClaimTypes.Webpage, iss));
|
|
||||||
|
|
||||||
// var token = _tokenHandler.CreateToken(new SecurityTokenDescriptor {
|
|
||||||
// IssuedAt = DateTime.UtcNow,
|
|
||||||
// Subject = new ClaimsIdentity(claims),
|
|
||||||
// Expires = expires,
|
|
||||||
// SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature),
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return _tokenHandler.WriteToken(token);
|
|
||||||
//}
|
|
||||||
|
|
||||||
public JwtSecurityToken ReadJwtToken(string token) => _tokenHandler.ReadJwtToken(token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,10 @@ public class PasswordController : ControllerBase {
|
|||||||
|
|
||||||
private readonly IPasswordService _passwordService;
|
private readonly IPasswordService _passwordService;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="passwordService"></param>
|
||||||
public PasswordController(
|
public PasswordController(
|
||||||
IPasswordService passwordService
|
IPasswordService passwordService
|
||||||
) {
|
) {
|
||||||
|
|||||||
18
webapi/WeatherForecast/Controllers/UserController.cs
Normal file
18
webapi/WeatherForecast/Controllers/UserController.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace WeatherForecast.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
public class UserController : ControllerBase {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public UserController() { }
|
||||||
|
}
|
||||||
@ -1,6 +1,9 @@
|
|||||||
using Core.Abstractions;
|
using Core.Abstractions;
|
||||||
|
using Core.DomainObjects;
|
||||||
using DataProviders.Collections;
|
using DataProviders.Collections;
|
||||||
using DomainResults.Common;
|
using DomainResults.Common;
|
||||||
|
using ExtensionMethods;
|
||||||
|
using HashService;
|
||||||
using JWTService;
|
using JWTService;
|
||||||
using WeatherForecast.Models.Requests;
|
using WeatherForecast.Models.Requests;
|
||||||
|
|
||||||
@ -26,6 +29,7 @@ namespace WeatherForecast.Services {
|
|||||||
public class AutheticationService : ServiceBase<AutheticationService>, IAuthenticationService {
|
public class AutheticationService : ServiceBase<AutheticationService>, IAuthenticationService {
|
||||||
|
|
||||||
private readonly IUserDataProvider _userDataProvider;
|
private readonly IUserDataProvider _userDataProvider;
|
||||||
|
private readonly IHashService _hashService;
|
||||||
private readonly IJWTService _jwtService;
|
private readonly IJWTService _jwtService;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -33,13 +37,16 @@ namespace WeatherForecast.Services {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger"></param>
|
/// <param name="logger"></param>
|
||||||
/// <param name="userDataProvider"></param>
|
/// <param name="userDataProvider"></param>
|
||||||
|
/// <param name="hashService"></param>
|
||||||
/// <param name="jwtService"></param>
|
/// <param name="jwtService"></param>
|
||||||
public AutheticationService (
|
public AutheticationService (
|
||||||
ILogger<AutheticationService> logger,
|
ILogger<AutheticationService> logger,
|
||||||
IUserDataProvider userDataProvider,
|
IUserDataProvider userDataProvider,
|
||||||
|
IHashService hashService,
|
||||||
IJWTService jwtService
|
IJWTService jwtService
|
||||||
) : base(logger) {
|
) : base(logger) {
|
||||||
_userDataProvider = userDataProvider;
|
_userDataProvider = userDataProvider;
|
||||||
|
_hashService = hashService;
|
||||||
_jwtService = jwtService;
|
_jwtService = jwtService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,18 +56,77 @@ namespace WeatherForecast.Services {
|
|||||||
/// <param name="siteId"></param>
|
/// <param name="siteId"></param>
|
||||||
/// <param name="requestData"></param>
|
/// <param name="requestData"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public (string?, IDomainResult) Post (Guid siteId, AuthenticationRequestModel requestData) {
|
public (string?, IDomainResult) Post(Guid siteId, AuthenticationRequestModel requestData) {
|
||||||
try {
|
var opId = Guid.NewGuid();
|
||||||
var token = _jwtService.CreateJwtToken();
|
|
||||||
|
// Retrieve user from database by userName
|
||||||
|
var (user, getUserResult) = _userDataProvider.GetByNickName(requestData.Username);
|
||||||
|
if (!getUserResult.IsSuccess || user == null)
|
||||||
|
return IDomainResult.NotFound<string?>();
|
||||||
|
|
||||||
|
if (user.Passwords.Password == null)
|
||||||
|
return IDomainResult.Failed<string?>($"Opid = [{opId}] Password is not set, create new password.");
|
||||||
|
|
||||||
|
// Check provided password hash with the stored one
|
||||||
|
var (salt, hash) = _hashService.CreateSaltedHash(requestData.Password);
|
||||||
|
if (!_hashService.ValidateHash(requestData.Password, salt, hash))
|
||||||
|
return IDomainResult.Unauthorized<string?>();
|
||||||
|
|
||||||
|
// Check password expiration if enabled
|
||||||
|
if (user.Passwords.Expiration.Enabled && DateTime.UtcNow > user.Passwords.Password.Created.AddDays(user.Passwords.Expiration.Days)) {
|
||||||
|
user.Passwords.Expired.Add(user.Passwords.Password.Prototype());
|
||||||
|
user.Passwords.Password = null;
|
||||||
|
|
||||||
return token != null
|
|
||||||
? IDomainResult.Success(token)
|
|
||||||
: IDomainResult.Failed<string?>();
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
_logger.LogError("Unhandled exception", ex);
|
|
||||||
return IDomainResult.Failed<string?>();
|
return IDomainResult.Failed<string?>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creating JWT token
|
||||||
|
var claims = new List<KeyValuePair<string, string>> {
|
||||||
|
new KeyValuePair<string, string>("UserId", $"{user.Id}")
|
||||||
|
};
|
||||||
|
|
||||||
|
var created = DateTime.UtcNow;
|
||||||
|
var expires = created.AddDays(365);
|
||||||
|
|
||||||
|
var token = _jwtService.CreateJwtToken(expires, claims);
|
||||||
|
|
||||||
|
user.Tokens.Add(new Token {
|
||||||
|
Value = token,
|
||||||
|
Created = created,
|
||||||
|
Expires = expires,
|
||||||
|
});
|
||||||
|
|
||||||
|
return IDomainResult.Success(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public IDomainResult Get(string token) {
|
||||||
|
|
||||||
|
#region Retrieve user id from token claim
|
||||||
|
var (claims, getClaimsResult) = _jwtService.JwtTokenClaims(token);
|
||||||
|
if (!getClaimsResult.IsSuccess || claims == null)
|
||||||
|
return IDomainResult.Failed();
|
||||||
|
|
||||||
|
var userId = claims.SingleOrDefault(x => x.Key == "UserId").Value.ToGuid();
|
||||||
|
if(userId == Guid.Empty)
|
||||||
|
return IDomainResult.Failed();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
var (user, getUserRersult) = _userDataProvider.Get(userId);
|
||||||
|
if(!getUserRersult.IsSuccess || user == null)
|
||||||
|
return IDomainResult.Failed();
|
||||||
|
|
||||||
|
// remove expired tokens
|
||||||
|
user.Tokens = user.Tokens.Where(x => x.Expires < DateTime.UtcNow).ToList();
|
||||||
|
|
||||||
|
if (!user.Tokens.Any(x => x.Value == token))
|
||||||
|
return IDomainResult.Failed();
|
||||||
|
|
||||||
|
return IDomainResult.Success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
webapi/WeatherForecast/Services/UserService.cs
Normal file
16
webapi/WeatherForecast/Services/UserService.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace WeatherForecast.Services {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public interface IUserService {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class UserService : IUserService {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -84,6 +84,7 @@ namespace WeatherForecast {
|
|||||||
services.AddScoped<IBlogItemsService, BlogItemsService>();
|
services.AddScoped<IBlogItemsService, BlogItemsService>();
|
||||||
services.AddScoped<ICategoryItemService, CategoryItemService>();
|
services.AddScoped<ICategoryItemService, CategoryItemService>();
|
||||||
services.AddScoped<ICategoryItemsService, CategoryItemsService>();
|
services.AddScoped<ICategoryItemsService, CategoryItemsService>();
|
||||||
|
services.AddScoped<IUserService, UserService>();
|
||||||
|
|
||||||
services.AddScoped<IFileService, FileService>();
|
services.AddScoped<IFileService, FileService>();
|
||||||
services.AddScoped<IFilesService, FilesService>();
|
services.AddScoped<IFilesService, FilesService>();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user