Implemented Artist HTTP endpoint functionality. #21 and #26

This commit is contained in:
amazing-username
2019-05-10 22:21:30 -04:00
parent 0c4a1612b1
commit a3c74b50bc
11 changed files with 224 additions and 102 deletions
+1
View File
@@ -13,6 +13,7 @@ namespace Icarus.Controllers
{ {
[Route("api/album")] [Route("api/album")]
[ApiController] [ApiController]
// TODO: Secure the HTTP endpoint routes with Auth0 grants. #39
public class AlbumController : ControllerBase public class AlbumController : ControllerBase
{ {
#region Fields #region Fields
+34 -6
View File
@@ -8,11 +8,13 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Icarus.Models; using Icarus.Models;
using Icarus.Models.Context;
namespace Icarus.Controllers namespace Icarus.Controllers
{ {
[Route("api/artist")] [Route("api/artist")]
[ApiController] [ApiController]
// TODO: Secure the HTTP endpoint routes with Auth0 grants. #39
public class ArtistController : ControllerBase public class ArtistController : ControllerBase
{ {
#region Fields #region Fields
@@ -36,19 +38,45 @@ namespace Icarus.Controllers
[HttpGet] [HttpGet]
public IActionResult Get() public IActionResult Get()
{ {
List<Artist> artists = new List<Artist>(); ArtistStoreContext artistStoreContext = HttpContext
// TODO: Implement functionality .RequestServices
.GetService(typeof(ArtistStoreContext)) as ArtistStoreContext;
return Ok(artists); var artists = artistStoreContext.GetArtists();
if (artists.Count > 0)
{
return Ok(artists);
}
else
{
return NotFound();
}
} }
[HttpGet("{id}")] [HttpGet("{id}")]
public IActionResult Get(int id) public IActionResult Get(int id)
{ {
Artist artist = new Artist(); Artist artist = new Artist
// TODO: Implement functionality {
ArtistId = id
};
ArtistStoreContext artistStoreContext = HttpContext
.RequestServices
.GetService(typeof(ArtistStoreContext)) as ArtistStoreContext;
return Ok(artist); if (artistStoreContext.DoesArtistExist(artist))
{
artist = artistStoreContext.GetArtist(artist);
return Ok(artist);
}
else
{
return NotFound();
}
} }
#endregion #endregion
} }
+10 -3
View File
@@ -38,10 +38,17 @@ namespace Icarus.Controllers
#region HTTP endpoints #region HTTP endpoints
public IActionResult Post([FromBody] User user) public IActionResult Post([FromBody] User user)
{ {
// TODO: Secure this HTTP endpoint. #38
// Currently there is no check done to determine whether or not the
// user's password sent with the request matches the password stored
// in the database. In fact there is not check if the user credentials
// sent with this request even exist in the database. I knowingly left
// this bug in here for the sole purpose of making it easier to test
// but it should now be addressed.
UserStoreContext context = HttpContext UserStoreContext context = HttpContext
.RequestServices .RequestServices
.GetService(typeof(UserStoreContext)) .GetService(typeof(UserStoreContext)) as UserStoreContext;
as UserStoreContext;
user = context.RetrieveUser(user); user = context.RetrieveUser(user);
Console.WriteLine($"Username: {user.Username}"); Console.WriteLine($"Username: {user.Username}");
+43 -12
View File
@@ -490,24 +490,33 @@ namespace Icarus.Controllers.Managers
{ {
_results = new DataTable(); _results = new DataTable();
} }
private void SaveSongToDatabase(Song song, MusicStoreContext songStore, AlbumStoreContext albumStore, private void SaveSongToDatabase(Song song, MusicStoreContext songStore, AlbumStoreContext albumStore,
ArtistStoreContext artistStore) ArtistStoreContext artistStore)
{ {
song.AlbumId = 1; _logger.Info("Starting process to save the song to the database");
SaveAlbumToDatabase(ref song, albumStore);
SaveArtistToDatabase(ref song, artistStore);
_logger.Info($"Song;\nTitle {song.Title}\nAlbum {song.AlbumTitle}\nAlbum Id {song.AlbumId}\nArtist {song.ArtistId}");
songStore.SaveSong(song);
}
private void SaveAlbumToDatabase(ref Song song, AlbumStoreContext albumStore)
{
_logger.Info("Starting process to save the album record of the song to the database");
var album = new Album(); var album = new Album();
album.Title = song.AlbumTitle; album.Title = song.AlbumTitle;
album.AlbumArtist = song.Artist; album.AlbumArtist = song.Artist;
if (!albumStore.DoesAlbumExist(song)) if (!albumStore.DoesAlbumExist(song))
{ {
album.SongCount = 1; album.SongCount = 1;
_logger.Info("Saving album to database");
_logger.Info($"Ablum song count before retrieving from store: {album.SongCount}");
_logger.Info($"Ablum Id before retrieving from store: {album.AlbumId}");
albumStore.SaveAlbum(album); albumStore.SaveAlbum(album);
_logger.Info("Album suuccessfully saved to database");
album = albumStore.GetAlbum(song); album = albumStore.GetAlbum(song);
_logger.Info($"Ablum song count after retrieving from store: {album.SongCount}");
_logger.Info($"Ablum Id after retrieving from store: {album.AlbumId}");
} }
else else
{ {
@@ -517,12 +526,34 @@ namespace Icarus.Controllers.Managers
albumStore.UpdateAlbum(album); albumStore.UpdateAlbum(album);
} }
song.AlbumId = album.AlbumId;
_logger.Info($"Song;\nTitle {song.Title}\nAlbum {song.AlbumTitle}\nAlbum Id {song.AlbumId}");
songStore.SaveSong(song); song.AlbumId = album.AlbumId;
_logger.Info("Successfully saved song to database"); }
private void SaveArtistToDatabase(ref Song song, ArtistStoreContext artistStore)
{
_logger.Info("Starting process to save the artist record of the song to the database");
var artist = new Artist();
artist.Name = song.Artist;
artist.SongCount = 1;
if (!artistStore.DoesArtistExist(song))
{
artist.SongCount = 1;
artistStore.SaveArtist(artist);
artist = artistStore.GetArtist(song);
}
else
{
var artistRetrieved = artistStore.GetArtist(song);
artist.ArtistId = artistRetrieved.ArtistId;
artist.SongCount = artistRetrieved.SongCount + 1;
artistStore.UpdateArtist(artist);
}
song.ArtistId = artist.ArtistId;
} }
private async Task PopulateSongDetails() private async Task PopulateSongDetails()
+5 -3
View File
@@ -43,14 +43,15 @@ namespace Icarus.Controllers.Managers
var tokenRequest = RetrieveTokenRequest(); var tokenRequest = RetrieveTokenRequest();
var tokenObject = JsonConvert.SerializeObject(tokenRequest); var tokenObject = JsonConvert.SerializeObject(tokenRequest);
request.AddParameter("application/json; charset=utf-8", request.AddParameter("application/json; charset=utf-8",
tokenObject, ParameterType.RequestBody); tokenObject, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json; request.RequestFormat = DataFormat.Json;
IRestResponse response = client.Execute(request); IRestResponse response = client.Execute(request);
var tokenResult = JsonConvert var tokenResult = JsonConvert
.DeserializeObject<Token>(response.Content); .DeserializeObject<Token>(response.Content);
return new LoginResult return new LoginResult
{ {
@@ -81,9 +82,9 @@ namespace Icarus.Controllers.Managers
_grantType = "client_credentials"; _grantType = "client_credentials";
_url = $"https://{_config["Auth0:Domain"]}"; _url = $"https://{_config["Auth0:Domain"]}";
//PrintCredentials();
} }
#region Testing Methods
// For testing purposes // For testing purposes
private void PrintCredentials() private void PrintCredentials()
{ {
@@ -94,6 +95,7 @@ namespace Icarus.Controllers.Managers
Console.WriteLine($"Url: {_url}"); Console.WriteLine($"Url: {_url}");
} }
#endregion #endregion
#endregion
#region Classes #region Classes
+14 -14
View File
@@ -14,10 +14,10 @@ using Icarus.Models.Context;
namespace Icarus.Controllers namespace Icarus.Controllers
{ {
[Route("api/register")] [Route("api/register")]
[ApiController] [ApiController]
public class RegisterController : ControllerBase public class RegisterController : ControllerBase
{ {
#region Fields #region Fields
private IConfiguration _config; private IConfiguration _config;
#endregion #endregion
@@ -30,14 +30,13 @@ namespace Icarus.Controllers
#region Constructor #region Constructor
public RegisterController(IConfiguration config) public RegisterController(IConfiguration config)
{ {
_config = config; _config = config;
} }
#endregion #endregion
[HttpPost]
[HttpPost] public void Post([FromBody] User user)
public void Post([FromBody] User user) {
{
Console.WriteLine($"Username: {user.Username}"); Console.WriteLine($"Username: {user.Username}");
Console.WriteLine($"Password: {user.Password}"); Console.WriteLine($"Password: {user.Password}");
@@ -46,10 +45,11 @@ namespace Icarus.Controllers
user.EmailVerified = false; user.EmailVerified = false;
Console.WriteLine($"Hashed Password: {user.Password}"); Console.WriteLine($"Hashed Password: {user.Password}");
UserStoreContext context = HttpContext.RequestServices UserStoreContext context = HttpContext
.GetService(typeof(UserStoreContext)) .RequestServices
as UserStoreContext; .GetService(typeof(UserStoreContext)) as UserStoreContext;
context.SaveUser(user); context.SaveUser(user);
} }
} }
} }
+38 -38
View File
@@ -17,50 +17,50 @@ using Icarus.Models.Context;
namespace Icarus.Controllers namespace Icarus.Controllers
{ {
[Route("api/song/compressed/data")] [Route("api/song/compressed/data")]
[ApiController] [ApiController]
public class SongCompressedDataController : ControllerBase public class SongCompressedDataController : ControllerBase
{
#region Fields
private IConfiguration _config;
private SongManager _songMgr;
private string _songTempDir;
private string _archiveDir;
#endregion
#region Properties
#endregion
#region Constructor
public SongCompressedDataController(IConfiguration config)
{ {
_config = config; #region Fields
_songTempDir = _config.GetValue<string>("TemporaryMusicPath"); private IConfiguration _config;
_archiveDir = _config.GetValue<string>("ArchivePath"); private SongManager _songMgr;
} private string _songTempDir;
#endregion private string _archiveDir;
#endregion
#region API Routes #region Properties
[HttpGet("{id}")] #endregion
#region Constructor
public SongCompressedDataController(IConfiguration config)
{
_config = config;
_songTempDir = _config.GetValue<string>("TemporaryMusicPath");
_archiveDir = _config.GetValue<string>("ArchivePath");
}
#endregion
#region API Routes
[HttpGet("{id}")]
[Authorize("download:songs")] [Authorize("download:songs")]
public async Task<IActionResult> Get(int id) public async Task<IActionResult> Get(int id)
{ {
MusicStoreContext context = HttpContext.RequestServices MusicStoreContext context = HttpContext
.GetService(typeof(MusicStoreContext)) .RequestServices
as MusicStoreContext; .GetService(typeof(MusicStoreContext)) as MusicStoreContext;
SongCompression cmp = new SongCompression(_archiveDir); SongCompression cmp = new SongCompression(_archiveDir);
Console.WriteLine($"Archive directory root: {_archiveDir}"); Console.WriteLine($"Archive directory root: {_archiveDir}");
Console.WriteLine("Starting process of retrieving comrpessed song"); Console.WriteLine("Starting process of retrieving comrpessed song");
SongData song = await cmp.RetrieveCompressedSong(context.GetSong(id)); SongData song = await cmp.RetrieveCompressedSong(context.GetSong(id));
return File(song.Data, "application/x-msdownload", cmp.CompressedSongFilename); return File(song.Data, "application/x-msdownload", cmp.CompressedSongFilename);
} }
#endregion #endregion
} }
} }
+21 -18
View File
@@ -18,6 +18,7 @@ namespace Icarus.Controllers
{ {
[Route("api/song")] [Route("api/song")]
[ApiController] [ApiController]
// TODO: Secure the HTTP endpoint routes with Auth0 grants. #39
public class SongController : ControllerBase public class SongController : ControllerBase
{ {
#region Fields #region Fields
@@ -44,7 +45,7 @@ namespace Icarus.Controllers
[HttpGet] [HttpGet]
[Authorize("read:song_details")] [Authorize("read:song_details")]
public ActionResult<IEnumerable<Song>> Get() public IActionResult<IEnumerable<Song>> Get()
{ {
List<Song> songs = new List<Song>(); List<Song> songs = new List<Song>();
Console.WriteLine("Attemtping to retrieve songs"); Console.WriteLine("Attemtping to retrieve songs");
@@ -56,19 +57,33 @@ namespace Icarus.Controllers
songs = context.GetAllSongs(); songs = context.GetAllSongs();
return songs; if (songs.Count > 0)
{
return Ok(songs);
}
else
{
return NotFound();
}
} }
[HttpGet("{id}")] [HttpGet("{id}")]
public ActionResult<Song> Get(int id) public IActionResult<Song> Get(int id)
{ {
MusicStoreContext context = HttpContext MusicStoreContext context = HttpContext
.RequestServices .RequestServices
.GetService(typeof(MusicStoreContext)) as MusicStoreContext; .GetService(typeof(MusicStoreContext)) as MusicStoreContext;
Song song = context.GetSong(id); Song song = context.GetSong(id);
return song; if (song.Id != 0)
{
return Ok(song);
}
else
{
return NotFound();
}
} }
@@ -99,17 +114,5 @@ namespace Icarus.Controllers
return Ok(songResult); return Ok(songResult);
} }
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
MusicStoreContext context = HttpContext
.RequestServices
.GetService(typeof(MusicStoreContext)) as MusicStoreContext;
context.DeleteSong(id);
return Ok();
}
}
} }
+5
View File
@@ -279,6 +279,8 @@ namespace Icarus.Models.Context
private List<Album> ParseData(MySqlDataReader reader) private List<Album> ParseData(MySqlDataReader reader)
{ {
List<Album> albums = new List<Album>(); List<Album> albums = new List<Album>();
_logger.Info("Retrieving album records");
while (reader.Read()) while (reader.Read())
{ {
var id = Convert.ToInt32(reader["AlbumId"]); var id = Convert.ToInt32(reader["AlbumId"]);
@@ -294,12 +296,15 @@ namespace Icarus.Models.Context
}); });
} }
_logger.Info("Album records retrieved");
return albums; return albums;
} }
private Album ParseSingleData(MySqlDataReader reader) private Album ParseSingleData(MySqlDataReader reader)
{ {
Album album = new Album(); Album album = new Album();
_logger.Info("Retrieving single album record"); _logger.Info("Retrieving single album record");
while (reader.Read()) while (reader.Read())
{ {
var id = Convert.ToInt32(reader["AlbumId"]); var id = Convert.ToInt32(reader["AlbumId"]);
+37 -5
View File
@@ -63,6 +63,7 @@ namespace Icarus.Models.Context
{ {
try try
{ {
_logger.Info("Checking to see if Artist exists");
using (MySqlConnection conn = GetConnection()) using (MySqlConnection conn = GetConnection())
{ {
conn.Open(); conn.Open();
@@ -70,7 +71,7 @@ namespace Icarus.Models.Context
var query = "SELECT * FROM Artist WHERE ArtistId=@ArtistId"; var query = "SELECT * FROM Artist WHERE ArtistId=@ArtistId";
using (MySqlCommand cmd = new MySqlCommand(query, conn)) using (MySqlCommand cmd = new MySqlCommand(query, conn))
{ {
cmd.Parameters.AddWithValue("@AlbumId", artist.ArtistId); cmd.Parameters.AddWithValue("@ArtistId", artist.ArtistId);
using (var reader = cmd.ExecuteReader()) using (var reader = cmd.ExecuteReader())
{ {
@@ -90,17 +91,21 @@ namespace Icarus.Models.Context
var msg = ex.Message; var msg = ex.Message;
_logger.Error(msg, "An error occurred"); _logger.Error(msg, "An error occurred");
} }
_logger.Info("Could not successfully retrieve Artist");
return false; return false;
} }
public bool DoesArtistExist(Song song) public bool DoesArtistExist(Song song)
{ {
try try
{ {
_logger.Info("Checking to see if Artist exists");
using (MySqlConnection conn = GetConnection()) using (MySqlConnection conn = GetConnection())
{ {
conn.Open(); conn.Open();
var query = "SELECT * FROM Album WHERE Name=@Name"; var query = "SELECT * FROM Artist WHERE Name=@Name";
using (MySqlCommand cmd = new MySqlCommand(query, conn)) using (MySqlCommand cmd = new MySqlCommand(query, conn))
{ {
cmd.Parameters.AddWithValue("@Name", song.Artist); cmd.Parameters.AddWithValue("@Name", song.Artist);
@@ -123,6 +128,9 @@ namespace Icarus.Models.Context
var msg = ex.Message; var msg = ex.Message;
_logger.Error(msg, "An error occurred"); _logger.Error(msg, "An error occurred");
} }
_logger.Info("Could not successfully retrieve Artist");
return false; return false;
} }
@@ -131,6 +139,7 @@ namespace Icarus.Models.Context
{ {
try try
{ {
_logger.Info("Saving artist record");
using (MySqlConnection conn = GetConnection()) using (MySqlConnection conn = GetConnection())
{ {
conn.Open(); conn.Open();
@@ -145,6 +154,8 @@ namespace Icarus.Models.Context
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
} }
_logger.Info("Artist record has successfully been saved");
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -156,11 +167,24 @@ namespace Icarus.Models.Context
{ {
try try
{ {
_logger.Info("Updating artist record");
using (MySqlConnection conn = GetConnection()) using (MySqlConnection conn = GetConnection())
{ {
conn.Open(); conn.Open();
// TODO: Implement functionality var query = "UPDATE Artist SET Name=@Name, SongCount" +
"=@SongCount WHERE ArtistId=@ArtistId";
using (MySqlCommand cmd = new MySqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("@Name", artist.Name);
cmd.Parameters.AddWithValue("@SongCount", artist.SongCount);
cmd.Parameters.AddWithValue("@ArtistId", artist.ArtistId);
cmd.ExecuteNonQuery();
}
} }
_logger.Info("Artist record has successfully been saved");
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -173,6 +197,7 @@ namespace Icarus.Models.Context
{ {
try try
{ {
_logger.Info("Retrieving artist record from the database");
using (MySqlConnection conn = GetConnection()) using (MySqlConnection conn = GetConnection())
{ {
conn.Open(); conn.Open();
@@ -181,6 +206,7 @@ namespace Icarus.Models.Context
using (MySqlCommand cmd = new MySqlCommand(query, conn)) using (MySqlCommand cmd = new MySqlCommand(query, conn))
{ {
cmd.Parameters.AddWithValue("@ArtistId", artist.ArtistId); cmd.Parameters.AddWithValue("@ArtistId", artist.ArtistId);
using (var reader = cmd.ExecuteReader()) using (var reader = cmd.ExecuteReader())
{ {
artist = ParseSingleData(reader); artist = ParseSingleData(reader);
@@ -201,14 +227,16 @@ namespace Icarus.Models.Context
Artist artist = new Artist(); Artist artist = new Artist();
try try
{ {
_logger.Info("Retrieving artist record from the database");
using (MySqlConnection conn = GetConnection()) using (MySqlConnection conn = GetConnection())
{ {
conn.Open(); conn.Open();
var query = "SELECT * FROM Artist WHERE ArtistId=@ArtistId"; var query = "SELECT * FROM Artist WHERE Name=@Name";
using (MySqlCommand cmd = new MySqlCommand(query, conn)) using (MySqlCommand cmd = new MySqlCommand(query, conn))
{ {
cmd.Parameters.AddWithValue("@ArtistId", song.ArtistId); cmd.Parameters.AddWithValue("@Name", song.Artist);
using (var reader = cmd.ExecuteReader()) using (var reader = cmd.ExecuteReader())
{ {
artist = ParseSingleData(reader); artist = ParseSingleData(reader);
@@ -243,6 +271,8 @@ namespace Icarus.Models.Context
}); });
} }
_logger.Info("Artist records retrieved");
return artists; return artists;
} }
@@ -260,6 +290,8 @@ namespace Icarus.Models.Context
artist.SongCount = songCount; artist.SongCount = songCount;
} }
_logger.Info("Single artist record retrieved");
return artist; return artist;
} }
#endregion #endregion
+16 -3
View File
@@ -30,13 +30,15 @@ namespace Icarus.Models.Context
{ {
try try
{ {
_logger.Info("Saving song to the database");
using (MySqlConnection conn = GetConnection()) using (MySqlConnection conn = GetConnection())
{ {
conn.Open(); conn.Open();
string query = "INSERT INTO Song(Title, AlbumTitle, Artist," + string query = "INSERT INTO Song(Title, AlbumTitle, Artist," +
" Year, Genre, Duration, Filename, SongPath, AlbumId) " + " Year, Genre, Duration, Filename, SongPath, AlbumId, " +
"VALUES(@Title, @AlbumTitle, @Artist, @Year, @Genre, " + "ArtistId) VALUES(@Title, @AlbumTitle, @Artist, @Year, " +
"@Duration, @Filename, @SongPath, @AlbumId)"; "@Genre, @Duration, @Filename, @SongPath, @AlbumId, " +
"@ArtistId)";
using (MySqlCommand cmd = new MySqlCommand(query, conn)) using (MySqlCommand cmd = new MySqlCommand(query, conn))
{ {
cmd.Parameters.AddWithValue("@Title", song.Title); cmd.Parameters.AddWithValue("@Title", song.Title);
@@ -48,10 +50,12 @@ namespace Icarus.Models.Context
cmd.Parameters.AddWithValue("@Filename", song.Filename); cmd.Parameters.AddWithValue("@Filename", song.Filename);
cmd.Parameters.AddWithValue("@SongPath", song.SongPath); cmd.Parameters.AddWithValue("@SongPath", song.SongPath);
cmd.Parameters.AddWithValue("@AlbumId", song.AlbumId); cmd.Parameters.AddWithValue("@AlbumId", song.AlbumId);
cmd.Parameters.AddWithValue("@ArtistId", song.ArtistId);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
} }
} }
_logger.Info("Successfully saved song to the database");
} }
catch(Exception ex) catch(Exception ex)
{ {
@@ -125,8 +129,10 @@ namespace Icarus.Models.Context
public List<Song> GetAllSongs() public List<Song> GetAllSongs()
{ {
List<Song> songs = new List<Song>(); List<Song> songs = new List<Song>();
try try
{ {
_logger.Info("Retrieving songs from the database");
using (MySqlConnection conn = GetConnection()) using (MySqlConnection conn = GetConnection())
{ {
conn.Open(); conn.Open();
@@ -134,6 +140,8 @@ namespace Icarus.Models.Context
MySqlCommand cmd = new MySqlCommand(query, conn); MySqlCommand cmd = new MySqlCommand(query, conn);
using (var reader = cmd.ExecuteReader()) using (var reader = cmd.ExecuteReader())
{ {
songs = ParseData(reader);
/**
while (reader.Read()) while (reader.Read())
{ {
songs.Add(new Song songs.Add(new Song
@@ -149,6 +157,7 @@ namespace Icarus.Models.Context
SongPath = reader["SongPath"].ToString() SongPath = reader["SongPath"].ToString()
}); });
} }
*/
} }
} }
} }
@@ -169,6 +178,7 @@ namespace Icarus.Models.Context
try try
{ {
_logger.Info("Retrieving song from database");
using (MySqlConnection conn = GetConnection()) using (MySqlConnection conn = GetConnection())
{ {
conn.Open(); conn.Open();
@@ -179,6 +189,8 @@ namespace Icarus.Models.Context
using (var reader = cmd.ExecuteReader()) using (var reader = cmd.ExecuteReader())
{ {
song = ParseSingleData(reader);
/**
while (reader.Read()) while (reader.Read())
{ {
song = new Song song = new Song
@@ -194,6 +206,7 @@ namespace Icarus.Models.Context
SongPath = reader["SongPath"].ToString() SongPath = reader["SongPath"].ToString()
}; };
} }
*/
} }
} }
_logger.Info("Song found"); _logger.Info("Song found");