From eafaa5d9d2922431761e8eb72342bdeed5dc2920 Mon Sep 17 00:00:00 2001 From: phoenix Date: Tue, 11 Mar 2025 20:02:14 -0400 Subject: [PATCH] tsk-#76: Added functionality --- Icarus/Controllers/Managers/TokenManager.cs | 20 ++++++++++++------- Icarus/Controllers/v1/SongDataController.cs | 15 +++++++++++++- .../Database/Contexts/AccessLevelContext.cs | 19 ++++++++++++++---- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Icarus/Controllers/Managers/TokenManager.cs b/Icarus/Controllers/Managers/TokenManager.cs index 42cda59..4eb02fa 100644 --- a/Icarus/Controllers/Managers/TokenManager.cs +++ b/Icarus/Controllers/Managers/TokenManager.cs @@ -138,24 +138,30 @@ public class TokenManager : BaseManager return tokenUserId.Value == song.UserId; } - public int? RetrieveUserIdFromToken(string token) + public string? GetBearerToken(HttpContext context) { - if (this.ContainsBearer(token)) + string authorizationHeader = context.Request.Headers["Authorization"]!; + + if (!authorizationHeader.IsNullOrEmpty() && authorizationHeader.StartsWith("Bearer", StringComparison.OrdinalIgnoreCase)) { - token = this.StripBearer(token); + string token = authorizationHeader.Substring("Bearer ".Length).Trim(); + return token; } + return null; + } + + public int? RetrieveUserIdFromToken(string token) + { + var parsedToken = this.ContainsBearer(token) ? this.StripBearer(token) : token; var tokenHandler = new JwtSecurityTokenHandler(); - var readTok = tokenHandler.ReadJwtToken(token); - // var userId = -1; + var readTok = tokenHandler.ReadJwtToken(parsedToken); foreach (var item in readTok.Payload) { if (item.Key == "user_id") { - // userId = return Convert.ToInt32(item.Value); - // break; } } diff --git a/Icarus/Controllers/v1/SongDataController.cs b/Icarus/Controllers/v1/SongDataController.cs index 9eb14af..0876ef7 100644 --- a/Icarus/Controllers/v1/SongDataController.cs +++ b/Icarus/Controllers/v1/SongDataController.cs @@ -38,11 +38,23 @@ public class SongDataController : BaseController #endregion + [HttpGet("download/{id}")] public IActionResult Download(int id, [FromQuery] bool? randomizeFilename) { - var songContext = new SongContext(_connectionString!); + var tokenManager = new TokenManager(this._config!); + var songContext = new SongContext(this._connectionString!); + var accLvlContext = new AccessLevelContext(this._connectionString!); var songMetaData = songContext.RetrieveRecord(new Song { Id = id }); + var accessLevel = accLvlContext.GetAccessLevel(songMetaData.Id); + var token = tokenManager.GetBearerToken(HttpContext); + if (token == null || accessLevel == null) { + return BadRequest(); + } + + if (!tokenManager.CanAccessSong(token, songMetaData, accessLevel)) { + return BadRequest(); + } var song = _songMgr!.RetrieveSong(songMetaData).Result; string filename; @@ -66,6 +78,7 @@ public class SongDataController : BaseController return File(song.Data!, "application/x-msdownload", filename); } + // NOTE: No longer being used // Assumes that the song already has metadata such as // Title // Artist diff --git a/Icarus/Database/Contexts/AccessLevelContext.cs b/Icarus/Database/Contexts/AccessLevelContext.cs index fea0901..78edbbc 100644 --- a/Icarus/Database/Contexts/AccessLevelContext.cs +++ b/Icarus/Database/Contexts/AccessLevelContext.cs @@ -4,21 +4,32 @@ namespace Icarus.Database.Contexts; public class AccessLevelContext : DbContext { - public DbSet? AccessLevels { get; set; } + #region Properties + public DbSet? AccessLevels { get; set; } + #endregion + #region Constructors public AccessLevelContext(DbContextOptions options) : base(options) { } public AccessLevelContext(string connString) : base(new DbContextOptionsBuilder() .UseMySQL(connString).Options) { - + if (this.AccessLevels == null) + { + } } + #endregion #region Methods + public Models.AccessLevel? GetAccessLevel(int songId) { + var accessLevel = this.AccessLevels!.FirstOrDefault(acc => acc.SongId == songId); + return accessLevel; + } + protected override void OnModelCreating(ModelBuilder modelBuilder) { - modelBuilder.Entity().ToTable("AccessLevel"); + modelBuilder.Entity().ToTable("AccessLevel"); - modelBuilder.Entity().Property(m => m.Level).IsRequired(true); + modelBuilder.Entity().Property(m => m.Level).IsRequired(true); } #endregion }