1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
using Timeline.Configs;
using Timeline.Entities;
using Timeline.Helpers;
using Timeline.Services.User;
namespace Timeline.Services.Token
{
public class UserTokenManager : IUserTokenManager
{
private readonly ILogger<UserTokenManager> _logger;
private readonly IOptionsMonitor<TokenOptions> _tokenOptionsMonitor;
private readonly IUserService _userService;
private readonly IUserTokenHandler _userTokenService;
private readonly IClock _clock;
public UserTokenManager(ILogger<UserTokenManager> logger, IOptionsMonitor<TokenOptions> tokenOptionsMonitor, IUserService userService, IUserTokenHandler userTokenService, IClock clock)
{
_logger = logger;
_tokenOptionsMonitor = tokenOptionsMonitor;
_userService = userService;
_userTokenService = userTokenService;
_clock = clock;
}
public async Task<UserTokenCreateResult> CreateTokenAsync(string username, string password, DateTime? expireAt = null)
{
expireAt = expireAt?.MyToUtc();
if (username == null)
throw new ArgumentNullException(nameof(username));
if (password == null)
throw new ArgumentNullException(nameof(password));
var userId = await _userService.VerifyCredential(username, password);
var user = await _userService.GetUserAsync(userId);
var token = await _userTokenService.GenerateTokenAsync(new UserTokenInfo
{
Id = user.Id,
Version = user.Version,
ExpireAt = expireAt ?? _clock.GetCurrentTime() + TimeSpan.FromSeconds(_tokenOptionsMonitor.CurrentValue.DefaultExpireSeconds)
});
_logger.LogInformation(Resource.LogTokenCreate, user.Username, userId);
return new UserTokenCreateResult { Token = token, User = user };
}
public async Task<UserEntity> VerifyTokenAsync(string token)
{
if (token == null)
throw new ArgumentNullException(nameof(token));
UserTokenInfo tokenInfo;
try
{
tokenInfo = await _userTokenService.ValidateTokenAsync(token);
}
catch (UserTokenBadFormatException e)
{
_logger.LogInformation(e, Resource.LogTokenVerifiedFail);
throw;
}
var currentTime = _clock.GetCurrentTime();
if (tokenInfo.ExpireAt < currentTime)
{
var e = new UserTokenTimeExpiredException(token, tokenInfo.ExpireAt, currentTime);
_logger.LogInformation(e, Resource.LogTokenVerifiedFail);
throw e;
}
try
{
var user = await _userService.GetUserAsync(tokenInfo.Id);
if (tokenInfo.Version < user.Version)
{
var e = new UserTokenVersionExpiredException(token, tokenInfo.Version, user.Version);
_logger.LogInformation(e, Resource.LogTokenVerifiedFail);
throw e;
}
_logger.LogInformation(Resource.LogTokenVerified, user.Username, user.Id);
return user;
}
catch (EntityNotExistException e)
{
var exception = new UserTokenUserNotExistException(token, e);
_logger.LogInformation(exception, Resource.LogTokenVerifiedFail);
throw exception;
}
}
}
}
|