Added API token functionality
This commit is contained in:
@@ -30,5 +30,10 @@ public abstract class HopDbContextBase : DbContext {
|
||||
.HasMany(g => g.Permissions)
|
||||
.WithOne(p => p.Group)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<Token>()
|
||||
.HasMany(t => t.Permissions)
|
||||
.WithOne(t => t.Token)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,9 @@ public class Permission {
|
||||
[ForeignKey("GroupName"), JsonIgnore]
|
||||
public virtual PermissionGroup Group { get; set; }
|
||||
|
||||
[ForeignKey("TokenId"), JsonIgnore]
|
||||
public virtual Token Token { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public interface IPermissionOwner;
|
||||
|
||||
@@ -4,24 +4,32 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace HopFrame.Database.Models;
|
||||
|
||||
public class Token {
|
||||
public class Token : IPermissionOwner {
|
||||
public const int RefreshTokenType = 0;
|
||||
public const int AccessTokenType = 1;
|
||||
public const int ApiTokenType = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the Type of the stored Token
|
||||
/// 0: Refresh token
|
||||
/// 1: Access token
|
||||
/// 2: Api token
|
||||
/// </summary>
|
||||
[Required, MinLength(1), MaxLength(1)]
|
||||
public int Type { get; set; }
|
||||
|
||||
[Key, Required, MinLength(36), MaxLength(36)]
|
||||
public Guid Content { get; set; }
|
||||
public Guid TokenId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the creation date of the token
|
||||
/// In case of an api token it defines the date it becomes invalid
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[ForeignKey("UserId"), JsonIgnore]
|
||||
public virtual User Owner { get; set; }
|
||||
|
||||
public virtual List<Permission> Permissions { get; set; }
|
||||
}
|
||||
@@ -6,4 +6,5 @@ public interface ITokenRepository {
|
||||
Task<Token> GetToken(string content);
|
||||
Task<Token> CreateToken(int type, User owner);
|
||||
Task DeleteUserTokens(User owner);
|
||||
Task<Token> CreateApiToken(User owner, DateTime expirationDate);
|
||||
}
|
||||
@@ -24,6 +24,10 @@ internal sealed class PermissionRepository<TDbContext>(TDbContext context, IGrou
|
||||
entry.User = user;
|
||||
}else if (owner is PermissionGroup group) {
|
||||
entry.Group = group;
|
||||
}else if (owner is Token token) {
|
||||
if (token.Type != Token.ApiTokenType)
|
||||
throw new ArgumentException("Only API tokens can have permissions!");
|
||||
entry.Token = token;
|
||||
}
|
||||
|
||||
await context.Permissions.AddAsync(entry);
|
||||
@@ -48,6 +52,13 @@ internal sealed class PermissionRepository<TDbContext>(TDbContext context, IGrou
|
||||
.Where(p =>p.Group.Name == group.Name)
|
||||
.Where(p => p.PermissionName == permission)
|
||||
.SingleOrDefaultAsync();
|
||||
}else if (owner is Token token) {
|
||||
entry = await context.Permissions
|
||||
.Include(p => p.Token)
|
||||
.Where(p => p.Token != null)
|
||||
.Where(p => p.Token.TokenId == token.TokenId)
|
||||
.Where(p => p.PermissionName == permission)
|
||||
.SingleOrDefaultAsync();
|
||||
}
|
||||
|
||||
if (entry is not null) {
|
||||
@@ -74,6 +85,14 @@ internal sealed class PermissionRepository<TDbContext>(TDbContext context, IGrou
|
||||
.Where(p =>p.Group.Name == group.Name)
|
||||
.ToListAsync();
|
||||
|
||||
permissions.AddRange(perms.Select(p => p.PermissionName));
|
||||
}else if (owner is Token token) {
|
||||
var perms = await context.Permissions
|
||||
.Include(p => p.Token)
|
||||
.Where(p => p.Token != null)
|
||||
.Where(p =>p.Token.TokenId == token.TokenId)
|
||||
.ToListAsync();
|
||||
|
||||
permissions.AddRange(perms.Select(p => p.PermissionName));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ internal sealed class TokenRepository<TDbContext>(TDbContext context) : ITokenRe
|
||||
|
||||
return await context.Tokens
|
||||
.Include(t => t.Owner)
|
||||
.Where(t => t.Content == guid)
|
||||
.Where(t => t.TokenId == guid)
|
||||
.SingleOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<Token> CreateToken(int type, User owner) {
|
||||
var token = new Token {
|
||||
CreatedAt = DateTime.Now,
|
||||
Content = Guid.NewGuid(),
|
||||
TokenId = Guid.NewGuid(),
|
||||
Type = type,
|
||||
Owner = owner
|
||||
};
|
||||
@@ -38,4 +38,18 @@ internal sealed class TokenRepository<TDbContext>(TDbContext context) : ITokenRe
|
||||
context.Tokens.RemoveRange(tokens);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task<Token> CreateApiToken(User owner, DateTime expirationDate) {
|
||||
var token = new Token {
|
||||
CreatedAt = expirationDate,
|
||||
TokenId = Guid.NewGuid(),
|
||||
Type = Token.ApiTokenType,
|
||||
Owner = owner
|
||||
};
|
||||
|
||||
await context.Tokens.AddAsync(token);
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user