aboutsummaryrefslogtreecommitdiff
path: root/Timeline/Services
diff options
context:
space:
mode:
Diffstat (limited to 'Timeline/Services')
-rw-r--r--Timeline/Services/JwtService.cs39
-rw-r--r--Timeline/Services/UserService.cs39
2 files changed, 48 insertions, 30 deletions
diff --git a/Timeline/Services/JwtService.cs b/Timeline/Services/JwtService.cs
index bf470354..f5df59a5 100644
--- a/Timeline/Services/JwtService.cs
+++ b/Timeline/Services/JwtService.cs
@@ -11,24 +11,28 @@ using Timeline.Entities;
namespace Timeline.Services
{
+ public class TokenInfo
+ {
+ public string Name { get; set; }
+ public string[] Roles { get; set; }
+ }
+
public interface IJwtService
{
/// <summary>
/// Create a JWT token for a given user info.
/// </summary>
- /// <param name="userId">The user id contained in generate token.</param>
- /// <param name="username">The username contained in token.</param>
- /// <param name="roles">The roles contained in token.</param>
+ /// <param name="tokenInfo">The info to generate token.</param>
/// <returns>Return the generated token.</returns>
- string GenerateJwtToken(long userId, string username, string[] roles);
+ string GenerateJwtToken(TokenInfo tokenInfo);
/// <summary>
/// Verify a JWT token.
/// Return null is <paramref name="token"/> is null.
/// </summary>
/// <param name="token">The token string to verify.</param>
- /// <returns>Return null if <paramref name="token"/> is null or token is invalid. Return the saved user info otherwise.</returns>
- UserInfo VerifyJwtToken(string token);
+ /// <returns>Return null if <paramref name="token"/> is null or token is invalid. Return the saved info otherwise.</returns>
+ TokenInfo VerifyJwtToken(string token);
}
@@ -44,14 +48,20 @@ namespace Timeline.Services
_logger = logger;
}
- public string GenerateJwtToken(long id, string username, string[] roles)
+ public string GenerateJwtToken(TokenInfo tokenInfo)
{
+ if (tokenInfo == null)
+ throw new ArgumentNullException(nameof(tokenInfo));
+ if (tokenInfo.Name == null)
+ throw new ArgumentException("Name is null.", nameof(tokenInfo));
+ if (tokenInfo.Roles == null)
+ throw new ArgumentException("Roles is null.", nameof(tokenInfo));
+
var jwtConfig = _jwtConfig.CurrentValue;
var identity = new ClaimsIdentity();
- identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString()));
- identity.AddClaim(new Claim(identity.NameClaimType, username));
- identity.AddClaims(roles.Select(role => new Claim(identity.RoleClaimType, role)));
+ identity.AddClaim(new Claim(identity.NameClaimType, tokenInfo.Name));
+ identity.AddClaims(tokenInfo.Roles.Select(role => new Claim(identity.RoleClaimType, role)));
var tokenDescriptor = new SecurityTokenDescriptor()
{
@@ -71,7 +81,7 @@ namespace Timeline.Services
}
- public UserInfo VerifyJwtToken(string token)
+ public TokenInfo VerifyJwtToken(string token)
{
if (token == null)
return null;
@@ -90,8 +100,11 @@ namespace Timeline.Services
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config.SigningKey))
}, out SecurityToken validatedToken);
- return new UserInfo(principal.Identity.Name,
- principal.FindAll(ClaimTypes.Role).Select(c => c.Value).ToArray());
+ return new TokenInfo
+ {
+ Name = principal.Identity.Name,
+ Roles = principal.FindAll(ClaimTypes.Role).Select(c => c.Value).ToArray()
+ };
}
catch (Exception e)
{
diff --git a/Timeline/Services/UserService.cs b/Timeline/Services/UserService.cs
index 8ab3bc54..9fe9e08f 100644
--- a/Timeline/Services/UserService.cs
+++ b/Timeline/Services/UserService.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Models;
+using static Timeline.Entities.UserUtility;
namespace Timeline.Services
{
@@ -120,7 +121,7 @@ namespace Timeline.Services
/// <param name="roles">Array of roles of user.</param>
/// <returns>Return <see cref="PutUserResult.Created"/> if a new user is created.
/// Return <see cref="PutUserResult.Modified"/> if a existing user is modified.</returns>
- Task<PutUserResult> PutUser(string username, string password, string[] roles);
+ Task<PutUserResult> PutUser(string username, string password, bool isAdmin);
/// <summary>
/// Partially modify a use of given username.
@@ -130,7 +131,7 @@ namespace Timeline.Services
/// <param name="roles">New roles. If not modify, then null.</param>
/// <returns>Return <see cref="PatchUserResult.Success"/> if modification succeeds.
/// Return <see cref="PatchUserResult.NotExists"/> if the user of given username doesn't exist.</returns>
- Task<PatchUserResult> PatchUser(string username, string password, string[] roles);
+ Task<PatchUserResult> PatchUser(string username, string password, bool? isAdmin);
/// <summary>
/// Delete a user of given username.
@@ -203,12 +204,16 @@ namespace Timeline.Services
if (verifyResult)
{
- var userInfo = UserInfo.Create(user);
-
+ var roles = RoleStringToRoleArray(user.RoleString);
+ var token = _jwtService.GenerateJwtToken(new TokenInfo
+ {
+ Name = username,
+ Roles = roles
+ });
return new CreateTokenResult
{
- Token = _jwtService.GenerateJwtToken(user.Id, userInfo.Username, userInfo.Roles),
- UserInfo = userInfo
+ Token = token,
+ UserInfo = new UserInfo(username, RoleArrayToIsAdmin(roles))
};
}
else
@@ -220,33 +225,33 @@ namespace Timeline.Services
public async Task<UserInfo> VerifyToken(string token)
{
- var userInfo = _jwtService.VerifyJwtToken(token);
+ var tokenInfo = _jwtService.VerifyJwtToken(token);
- if (userInfo == null)
+ if (tokenInfo == null)
{
_logger.LogInformation($"Verify token falied. Reason: invalid token. Token: {token} .");
return null;
}
- return await Task.FromResult(userInfo);
+ return await Task.FromResult(new UserInfo(tokenInfo.Name, RoleArrayToIsAdmin(tokenInfo.Roles)));
}
public async Task<UserInfo> GetUser(string username)
{
return await _databaseContext.Users
.Where(user => user.Name == username)
- .Select(user => UserInfo.Create(user.Name, user.RoleString))
+ .Select(user => CreateUserInfo(user))
.SingleOrDefaultAsync();
}
public async Task<UserInfo[]> ListUsers()
{
return await _databaseContext.Users
- .Select(user => UserInfo.Create(user.Name, user.RoleString))
+ .Select(user => CreateUserInfo(user))
.ToArrayAsync();
}
- public async Task<PutUserResult> PutUser(string username, string password, string[] roles)
+ public async Task<PutUserResult> PutUser(string username, string password, bool isAdmin)
{
var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync();
@@ -256,20 +261,20 @@ namespace Timeline.Services
{
Name = username,
EncryptedPassword = _passwordService.HashPassword(password),
- RoleString = string.Join(',', roles)
+ RoleString = IsAdminToRoleString(isAdmin)
});
await _databaseContext.SaveChangesAsync();
return PutUserResult.Created;
}
user.EncryptedPassword = _passwordService.HashPassword(password);
- user.RoleString = string.Join(',', roles);
+ user.RoleString = IsAdminToRoleString(isAdmin);
await _databaseContext.SaveChangesAsync();
return PutUserResult.Modified;
}
- public async Task<PatchUserResult> PatchUser(string username, string password, string[] roles)
+ public async Task<PatchUserResult> PatchUser(string username, string password, bool? isAdmin)
{
var user = await _databaseContext.Users.Where(u => u.Name == username).SingleOrDefaultAsync();
@@ -284,10 +289,10 @@ namespace Timeline.Services
user.EncryptedPassword = _passwordService.HashPassword(password);
}
- if (roles != null)
+ if (isAdmin != null)
{
modified = true;
- user.RoleString = string.Join(',', roles);
+ user.RoleString = IsAdminToRoleString(isAdmin.Value);
}
if (modified)