v20190302.1

This commit is contained in:
Steven Hildreth 2019-03-02 14:18:41 -06:00
parent eee6f88283
commit 1b8d4a58b6
5 changed files with 118 additions and 77 deletions

View file

@ -57,14 +57,13 @@ namespace Roadie.Api.Services
} }
data.UserTrack userTrack = null; data.UserTrack userTrack = null;
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
track.PlayedCount = (track.PlayedCount ?? 0) + 1;
track.LastPlayed = now; try
var user = roadieUser != null ? this.DbContext.Users {
.Include(x => x.TrackRatings) var user = roadieUser != null ? this.DbContext.Users.FirstOrDefault(x => x.RoadieId == roadieUser.UserId) : null;
.FirstOrDefault(x => x.RoadieId == roadieUser.UserId) : null;
if (user != null) if (user != null)
{ {
userTrack = user.TrackRatings.FirstOrDefault(x => x.TrackId == track.Id); userTrack = this.DbContext.UserTracks.FirstOrDefault(x => x.UserId == user.Id && x.TrackId == track.Id);
if (userTrack == null) if (userTrack == null)
{ {
userTrack = new data.UserTrack(now) userTrack = new data.UserTrack(now)
@ -77,7 +76,16 @@ namespace Roadie.Api.Services
userTrack.LastPlayed = now; userTrack.LastPlayed = now;
userTrack.PlayedCount = (userTrack.PlayedCount ?? 0) + 1; userTrack.PlayedCount = (userTrack.PlayedCount ?? 0) + 1;
this.CacheManager.ClearRegion(user.CacheRegion); this.CacheManager.ClearRegion(user.CacheRegion);
await this.DbContext.SaveChangesAsync();
} }
}
catch (Exception ex)
{
this.Logger.LogError(ex, $"Error in CreatePlayActivity, Creating UserTrack: User `{ roadieUser}` TrackId [{ track.Id }");
}
track.PlayedCount = (track.PlayedCount ?? 0) + 1;
track.LastPlayed = now;
var release = this.DbContext.Releases.Include(x => x.Artist).FirstOrDefault(x => x.RoadieId == track.ReleaseMedia.Release.RoadieId); var release = this.DbContext.Releases.Include(x => x.Artist).FirstOrDefault(x => x.RoadieId == track.ReleaseMedia.Release.RoadieId);
release.LastPlayed = now; release.LastPlayed = now;

View file

@ -628,11 +628,39 @@ namespace Roadie.Api.Services
} }
var trackFileInfo = new FileInfo(trackPath); var trackFileInfo = new FileInfo(trackPath);
if (!trackFileInfo.Exists) if (!trackFileInfo.Exists)
{
// Not Found try recanning release
var release = (from r in this.DbContext.Releases
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
where rm.Id == track.ReleaseMediaId
select r).FirstOrDefault();
if (!release.IsLocked ?? false)
{
await this.AdminService.ScanRelease(new Library.Identity.ApplicationUser
{
Id = roadieUser.Id.Value
}, release.RoadieId, false, true);
}
track = this.DbContext.Tracks.FirstOrDefault(x => x.RoadieId == trackId);
if (track == null)
{
return new OperationResult<TrackStreamInfo>($"TrackStreamInfo: Unable To Find Track [{ trackId }]");
}
try
{
trackPath = track.PathToTrack(this.Configuration, this.Configuration.LibraryFolder);
}
catch (Exception ex)
{
return new OperationResult<TrackStreamInfo>(ex);
}
if (!trackFileInfo.Exists)
{ {
track.UpdateTrackMissingFile(); track.UpdateTrackMissingFile();
await this.DbContext.SaveChangesAsync(); await this.DbContext.SaveChangesAsync();
return new OperationResult<TrackStreamInfo>($"TrackStreamInfo: TrackId [{trackId}] Unable to Find Track [{trackFileInfo.FullName}]"); return new OperationResult<TrackStreamInfo>($"TrackStreamInfo: TrackId [{trackId}] Unable to Find Track [{trackFileInfo.FullName}]");
} }
}
var contentDurationTimeSpan = TimeSpan.FromMilliseconds((double)(track.Duration ?? 0)); var contentDurationTimeSpan = TimeSpan.FromMilliseconds((double)(track.Duration ?? 0));
var info = new TrackStreamInfo var info = new TrackStreamInfo
{ {

View file

@ -1,8 +1,8 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Roadie.Api.Models; using Roadie.Api.Models;
@ -10,14 +10,11 @@ using Roadie.Api.Services;
using Roadie.Library.Caching; using Roadie.Library.Caching;
using Roadie.Library.Configuration; using Roadie.Library.Configuration;
using Roadie.Library.Identity; using Roadie.Library.Identity;
using Roadie.Library.Utility;
using System; using System;
using System.Linq; using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.WebUtilities;
using Roadie.Library.Utility;
namespace Roadie.Api.Controllers namespace Roadie.Api.Controllers
{ {
@ -32,11 +29,11 @@ namespace Roadie.Api.Controllers
private readonly SignInManager<ApplicationUser> SignInManager; private readonly SignInManager<ApplicationUser> SignInManager;
private readonly ITokenService TokenService; private readonly ITokenService TokenService;
private readonly UserManager<ApplicationUser> UserManager; private readonly UserManager<ApplicationUser> UserManager;
private IRoadieSettings RoadieSettings { get; }
private ICacheManager CacheManager { get; }
private IAdminService AdminService { get; } private IAdminService AdminService { get; }
private ICacheManager CacheManager { get; }
private IEmailSender EmailSender { get; } private IEmailSender EmailSender { get; }
private IHttpContext RoadieHttpContext { get; } private IHttpContext RoadieHttpContext { get; }
private IRoadieSettings RoadieSettings { get; }
public AccountController( public AccountController(
IAdminService adminService, IAdminService adminService,
@ -63,6 +60,22 @@ namespace Roadie.Api.Controllers
this.RoadieHttpContext = httpContext; this.RoadieHttpContext = httpContext;
} }
[HttpGet("confirmemail")]
public IActionResult ConfirmEmail(string userid, string code)
{
var user = this.UserManager.FindByIdAsync(userid).Result;
IdentityResult result = this.UserManager.ConfirmEmailAsync(user, code).Result;
if (result.Succeeded)
{
this.Logger.LogInformation("User [{0}] Confirmed Email Successfully", userid);
return Content($"Email for { this.RoadieSettings.SiteName } account confirmed successfully!");
}
else
{
return Content("Error while confirming your email!");
}
}
[HttpPost] [HttpPost]
[Route("token")] [Route("token")]
public async Task<IActionResult> CreateToken([FromBody]LoginModel model) public async Task<IActionResult> CreateToken([FromBody]LoginModel model)
@ -84,14 +97,13 @@ namespace Roadie.Api.Controllers
await UserManager.UpdateAsync(user); await UserManager.UpdateAsync(user);
var t = await this.TokenService.GenerateToken(user, this.UserManager); var t = await this.TokenService.GenerateToken(user, this.UserManager);
this.Logger.LogInformation($"Successfully authenticated User [{ model.Username}]"); this.Logger.LogInformation($"Successfully authenticated User [{ model.Username}]");
if(!user.EmailConfirmed) if (!user.EmailConfirmed)
{ {
try try
{ {
var code = await this.UserManager.GenerateEmailConfirmationTokenAsync(user); var code = await this.UserManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, Request.Scheme); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, Request.Scheme);
await this.EmailSender.SendEmailAsync(user.Email, $"Confirm your { this.RoadieSettings.SiteName } email", $"Please confirm your { this.RoadieSettings.SiteName } account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); await this.EmailSender.SendEmailAsync(user.Email, $"Confirm your { this.RoadieSettings.SiteName } email", $"Please confirm your { this.RoadieSettings.SiteName } account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -149,10 +161,12 @@ namespace Roadie.Api.Controllers
{ {
if (ModelState.IsValid) if (ModelState.IsValid)
{ {
var now = DateTime.UtcNow;
var user = new ApplicationUser var user = new ApplicationUser
{ {
UserName = registerModel.Username, UserName = registerModel.Username,
RegisteredOn = DateTime.UtcNow, RegisteredOn = now,
LastLogin = now,
DoUseHtmlPlayer = true, DoUseHtmlPlayer = true,
Email = registerModel.Email Email = registerModel.Email
}; };
@ -160,14 +174,20 @@ namespace Roadie.Api.Controllers
var identityResult = await this.UserManager.CreateAsync(user, registerModel.Password); var identityResult = await this.UserManager.CreateAsync(user, registerModel.Password);
if (identityResult.Succeeded) if (identityResult.Succeeded)
{ {
if(user.Id == 1) if (user.Id == 1)
{ {
await this.AdminService.DoInitialSetup(user, this.UserManager); await this.AdminService.DoInitialSetup(user, this.UserManager);
} }
try
{
var code = await this.UserManager.GenerateEmailConfirmationTokenAsync(user); var code = await this.UserManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, Request.Scheme); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, Request.Scheme);
await this.EmailSender.SendEmailAsync(user.Email, $"Confirm your { this.RoadieSettings.SiteName } email", $"Please confirm your { this.RoadieSettings.SiteName } account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); await this.EmailSender.SendEmailAsync(user.Email, $"Confirm your { this.RoadieSettings.SiteName } email", $"Please confirm your { this.RoadieSettings.SiteName } account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
}
catch (Exception ex)
{
this.Logger.LogError(ex, $"Error Sending Register Email to [{ registerModel.Email }]");
}
await SignInManager.SignInAsync(user, isPersistent: false); await SignInManager.SignInAsync(user, isPersistent: false);
var t = await this.TokenService.GenerateToken(user, this.UserManager); var t = await this.TokenService.GenerateToken(user, this.UserManager);
this.Logger.LogInformation($"Successfully created and authenticated User [{ registerModel.Username}]"); this.Logger.LogInformation($"Successfully created and authenticated User [{ registerModel.Username}]");
@ -194,41 +214,6 @@ namespace Roadie.Api.Controllers
return BadRequest(ModelState); return BadRequest(ModelState);
} }
[HttpGet("confirmemail")]
public IActionResult ConfirmEmail(string userid, string code)
{
var user = this.UserManager.FindByIdAsync(userid).Result;
IdentityResult result = this.UserManager.ConfirmEmailAsync(user, code).Result;
if (result.Succeeded)
{
this.Logger.LogInformation("User [{0}] Confirmed Email Successfully", userid);
return Content($"Email for { this.RoadieSettings.SiteName } account confirmed successfully!");
}
else
{
return Content("Error while confirming your email!");
}
}
[HttpGet("sendpasswordresetemail")]
public async Task<IActionResult> SendPasswordResetEmail(string username, string callbackUrl)
{
var user = await UserManager.FindByNameAsync(username);
var token = await this.UserManager.GeneratePasswordResetTokenAsync(user);
callbackUrl = callbackUrl + "?username=" + username + "&token=" + WebEncoders.Base64UrlEncode(System.Text.Encoding.ASCII.GetBytes(token));
try
{
await this.EmailSender.SendEmailAsync(user.Email, $"Reset your { this.RoadieSettings.SiteName } password", $"A request has been made to reset your password for your { this.RoadieSettings.SiteName } account. To proceed <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>click here</a>.");
this.Logger.LogInformation("User [{0}] Email [{1}] Requested Password Reset Callback [{2}]", username, user.Email, callbackUrl);
return Ok();
}
catch (Exception ex)
{
this.Logger.LogError(ex);
}
return StatusCode(500);
}
[HttpPost("resetpassword")] [HttpPost("resetpassword")]
public async Task<IActionResult> ResetPassword([FromBody]ResetPasswordModel resetPasswordModel) public async Task<IActionResult> ResetPassword([FromBody]ResetPasswordModel resetPasswordModel)
{ {
@ -263,5 +248,24 @@ namespace Roadie.Api.Controllers
} }
return BadRequest(ModelState); return BadRequest(ModelState);
} }
[HttpGet("sendpasswordresetemail")]
public async Task<IActionResult> SendPasswordResetEmail(string username, string callbackUrl)
{
var user = await UserManager.FindByNameAsync(username);
var token = await this.UserManager.GeneratePasswordResetTokenAsync(user);
callbackUrl = callbackUrl + "?username=" + username + "&token=" + WebEncoders.Base64UrlEncode(System.Text.Encoding.ASCII.GetBytes(token));
try
{
await this.EmailSender.SendEmailAsync(user.Email, $"Reset your { this.RoadieSettings.SiteName } password", $"A request has been made to reset your password for your { this.RoadieSettings.SiteName } account. To proceed <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>click here</a>.");
this.Logger.LogInformation("User [{0}] Email [{1}] Requested Password Reset Callback [{2}]", username, user.Email, callbackUrl);
return Ok();
}
catch (Exception ex)
{
this.Logger.LogError(ex);
}
return StatusCode(500);
}
} }
} }

View file

@ -75,11 +75,11 @@ namespace Roadie.Api.Controllers
var user = this.UserManager.Users.FirstOrDefault(x => x.Id == userId); var user = this.UserManager.Users.FirstOrDefault(x => x.Id == userId);
if(user == null) if(user == null)
{ {
return StatusCode((int)HttpStatusCode.Forbidden); return StatusCode((int)HttpStatusCode.Unauthorized);
} }
if(!ServiceBase.ConfirmTrackPlayToken(user, id, trackPlayToken)) if(!ServiceBase.ConfirmTrackPlayToken(user, id, trackPlayToken))
{ {
return StatusCode((int)HttpStatusCode.Forbidden); return StatusCode((int)HttpStatusCode.Unauthorized);
} }
return await base.StreamTrack(id, this.TrackService, this.PlayActivityService, this.UserModelForUser(user)); return await base.StreamTrack(id, this.TrackService, this.PlayActivityService, this.UserModelForUser(user));
} }

View file

@ -50,6 +50,7 @@
"ConnectionStrings": { "ConnectionStrings": {
"RoadieDatabaseConnection": "server=voyager;userid=roadie;password=MenAtW0rk668;persistsecurityinfo=True;database=roadie_dev;ConvertZeroDateTime=true;Max Pool Size=200;default command timeout=180;" "RoadieDatabaseConnection": "server=voyager;userid=roadie;password=MenAtW0rk668;persistsecurityinfo=True;database=roadie_dev;ConvertZeroDateTime=true;Max Pool Size=200;default command timeout=180;"
}, },
"CORSOrigins": "http://localhost:8080|https://localhost:8080|http://localhost:80|https://localhost:80|http://192.168.1.177:8080",
"RoadieSettings": { "RoadieSettings": {
"SiteName": "Roadie", "SiteName": "Roadie",
"DefaultTimeZone": "US/Central", "DefaultTimeZone": "US/Central",