Skip to content

Commit 7db18da

Browse files
Merge pull request #1102 from TechnologyEnhancedLearning/Develop/Fixes/TD-3734-Concurrent-Session
TD-3734-Concurrent session-SIT fixes
2 parents e04b7af + 269bf89 commit 7db18da

File tree

5 files changed

+89
-29
lines changed

5 files changed

+89
-29
lines changed

LearningHub.Nhs.WebUI/Controllers/HomeController.cs

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace LearningHub.Nhs.WebUI.Controllers
66
using System.Linq;
77
using System.Net.Http;
88
using System.Threading.Tasks;
9+
using AspNetCoreRateLimit;
910
using elfhHub.Nhs.Models.Common;
1011
using elfhHub.Nhs.Models.Enums;
1112
using LearningHub.Nhs.Models.Content;
@@ -26,6 +27,7 @@ namespace LearningHub.Nhs.WebUI.Controllers
2627
using Microsoft.Extensions.Logging;
2728
using Microsoft.Extensions.Options;
2829
using Microsoft.FeatureManagement;
30+
using UAParser;
2931
using Settings = LearningHub.Nhs.WebUI.Configuration.Settings;
3032

3133
/// <summary>
@@ -206,43 +208,54 @@ public async Task<IActionResult> Index(string myLearningDashboard = "my-in-progr
206208
{
207209
if (this.User?.Identity.IsAuthenticated == true)
208210
{
209-
this.Settings.ConcurrentId = this.CurrentUserId;
210-
this.Logger.LogInformation("User is authenticated: User is {fullname} and userId is: {lhuserid}", this.User.Identity.GetCurrentName(), this.User.Identity.GetCurrentUserId());
211-
if (this.User.IsInRole("Administrator") || this.User.IsInRole("BlueUser") || this.User.IsInRole("ReadOnly") || this.User.IsInRole("BasicUser"))
211+
var userHistoryDetail = await this.userService.CheckUserHasAnActiveSessionAsync(this.CurrentUserId);
212+
var uaParser = Parser.GetDefault();
213+
var clientInfo = uaParser.Parse(this.Request.Headers["User-Agent"]);
214+
215+
if (userHistoryDetail.Items.Count == 0 || userHistoryDetail.Items[0].BrowserName == clientInfo.UA.Family)
212216
{
213-
var learningTask = this.dashboardService.GetMyAccessLearningsAsync(myLearningDashboard, 1);
214-
var resourcesTask = this.dashboardService.GetResourcesAsync(resourceDashboard, 1);
215-
var cataloguesTask = this.dashboardService.GetCataloguesAsync(catalogueDashboard, 1);
216-
217-
var enrolledCoursesTask = Task.FromResult(new List<MoodleCourseResponseViewModel>());
218-
var enableMoodle = Task.Run(() => this.featureManager.IsEnabledAsync(FeatureFlags.EnableMoodle)).Result;
219-
this.ViewBag.EnableMoodle = enableMoodle;
220-
this.ViewBag.ValidMoodleUser = this.CurrentMoodleUserId > 0;
221-
if (enableMoodle && myLearningDashboard == "my-enrolled-courses")
217+
this.Settings.ConcurrentId = this.CurrentUserId;
218+
this.Logger.LogInformation("User is authenticated: User is {fullname} and userId is: {lhuserid}", this.User.Identity.GetCurrentName(), this.User.Identity.GetCurrentUserId());
219+
if (this.User.IsInRole("Administrator") || this.User.IsInRole("BlueUser") || this.User.IsInRole("ReadOnly") || this.User.IsInRole("BasicUser"))
222220
{
223-
enrolledCoursesTask = this.dashboardService.GetEnrolledCoursesFromMoodleAsync(this.CurrentMoodleUserId, 1);
221+
var learningTask = this.dashboardService.GetMyAccessLearningsAsync(myLearningDashboard, 1);
222+
var resourcesTask = this.dashboardService.GetResourcesAsync(resourceDashboard, 1);
223+
var cataloguesTask = this.dashboardService.GetCataloguesAsync(catalogueDashboard, 1);
224+
225+
var enrolledCoursesTask = Task.FromResult(new List<MoodleCourseResponseViewModel>());
226+
var enableMoodle = Task.Run(() => this.featureManager.IsEnabledAsync(FeatureFlags.EnableMoodle)).Result;
227+
this.ViewBag.EnableMoodle = enableMoodle;
228+
this.ViewBag.ValidMoodleUser = this.CurrentMoodleUserId > 0;
229+
if (enableMoodle && myLearningDashboard == "my-enrolled-courses")
230+
{
231+
enrolledCoursesTask = this.dashboardService.GetEnrolledCoursesFromMoodleAsync(this.CurrentMoodleUserId, 1);
232+
}
233+
234+
await Task.WhenAll(learningTask, resourcesTask, cataloguesTask);
235+
236+
var model = new DashboardViewModel()
237+
{
238+
MyLearnings = await learningTask,
239+
Resources = await resourcesTask,
240+
Catalogues = await cataloguesTask,
241+
EnrolledCourses = await enrolledCoursesTask,
242+
};
243+
244+
if (!string.IsNullOrEmpty(this.Request.Query["preview"]) && Convert.ToBoolean(this.Request.Query["preview"]))
245+
{
246+
return this.View("LandingPage", await this.GetLandingPageContent(Convert.ToBoolean(this.Request.Query["preview"])));
247+
}
248+
249+
return this.View("Dashboard", model);
224250
}
225-
226-
await Task.WhenAll(learningTask, resourcesTask, cataloguesTask);
227-
228-
var model = new DashboardViewModel()
251+
else
229252
{
230-
MyLearnings = await learningTask,
231-
Resources = await resourcesTask,
232-
Catalogues = await cataloguesTask,
233-
EnrolledCourses = await enrolledCoursesTask,
234-
};
235-
236-
if (!string.IsNullOrEmpty(this.Request.Query["preview"]) && Convert.ToBoolean(this.Request.Query["preview"]))
237-
{
238-
return this.View("LandingPage", await this.GetLandingPageContent(Convert.ToBoolean(this.Request.Query["preview"])));
253+
return this.RedirectToAction("InvalidUserAccount", "Account");
239254
}
240-
241-
return this.View("Dashboard", model);
242255
}
243256
else
244257
{
245-
return this.RedirectToAction("InvalidUserAccount", "Account");
258+
return this.RedirectToAction("AlreadyAnActiveSession", "Account");
246259
}
247260
}
248261
else

LearningHub.Nhs.WebUI/Interfaces/IUserService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,13 @@ public interface IUserService
465465
/// <returns>providers.</returns>
466466
Task<List<ProviderViewModel>> GetProvidersByUserIdAsync(int userId);
467467

468+
/// <summary>
469+
/// To Check User Has An ActiveSession.
470+
/// </summary>
471+
/// <param name="userId">The userId.</param>
472+
/// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns>
473+
Task<PagedResultSet<UserHistoryViewModel>> CheckUserHasAnActiveSessionAsync(int userId);
474+
468475
/// <summary>
469476
/// To get the Base64MD5HashDigest value.
470477
/// </summary>

LearningHub.Nhs.WebUI/LearningHub.Nhs.WebUI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
</PackageReference>
144144
<PackageReference Include="NLog.Schema" Version="5.3.4" />
145145
<PackageReference Include="NLog.Web.AspNetCore" Version="4.15.0" />
146+
<PackageReference Include="UAParser" Version="3.1.47" />
146147
<PackageReference Include="UK.NHS.CookieBanner" Version="2.0.7" />
147148
</ItemGroup>
148149

LearningHub.Nhs.WebUI/Services/UserService.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,30 @@ public async Task<List<ProviderViewModel>> GetProvidersByUserIdAsync(int userId)
18641864
return viewmodel;
18651865
}
18661866

1867+
/// <inheritdoc/>
1868+
public async Task<PagedResultSet<UserHistoryViewModel>> CheckUserHasAnActiveSessionAsync(int userId)
1869+
{
1870+
PagedResultSet<UserHistoryViewModel> userHistoryViewModel = new PagedResultSet<UserHistoryViewModel>();
1871+
1872+
var client = await this.userApiHttpClient.GetClientAsync();
1873+
var request = $"UserHistory/CheckUserHasActiveSession/{userId}";
1874+
var response = await client.GetAsync(request).ConfigureAwait(false);
1875+
1876+
if (response.IsSuccessStatusCode)
1877+
{
1878+
var result = await response.Content.ReadAsStringAsync();
1879+
userHistoryViewModel = JsonConvert.DeserializeObject<PagedResultSet<UserHistoryViewModel>>(result);
1880+
}
1881+
else if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden)
1882+
{
1883+
throw new Exception("AccessDenied");
1884+
}
1885+
1886+
return userHistoryViewModel;
1887+
}
1888+
1889+
1890+
18671891
/// <summary>
18681892
/// The base 64 m d 5 hash digest.
18691893
/// </summary>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@{
2+
ViewData["Title"] = "Already active session";
3+
}
4+
<div class="bg-white">
5+
<div class="nhsuk-width-container app-width-container">
6+
<div class="nhsuk-grid-row">
7+
<div class="nhsuk-grid-column-full nhsuk-u-padding-top-9 nhsuk-u-padding-bottom-7">
8+
<h1 class="nhsuk-heading-xl"> @ViewData["Title"]</h1>
9+
<p>You are already logged in from another browser. Please continue using the same browser or close the existing session and try again with a new one.</p>
10+
<p>If you have any questions, please contact the <a href="@ViewBag.SupportFormUrl" target="_blank">support team</a>.</p>
11+
<p>@DateTimeOffset.Now.ToString("d MMMM yyyy HH:mm:ss")</p>
12+
</div>
13+
</div>
14+
</div>
15+
</div>

0 commit comments

Comments
 (0)