11namespace LearningHub . Nhs . WebUI . Controllers
22{
3- using System ;
4- using System . Diagnostics ;
5- using System . IO ;
6- using System . Net ;
7- using System . Threading . Tasks ;
8- using LearningHub . Nhs . WebUI . Configuration ;
9- using LearningHub . Nhs . WebUI . EventSource ;
10- using LearningHub . Nhs . WebUI . Interfaces ;
11- using Microsoft . AspNetCore . Authorization ;
12- using Microsoft . AspNetCore . Mvc ;
13- using Microsoft . AspNetCore . StaticFiles ;
14- using Microsoft . Extensions . Options ;
3+ using System ;
4+ using System . Diagnostics ;
5+ using System . IO ;
6+ using System . Net ;
7+ using System . Threading . Tasks ;
8+ using LearningHub . Nhs . WebUI . Configuration ;
9+ using LearningHub . Nhs . WebUI . EventSource ;
10+ using LearningHub . Nhs . WebUI . Interfaces ;
11+ using Microsoft . AspNetCore . Authorization ;
12+ using Microsoft . AspNetCore . Mvc ;
13+ using Microsoft . AspNetCore . StaticFiles ;
14+ using Microsoft . Extensions . Options ;
15+
16+ /// <summary>
17+ /// Defines the <see cref="LearningSessionsController" />.
18+ /// </summary>
19+ public class LearningSessionsController : Controller
20+ {
21+ private readonly IResourceService resourceService ;
22+ private readonly IFileService fileService ;
23+ private readonly IOptions < Settings > settings ;
24+ private readonly IUserGroupService userGroupService ;
1525
1626 /// <summary>
17- /// Defines the <see cref="LearningSessionsController" /> .
27+ /// Initializes a new instance of the <see cref="LearningSessionsController"/> class .
1828 /// </summary>
19- public class LearningSessionsController : Controller
29+ /// <param name="resourceService">Resource service.</param>
30+ /// <param name="fileService">File service.</param>
31+ /// <param name="settings">Settings.</param>
32+ /// <param name="userGroupService">userGroupService.</param>
33+ public LearningSessionsController (
34+ IResourceService resourceService ,
35+ IFileService fileService ,
36+ IOptions < Settings > settings ,
37+ IUserGroupService userGroupService )
2038 {
21- private readonly IResourceService resourceService ;
22- private readonly IFileService fileService ;
23- private readonly IOptions < Settings > settings ;
24- private readonly IUserGroupService userGroupService ;
39+ this . resourceService = resourceService ;
40+ this . fileService = fileService ;
41+ this . settings = settings ;
42+ this . userGroupService = userGroupService ;
43+ }
2544
26- /// <summary>
27- /// Initializes a new instance of the <see cref="LearningSessionsController"/> class.
28- /// </summary>
29- /// <param name="resourceService">Resource service.</param>
30- /// <param name="fileService">File service.</param>
31- /// <param name="settings">Settings.</param>
32- /// <param name="userGroupService">userGroupService.</param>
33- public LearningSessionsController (
34- IResourceService resourceService ,
35- IFileService fileService ,
36- IOptions < Settings > settings ,
37- IUserGroupService userGroupService )
38- {
39- this . resourceService = resourceService ;
40- this . fileService = fileService ;
41- this . settings = settings ;
42- this . userGroupService = userGroupService ;
43- }
45+ /// <summary>
46+ /// The Scorm.
47+ /// </summary>
48+ /// <param name="id">id.</param>
49+ /// <returns>bool.</returns>
50+ public async Task < IActionResult > Scorm ( int id )
51+ {
52+ var rv = await this . resourceService . GetItemByIdAsync ( id ) ;
53+ if ( rv != null )
54+ {
55+ this . ViewBag . FilePath = $ "/ScormContent/{ rv . ScormDetails . ContentFilePath } /{ rv . ScormDetails . ScormManifest . ManifestUrl } ";
56+ }
4457
45- /// <summary>
46- /// The Scorm.
47- /// </summary>
48- /// <param name="id">id.</param>
49- /// <returns>bool.</returns>
50- public async Task < IActionResult > Scorm ( int id )
51- {
52- var rv = await this . resourceService . GetItemByIdAsync ( id ) ;
53- if ( rv != null )
54- {
55- this . ViewBag . FilePath = $ "/ScormContent/{ rv . ScormDetails . ContentFilePath } /{ rv . ScormDetails . ScormManifest . ManifestUrl } ";
56- }
58+ this . ViewBag . ResourceReferenceId = id ;
59+ this . ViewBag . KeepUserSessionAliveInterval = Convert . ToInt32 ( this . settings . Value . KeepUserSessionAliveIntervalMins ) * 60000 ;
60+ this . ViewBag . UseTraceWindow = await this . userGroupService . UserHasPermissionAsync ( "Scorm_Trace_Window" ) ;
5761
58- this . ViewBag . ResourceReferenceId = id ;
59- this . ViewBag . KeepUserSessionAliveInterval = Convert . ToInt32 ( this . settings . Value . KeepUserSessionAliveIntervalMins ) * 60000 ;
60- this . ViewBag . UseTraceWindow = await this . userGroupService . UserHasPermissionAsync ( "Scorm_Trace_Window" ) ;
62+ return this . View ( ) ;
63+ }
6164
62- return this . View ( ) ;
63- }
65+ /// <summary>
66+ /// The ScormContent.
67+ /// </summary>
68+ /// <param name="filePath">filePath.</param>
69+ /// <returns>bool.</returns>
70+ //// [ResponseCache(VaryByQueryKeys = new[] { "*" }, Duration = 0, NoStore = true)] // disable caching
71+ //// Removed Request.Headers["Referer"] Referer URL checking based on issue reported in TD-4283
72+ [ AllowAnonymous ]
73+ [ Route ( "ScormContent/{*filePath}" ) ]
74+ public async Task < IActionResult > ScormContent ( string filePath )
75+ {
76+ IActionResult result ;
77+ var sw = Stopwatch . StartNew ( ) ;
78+ long bytesServed = 0 ;
79+ string fileName = string . Empty ;
6480
65- /// <summary>
66- /// The ScormContent.
67- /// </summary>
68- /// <param name="filePath">filePath.</param>
69- /// <returns>bool.</returns>
70- //// [ResponseCache(VaryByQueryKeys = new[] { "*" }, Duration = 0, NoStore = true)] // disable caching
71- //// Removed Request.Headers["Referer"] Referer URL checking based on issue reported in TD-4283
72- [ AllowAnonymous ]
73- [ Route ( "ScormContent/{*filePath}" ) ]
74- public async Task < IActionResult > ScormContent ( string filePath )
81+ try
82+ {
83+ if ( ! this . User . Identity . IsAuthenticated )
7584 {
76- IActionResult result ;
77- var sw = Stopwatch . StartNew ( ) ;
78- long bytesServed = 0 ;
79- string fileName = string . Empty ;
80-
81- try
82- {
83- if ( ! this . User . Identity . IsAuthenticated )
84- {
85- throw new UnauthorizedAccessException ( "User is not authenticated." ) ;
86- }
87-
88- var directory = filePath . Substring ( 0 , filePath . LastIndexOf ( "/" ) ) ;
89- fileName = filePath . Substring ( filePath . LastIndexOf ( "/" ) + 1 , filePath . Length - filePath . LastIndexOf ( "/" ) - 1 ) ;
90-
91- var file = await this . fileService . DownloadFileAsync ( directory , fileName ) ;
85+ throw new UnauthorizedAccessException ( "User is not authenticated." ) ;
86+ }
9287
93- if ( ! new FileExtensionContentTypeProvider ( ) . TryGetContentType ( fileName , out var contentType ) )
94- {
95- contentType = "application/octet-stream" ;
96- }
88+ var directory = filePath . Substring ( 0 , filePath . LastIndexOf ( "/" ) ) ;
89+ fileName = filePath . Substring ( filePath . LastIndexOf ( "/" ) + 1 , filePath . Length - filePath . LastIndexOf ( "/" ) - 1 ) ;
90+ string extension = Path . GetExtension ( fileName ) ;
9791
98- result = this . File ( file . Content , contentType ) ;
99- bytesServed = file . ContentLength ;
100- }
101- catch ( Azure . RequestFailedException rfe ) when ( rfe . Status == ( int ) HttpStatusCode . NotFound )
102- {
103- result = this . NotFound ( ) ;
104- }
105- catch ( UnauthorizedAccessException ex )
106- {
107- this . ViewBag . FilePath = filePath ;
108- this . ViewBag . ErrorMessage = "Unauthorised" ;
109- this . ViewBag . ErrorDetail = ex . Message ;
110- result = this . View ( ) ;
111- }
112- catch ( Exception ex )
113- {
114- this . ViewBag . FilePath = filePath ;
115- this . ViewBag . ErrorMessage = "Unable to find content." ;
116- this . ViewBag . ErrorDetail = ex . Message ;
117- result = this . View ( ) ;
118- }
92+ var file = await this . fileService . DownloadFileAsync ( directory , fileName ) ;
11993
120- ScormContentEventSource . Instance . AddRequestProcessMetadata ( sw . ElapsedMilliseconds , bytesServed , Path . GetExtension ( fileName ) ) ;
121- return result ;
94+ if ( ! new FileExtensionContentTypeProvider ( ) . TryGetContentType ( fileName , out var contentType ) )
95+ {
96+ contentType = "application/octet-stream" ;
12297 }
12398
124- /// <summary>
125- /// The TraceWindow.
126- /// </summary>
127- /// <returns>bool.</returns>
128- public IActionResult TraceWindow ( )
99+ if ( extension == ".mp4" )
129100 {
130- return this . View ( ) ;
101+ contentType = "application/x-mpegURL" ;
131102 }
103+
104+ result = this . File ( file . Content , contentType ) ;
105+ bytesServed = file . ContentLength ;
106+ }
107+ catch ( Azure . RequestFailedException rfe ) when ( rfe . Status == ( int ) HttpStatusCode . NotFound )
108+ {
109+ result = this . NotFound ( ) ;
110+ }
111+ catch ( UnauthorizedAccessException ex )
112+ {
113+ this . ViewBag . FilePath = filePath ;
114+ this . ViewBag . ErrorMessage = "Unauthorised" ;
115+ this . ViewBag . ErrorDetail = ex . Message ;
116+ result = this . View ( ) ;
117+ }
118+ catch ( Exception ex )
119+ {
120+ this . ViewBag . FilePath = filePath ;
121+ this . ViewBag . ErrorMessage = "Unable to find content." ;
122+ this . ViewBag . ErrorDetail = ex . Message ;
123+ result = this . View ( ) ;
124+ }
125+
126+ ScormContentEventSource . Instance . AddRequestProcessMetadata ( sw . ElapsedMilliseconds , bytesServed , Path . GetExtension ( fileName ) ) ;
127+ return result ;
128+ }
129+
130+ /// <summary>
131+ /// The TraceWindow.
132+ /// </summary>
133+ /// <returns>bool.</returns>
134+ public IActionResult TraceWindow ( )
135+ {
136+ return this . View ( ) ;
132137 }
138+ }
133139}
0 commit comments