Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 21 additions & 34 deletions Auth/LearningHub.Nhs.Auth/Controllers/AccountController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Azure.Core;
using elfhHub.Nhs.Models.Common;
using elfhHub.Nhs.Models.Enums;
using IdentityModel;
Expand All @@ -23,11 +22,9 @@
using LearningHub.Nhs.Models.Common;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using UAParser;

/// <summary>
/// Account Controller operations.
Expand Down Expand Up @@ -166,44 +163,34 @@ await this.interaction.GrantConsentAsync(

if (loginResult.IsAuthenticated)
{
var uaParser = Parser.GetDefault();
var clientInfo = uaParser.Parse(this.Request.Headers["User-Agent"]);
var result = await this.UserService.CheckUserHasAnActiveSessionAsync(userId);
if (result.Items.Count == 0 || result.Items[0].BrowserName == clientInfo.UA.Family)
{
await this.SignInUser(userId, model.Username.Trim(), model.RememberLogin, context.Parameters["ext_referer"]);
await this.SignInUser(userId, model.Username.Trim(), model.RememberLogin, context.Parameters["ext_referer"]);

if (context != null)
if (context != null)
{
if (await this.ClientStore.IsPkceClientAsync(context.Client.ClientId))
{
if (await this.ClientStore.IsPkceClientAsync(context.Client.ClientId))
{
// if the client is PKCE then we assume it's native, so this change in how to
// return the response is for better UX for the end user.
return this.View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl });
}

// we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
return this.Redirect(model.ReturnUrl);
// if the client is PKCE then we assume it's native, so this change in how to
// return the response is for better UX for the end user.
return this.View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl });
}

// request for a local page
if (this.Url.IsLocalUrl(model.ReturnUrl))
{
return this.Redirect(model.ReturnUrl);
}
else if (string.IsNullOrEmpty(model.ReturnUrl))
{
return this.Redirect("~/");
}
else
{
// user might have clicked on a malicious link - should be logged
throw new Exception("invalid return URL");
}
// we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
return this.Redirect(model.ReturnUrl);
}

// request for a local page
if (this.Url.IsLocalUrl(model.ReturnUrl))
{
return this.Redirect(model.ReturnUrl);
}
else if (string.IsNullOrEmpty(model.ReturnUrl))
{
return this.Redirect("~/");
}
else
{
return this.View("AlreadyActiveSession");
// user might have clicked on a malicious link - should be logged
throw new Exception("invalid return URL");
}
}
else if (userId > 0)
Expand Down
7 changes: 0 additions & 7 deletions Auth/LearningHub.Nhs.Auth/Interfaces/IUserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,6 @@ public interface IUserService
/// </returns>
Task StoreUserHistoryAsync(UserHistoryViewModel userHistory);

/// <summary>
/// check user has an laredy active session.
/// </summary>
/// <param name="userId">The userId.</param>
/// <returns>The <see cref="Task"/>.</returns>
Task<PagedResultSet<UserHistoryViewModel>> CheckUserHasAnActiveSessionAsync(int userId);

/// <summary>
/// The store user history async.
/// </summary>
Expand Down
24 changes: 0 additions & 24 deletions Auth/LearningHub.Nhs.Auth/Services/UserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,29 +243,5 @@ public async Task StoreUserHistoryAsync(UserHistoryViewModel userHistory)
}
}
}

/// <inheritdoc/>
public async Task<PagedResultSet<UserHistoryViewModel>> CheckUserHasAnActiveSessionAsync(int userId)
{
PagedResultSet<UserHistoryViewModel> userHistoryViewModel = new PagedResultSet<UserHistoryViewModel>();

var client = this.UserApiHttpClient.GetClient();
var request = $"UserHistory/CheckUserHasActiveSession/{userId}";
var response = await client.GetAsync(request).ConfigureAwait(false);

if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
userHistoryViewModel = JsonConvert.DeserializeObject<PagedResultSet<UserHistoryViewModel>>(result);
}
else if (response.StatusCode == HttpStatusCode.Unauthorized
||
response.StatusCode == HttpStatusCode.Forbidden)
{
throw new Exception("AccessDenied");
}

return userHistoryViewModel;
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,5 @@ public interface IUserHistoryRepository
/// The <see cref="Task"/>.
/// </returns>
Task<UserHistoryStoredProcResults> GetPagedByUserIdAsync(int userId, int startPage, int pageSize);

/// <summary>
/// Check user has an active login session.
/// </summary>
/// <param name="userId">The userId.</param>
/// <returns>The <see cref="Task"/>.</returns>
Task<UserHistoryStoredProcResults> CheckUserHasActiveSessionAsync(int userId);
}
}
24 changes: 1 addition & 23 deletions LearningHub.Nhs.UserApi.Repository/UserHistoryRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using LearningHub.Nhs.UserApi.Repository.Interface;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;

