Implemented Tokens, Login Functionality, and download authorization #15, #27, #31, #34

This commit is contained in:
amazing-username
2019-04-28 22:29:15 +00:00
parent 6cc0b32563
commit 065abeecbc
7 changed files with 234 additions and 124 deletions
+6
View File
@@ -38,6 +38,12 @@ namespace Icarus.Controllers
#region HTTP endpoints #region HTTP endpoints
public IActionResult Post([FromBody] User user) public IActionResult Post([FromBody] User user)
{ {
UserStoreContext context = HttpContext
.RequestServices
.GetService(typeof(UserStoreContext))
as UserStoreContext;
user = context.RetrieveUser(user);
Console.WriteLine($"Username: {user.Username}"); Console.WriteLine($"Username: {user.Username}");
TokenManager tk = new TokenManager(_config); TokenManager tk = new TokenManager(_config);
+75 -7
View File
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using RestSharp; using RestSharp;
using Icarus.Models; using Icarus.Models;
@@ -13,6 +14,11 @@ namespace Icarus.Controllers.Managers
{ {
#region Fields #region Fields
private IConfiguration _config; private IConfiguration _config;
private string _clientId;
private string _clientSecret;
private string _audience;
private string _grantType;
private string _url;
#endregion #endregion
@@ -32,22 +38,84 @@ namespace Icarus.Controllers.Managers
#region Methods #region Methods
public LoginResult RetrieveLoginResult(User user) public LoginResult RetrieveLoginResult(User user)
{ {
// TODO: Request a token from Auth0 var client = new RestClient(_url);
var request = new RestRequest("oauth/token", Method.POST);
var tokenRequest = RetrieveTokenRequest();
var tokenObject = JsonConvert.SerializeObject(tokenRequest);
request.AddParameter("application/json; charset=utf-8",
tokenObject, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json;
IRestResponse response = client.Execute(request);
var tokenResult = JsonConvert
.DeserializeObject<Token>(response.Content);
return new LoginResult return new LoginResult
{ {
UserId = 0, UserId = user.Id,
Username = user.Username, Username = user.Username,
Token = "gggg", Token = tokenResult.AccessToken,
Expiration = 500 TokenType = tokenResult.TokenType,
Expiration = tokenResult.Expiration
};
}
private TokenRequest RetrieveTokenRequest()
{
return new TokenRequest
{
ClientId = _clientId,
ClientSecret = _clientSecret,
Audience = _audience,
GrantType = _grantType
}; };
} }
private void InitializeValues() private void InitializeValues()
{ {
// TODO: implement parse values necessary to _clientId = _config["Auth0:ClientId"];
// retrieve a token from the appSettings using _clientSecret = _config["Auth0:ClientSecret"];
// the _config object _audience = _config["Auth0:ApiIdentifier"];
_grantType = "client_credentials";
_url = $"https://{_config["Auth0:Domain"]}";
//PrintCredentials();
}
// For testing purposes
private void PrintCredentials()
{
Console.WriteLine("Auth0 credentials:");
Console.WriteLine($"Client Id: {_clientId}");
Console.WriteLine($"Client Secret: {_clientSecret}");
Console.WriteLine($"Audience: {_audience}");
Console.WriteLine($"Url: {_url}");
}
#endregion
#region Classes
private class TokenRequest
{
[JsonProperty("client_id")]
public string ClientId { get; set; }
[JsonProperty("client_secret")]
public string ClientSecret { get; set; }
[JsonProperty("audience")]
public string Audience { get; set; }
[JsonProperty("grant_type")]
public string GrantType { get; set; }
}
private class Token
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("expires_in")]
public int Expiration { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
} }
#endregion #endregion
} }
+53 -48
View File
@@ -4,6 +4,7 @@ using System.Configuration;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@@ -13,81 +14,85 @@ using Icarus.Models.Context;
namespace Icarus.Controllers namespace Icarus.Controllers
{ {
[Route("api/Song")] [Route("api/song")]
[ApiController] [ApiController]
public class SongController : ControllerBase public class SongController : ControllerBase
{ {
#region Fields #region Fields
private IConfiguration _config; private IConfiguration _config;
private MusicStoreContext _context; private MusicStoreContext _context;
private SongManager _songMgr; private SongManager _songMgr;
#endregion #endregion
#region Properties #region Properties
#endregion #endregion
#region Constructor #region Constructor
public SongController(IConfiguration config) public SongController(IConfiguration config)
{ {
_config = config; _config = config;
_songMgr = new SongManager(config); _songMgr = new SongManager(config);
} }
#endregion #endregion
[HttpGet] [HttpGet]
[Authorize("read:song_details")]
public ActionResult<IEnumerable<Song>> Get() public ActionResult<IEnumerable<Song>> Get()
{ {
List<Song> songs = new List<Song>(); List<Song> songs = new List<Song>();
//songs = _songMgr.RetrieveAllSongDetails().Result; Console.WriteLine("Attemtping to retrieve songs");
Console.WriteLine("Attemtping to retrieve songs");
MusicStoreContext context = HttpContext.RequestServices MusicStoreContext context = HttpContext
.GetService(typeof(MusicStoreContext)) .RequestServices
as MusicStoreContext; .GetService(typeof(MusicStoreContext))
as MusicStoreContext;
songs = context.GetAllSongs(); songs = context.GetAllSongs();
return songs;
return songs;
} }
[HttpGet("{id}")] [HttpGet("{id}")]
public ActionResult<Song> Get(int id) public ActionResult<Song> Get(int id)
{ {
MusicStoreContext context = HttpContext.RequestServices MusicStoreContext context = HttpContext
.GetService(typeof(MusicStoreContext)) .RequestServices
as MusicStoreContext; .GetService(typeof(MusicStoreContext))
Song song = context.GetSong(id); as MusicStoreContext;
return song; Song song = context.GetSong(id);
}
[HttpPost] return song;
public void Post([FromBody] Song song) }
{
MusicStoreContext context = HttpContext.RequestServices
.GetService(typeof(MusicStoreContext))
as MusicStoreContext;
context.SaveSong(song); [HttpPost]
} public void Post([FromBody] Song song)
{
MusicStoreContext context = HttpContext
.RequestServices
.GetService(typeof(MusicStoreContext))
as MusicStoreContext;
context.SaveSong(song);
}
[HttpPut("{id}")] [HttpPut("{id}")]
public void Put(int id, [FromBody] Song song) public void Put(int id, [FromBody] Song song)
{ {
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]
public void Delete(int id) public void Delete(int id)
{ {
MusicStoreContext context = HttpContext.RequestServices MusicStoreContext context = HttpContext
.GetService(typeof(MusicStoreContext)) .RequestServices
as MusicStoreContext; .GetService(typeof(MusicStoreContext))
as MusicStoreContext;
context.DeleteSong(id); context.DeleteSong(id);
} }
} }
} }
+60 -54
View File
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@@ -21,68 +22,71 @@ namespace Icarus.Controllers
{ {
#region Fields #region Fields
private IConfiguration _config; private IConfiguration _config;
private SongManager _songMgr; private SongManager _songMgr;
private string _songTempDir; private string _songTempDir;
#endregion #endregion
#region Properties #region Properties
#endregion #endregion
#region Constructor #region Constructor
public SongDataController(IConfiguration config) public SongDataController(IConfiguration config)
{ {
_config = config; _config = config;
_songTempDir = _config.GetValue<string>("TemporaryMusicPath"); _songTempDir = _config.GetValue<string>("TemporaryMusicPath");
_songMgr = new SongManager(config, _songTempDir); _songMgr = new SongManager(config, _songTempDir);
} }
#endregion #endregion
[HttpGet("{id}")] [HttpGet("{id}")]
//[Route("private-scoped")] [Route("private-scoped")]
//[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))
var songMetaData = context.GetSong(id); as MusicStoreContext;
var songMetaData = context.GetSong(id);
SongData song = await _songMgr.RetrieveSong(songMetaData); SongData song = await _songMgr.RetrieveSong(songMetaData);
return File(song.Data, "application/x-msdownload", songMetaData.Filename); return File(song.Data, "application/x-msdownload", songMetaData.Filename);
} }
[HttpPost] [HttpPost]
[Authorize("upload:songs")]
public async Task Post([FromForm(Name = "file")] List<IFormFile> songData) public async Task Post([FromForm(Name = "file")] List<IFormFile> songData)
{ {
try try
{ {
MusicStoreContext context = HttpContext.RequestServices MusicStoreContext context = HttpContext
.GetService(typeof(MusicStoreContext)) .RequestServices
as MusicStoreContext; .GetService(typeof(MusicStoreContext))
as MusicStoreContext;
Console.WriteLine("Uploading song..."); Console.WriteLine("Uploading song...");
var uploads = _songTempDir; var uploads = _songTempDir;
Console.WriteLine($"Song Root Path {uploads}"); Console.WriteLine($"Song Root Path {uploads}");
foreach (var sng in songData) foreach (var sng in songData)
{ {
if (sng.Length > 0) { if (sng.Length > 0) {
await _songMgr.SaveSongToFileSystem(sng); await _songMgr.SaveSongToFileSystem(sng);
var song = _songMgr.SongDetails; var song = _songMgr.SongDetails;
context.SaveSong(song); context.SaveSong(song);
Console.WriteLine("Song successfully saved"); Console.WriteLine("Song successfully saved");
} }
}
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
} }
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
[HttpPut("{id}")] [HttpPut("{id}")]
public void Put(int id, [FromBody] SongData song) public void Put(int id, [FromBody] SongData song)
@@ -90,20 +94,22 @@ namespace Icarus.Controllers
} }
[HttpDelete("{id}")] [HttpDelete("{id}")]
[Authorize("delete:songs")]
public void Delete(int id) public void Delete(int id)
{ {
MusicStoreContext context = HttpContext.RequestServices MusicStoreContext context = HttpContext
.GetService(typeof(MusicStoreContext)) .RequestServices
as MusicStoreContext; .GetService(typeof(MusicStoreContext))
as MusicStoreContext;
var songMetaData = context.GetSong(id); var songMetaData = context.GetSong(id);
var result = _songMgr.DeleteSongFromFileSystem(songMetaData); var result = _songMgr.DeleteSongFromFileSystem(songMetaData);
if (result) if (result)
{ {
context.DeleteSong(songMetaData.Id); context.DeleteSong(songMetaData.Id);
} }
} }
} }
} }
+10 -3
View File
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
@@ -81,19 +82,25 @@ namespace Icarus.Models.Context
{ {
while (reader.Read()) while (reader.Read())
{ {
var dateCreated = reader["DateCreated"].ToString();
var lastLogin = reader["LastLogin"].ToString();
var parsedC = DateTime.Parse(dateCreated);
var parsedL = DateTime.Parse(lastLogin);
user.Id = Convert.ToInt32(reader["Id"]); user.Id = Convert.ToInt32(reader["Id"]);
user.Nickname = reader["Nickname"].ToString(); user.Nickname = reader["Nickname"].ToString();
user.Email = reader["Email"].ToString(); user.Email = reader["Email"].ToString();
user.PhoneNumber = reader["PhoneNumber"].ToString(); user.PhoneNumber = reader["PhoneNumber"].ToString();
user.EmailVerified = Boolean.Parse(reader["EmailVerified"].ToString()); user.EmailVerified = (reader["EmailVerified"].ToString()) == "1";
user.Firstname = reader["Firstname"].ToString(); user.Firstname = reader["Firstname"].ToString();
user.Lastname = reader["Lastname"].ToString(); user.Lastname = reader["Lastname"].ToString();
user.DateCreated = DateTime.ParseExact(reader["DateCreated"].ToString(), "yyyy-MM-dd HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture); user.DateCreated = DateTime.Parse(parsedC.ToString("yyyy-MM-dd HH:mm:ss"));
user.LastLogin = DateTime.ParseExact(reader["LastLogin"].ToString(), "yyyy-MM-dd HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture); user.LastLogin = DateTime.Parse(parsedL.ToString("yyyy-MM-dd HH:mm:ss"));
} }
} }
} }
} }
return user;
} }
catch (Exception ex) catch (Exception ex)
{ {
+2
View File
@@ -12,6 +12,8 @@ namespace Icarus.Models
public string Username { get; set; } public string Username { get; set; }
[JsonProperty("token")] [JsonProperty("token")]
public string Token { get; set; } public string Token { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("expiration")] [JsonProperty("expiration")]
public int Expiration { get; set; } public int Expiration { get; set; }
} }
+19 -3
View File
@@ -37,7 +37,7 @@ namespace Icarus
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton<IConfiguration>(Configuration); services.AddSingleton<IConfiguration>(Configuration);
string domain = $"https://{Configuration["Auth0:Domain"]}/"; string domain = $"https://{Configuration["Auth0:Domain"]}/";
@@ -55,8 +55,24 @@ namespace Icarus
services.AddAuthorization(options => services.AddAuthorization(options =>
{ {
options.AddPolicy("download:songs", policy => options.AddPolicy("download:songs", policy =>
policy.Requirements.Add(new HasScopeRequirement policy
("download:songs", domain))); .Requirements
.Add(new HasScopeRequirement("download:songs", domain)));
options.AddPolicy("upload:songs", policy =>
policy
.Requirements
.Add(new HasScopeRequirement("upload:songs", domain)));
options.AddPolicy("delete:songs", policy =>
policy
.Requirements
.Add(new HasScopeRequirement("delete:songs", domain)));
options.AddPolicy("read:song_details", policy =>
policy
.Requirements
.Add(new HasScopeRequirement("read:song_details", domain)));
}); });