/// <summary>
/// The user history repository.
Expand Down Expand Up @@ -67,13 +66,11 @@ public async Task CreateAsync(int userId, int tenantId, UserHistoryViewModel use
new SqlParameter("@LoginIP", SqlDbType.VarChar) { Value = userHistoryVM.LoginIP ?? (object)DBNull.Value },
new SqlParameter("@LoginSuccessFul", SqlDbType.Bit) { Value = userHistoryVM.LoginSuccessFul ?? (object)DBNull.Value },
new SqlParameter("@TenantId", SqlDbType.Int) { Value = tenantId },
new SqlParameter("@SessionId", SqlDbType.VarChar) { Value = (userHistoryVM.UserHistoryTypeId == 0 && userHistoryVM.Detail == "User logged on. Source of auth: LearningHub.Nhs.Auth Account\\Login") ? userHistoryVM.SessionId : (object)DBNull.Value },
new SqlParameter("@IsActive", SqlDbType.Bit) { Value = (userHistoryVM.UserHistoryTypeId == 0 && userHistoryVM.Detail == "User logged on. Source of auth: LearningHub.Nhs.Auth Account\\Login") ? userHistoryVM.IsActive : (object)DBNull.Value },
new SqlParameter("@AmendUserId", SqlDbType.Int) { Value = userId },
new SqlParameter("@AmendDate", SqlDbType.DateTimeOffset) { Value = DateTimeOffset.Now },
};

string sql = "proc_UserHistoryInsert @UserId, @UserHistoryTypeId, @Detail, @UserAgent, @BrowserName, @BrowserVersion, @UrlReferer, @LoginIP, @LoginSuccessFul, @TenantId, @SessionId, @IsActive, @AmendUserId, @AmendDate";
string sql = "proc_UserHistoryInsert @UserId, @UserHistoryTypeId, @Detail, @UserAgent, @BrowserName, @BrowserVersion, @UrlReferer, @LoginIP, @LoginSuccessFul, @TenantId, @AmendUserId, @AmendDate";

await this.DbContext.Database.ExecuteSqlRawAsync(sql, sqlParams);
}
Expand Down Expand Up @@ -101,24 +98,5 @@ public async Task<UserHistoryStoredProcResults> GetPagedByUserIdAsync(int userId

return retVal;
}

/// <inheritdoc/>
public async Task<UserHistoryStoredProcResults> CheckUserHasActiveSessionAsync(int userId)
{
try
{
var retVal = new UserHistoryStoredProcResults();
var param0 = new SqlParameter("@p0", SqlDbType.Int) { Value = userId };

var result = await this.DbContext.Set<UserHistoryStoredProcResult>().FromSqlRaw(
"dbo.proc_ActiveLearningHubUserbyId @p0", param0).AsNoTracking().ToListWithNoLockAsync();
retVal.Results = result;
return retVal;
}
catch (Exception ex)
{
return null;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,5 @@ public interface IUserHistoryService
/// The <see cref="Task"/>.
/// </returns>
Task<PagedResultSet<UserHistoryViewModel>> GetUserHistoryPageAsync(int page, int pageSize, string sortColumn = "", string sortDirection = "", string presetFilter = "", string filter = "");

/// <summary>
/// Check user has an active login session.
/// </summary>
/// <param name="userId">The userId.</param>
/// <returns>The <see cref="Task"/>.</returns>
Task<PagedResultSet<UserHistoryViewModel>> CheckUserHasActiveSessionAsync(int userId);
}
}
13 changes: 0 additions & 13 deletions LearningHub.Nhs.UserApi.Services/UserHistoryService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
namespace LearningHub.Nhs.UserApi.Services
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Expand Down Expand Up @@ -57,8 +56,6 @@ public async Task<LearningHubValidationResult> CreateAsync(UserHistoryViewModel

if (retVal.IsValid)
{
userHistoryVM.SessionId = Guid.NewGuid().ToString();
userHistoryVM.IsActive = true;
await this.userHistoryRepository.CreateAsync(userHistoryVM.UserId, this.settings.LearningHubTenantId, userHistoryVM);
}

Expand Down Expand Up @@ -102,16 +99,6 @@ public async Task<PagedResultSet<UserHistoryViewModel>> GetUserHistoryPageAsync(
return result;
}

/// <inheritdoc/>
public async Task<PagedResultSet<UserHistoryViewModel>> CheckUserHasActiveSessionAsync(int userId)
{
PagedResultSet<UserHistoryViewModel> result = new PagedResultSet<UserHistoryViewModel>();
var userHistory = await this.userHistoryRepository.CheckUserHasActiveSessionAsync(userId);
userHistory.Results.ForEach(x => x.UserAgent = this.ParseUserAgentString(x.UserAgent));
result.Items = this.mapper.Map<List<UserHistoryViewModel>>(userHistory.Results);
return result;
}

private string ParseUserAgentString(string userAgent)
{
string retVal = string.Empty;
Expand Down
13 changes: 0 additions & 13 deletions LearningHub.Nhs.UserApi/Controllers/UserHistoryController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,6 @@ public async Task<IActionResult> GetUserHistoryPageAsync(int page, int pageSize,
return this.Ok(pagedResultSet);
}

/// <summary>
/// Check the user has an active login session.
/// </summary>
/// <param name="userId">The UserId.</param>
/// <returns>The <see cref="Task"/>.</returns>
[HttpGet]
[Route("CheckUserHasActiveSession/{userId}")]
public async Task<IActionResult> CheckUserHasActiveSessionAsync(int userId)
{
PagedResultSet<UserHistoryViewModel> pagedResultSet = await this.userHistoryService.CheckUserHasActiveSessionAsync(userId);
return this.Ok(pagedResultSet);
}

/// <summary>
/// Create a UserHistory.
/// </summary>
Expand Down
Loading