Skip to content

Commit

Permalink
Merge pull request #13 from valadas/security-api
Browse files Browse the repository at this point in the history
Implemented API to get security bulletins
  • Loading branch information
david-poindexter authored Feb 27, 2022
2 parents 28652a7 + ae9cefb commit 17782b8
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 0 deletions.
51 changes: 51 additions & 0 deletions Controllers/SecurityController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// MIT License
// Copyright DNN Community

using Dnn.Modules.SecurityCenter.Services;
using DotNetNuke.Web.Api;
using System;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;

namespace Dnn.Modules.SecurityCenter.Controllers
{
/// <summary>
/// Provides information about DNN security services.
/// </summary>
public class SecurityController : ModuleApiController
{
private readonly ISecurityService securityService;

/// <summary>
/// Initializes a new instance of the <see cref="SecurityController"/> class.
/// </summary>
/// <param name="securityService">Provides access to DNN security bulletins service.</param>
public SecurityController(ISecurityService securityService)
{
this.securityService = securityService;
}

/// <summary>
/// Gets all the DNN security bulletins.
/// </summary>
/// <param name="versionString">The version for which to get the security bulletins for in the format 090202 for v9.9.2.</param>
/// <returns>A list of DNN security bulletins.</returns>
[ValidateAntiForgeryToken]
[HttpGet]
[DnnModuleAuthorize(AccessLevel = DotNetNuke.Security.SecurityAccessLevel.View)]
public async Task<IHttpActionResult> GetSecurityBulletins(string versionString)
{
try
{
var viewModel = await this.securityService.GetAllSecurityBulletinsAsync(versionString);
return this.Ok(viewModel);
}
catch (HttpException)
{
return this.InternalServerError(new Exception("The update service is currently not available."));
throw;
}
}
}
}
5 changes: 5 additions & 0 deletions Module.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
Expand All @@ -55,6 +56,7 @@
<Compile Include="Common\Globals.cs" />
<Compile Include="Common\Extensions\IQueryableExtensions.cs" />
<Compile Include="Controllers\LocalizationController.cs" />
<Compile Include="Controllers\SecurityController.cs" />
<Compile Include="DTO\GetItemsPageDTO.cs" />
<Compile Include="Controllers\ValidateModelAttribute.cs" />
<Compile Include="Data\Entities\BaseEntity.cs" />
Expand All @@ -72,15 +74,18 @@
<Compile Include="Controllers\ModuleExceptionFilterAttribute.cs" />
<Compile Include="Controllers\ServiceRouteMapper.cs" />
<Compile Include="Services\ILoggingService.cs" />
<Compile Include="Services\ISecurityService.cs" />
<Compile Include="Services\LoggingService.cs" />
<Compile Include="Services\IItemService.cs" />
<Compile Include="Services\ILocalizationService.cs" />
<Compile Include="Services\ItemService.cs" />
<Compile Include="Services\LocalizationService.cs" />
<Compile Include="Services\SecurityService.cs" />
<Compile Include="Startup.cs" />
<Compile Include="ViewModels\ItemsPageViewModel.cs" />
<Compile Include="ViewModels\ItemViewModel.cs" />
<Compile Include="ViewModels\LocalizationViewModel.cs" />
<Compile Include="ViewModels\SecurityBulletinsViewModel.cs" />
<Resource Include=".gitignore" />
<Resource Include="resources\images\module-icon.png" />
<Resource Include="resources\views\view.html" />
Expand Down
21 changes: 21 additions & 0 deletions Services/ISecurityService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// MIT License
// Copyright DNN Community

using Dnn.Modules.SecurityCenter.ViewModels;
using System.Threading.Tasks;

namespace Dnn.Modules.SecurityCenter.Services
{
/// <summary>
/// Provides access to the DNN security service at dnnplatform.io.
/// </summary>
public interface ISecurityService
{
/// <summary>
/// Gets a list of all security bulletins that apply for a given version.
/// </summary>
/// <param name="versionString">A string representation of a DNN version in the format 090202 for v9.2.2.</param>
/// <returns><see cref="SecurityBulletinsViewModel"/>.</returns>
Task<SecurityBulletinsViewModel> GetAllSecurityBulletinsAsync(string versionString);
}
}
53 changes: 53 additions & 0 deletions Services/SecurityService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// MIT License
// Copyright DNN Community

using Dnn.Modules.SecurityCenter.ViewModels;
using DotNetNuke.Common.Utilities;
using System;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Threading.Tasks;
using System.Xml;

namespace Dnn.Modules.SecurityCenter.Services
{
/// <summary>
/// Provides access to the DNN security service at dnnplatform.io.
/// </summary>
internal class SecurityService : ISecurityService
{
/// <inheritdoc/>
public async Task<SecurityBulletinsViewModel> GetAllSecurityBulletinsAsync(string versionString)
{
return await Task.Run(() =>
{
var cacheKey = "Dnn.Security_SecurityBelletinsViewModel";
var cached = DataCache.GetCache<SecurityBulletinsViewModel>(cacheKey);
if (cached is null)
{
XmlReader reader = XmlReader.Create($"https://dnnplatform.io/security.aspx?type=Framework&name=DNNCorp.CE&version={versionString}");
var feed = SyndicationFeed.Load(reader);
var viewModel = new SecurityBulletinsViewModel
{
Bulletins = feed.Items.Select(item => new SecurityBulletinsViewModel.Bulletin
{
Description = item.Summary.Text,
Link = item.Links.FirstOrDefault().Uri.ToString(),
PublicationDateUtc = item.PublishDate.UtcDateTime,
Title = item.Title.Text,
}),
Description = feed.Description.Text,
Link = feed.Links.FirstOrDefault().Uri.ToString(),
Title = feed.Title.Text,
};
DataCache.SetCache(cacheKey, viewModel, DateTime.Now.AddHours(1));
return viewModel;
}
return cached;
});
}
}
}
1 change: 1 addition & 0 deletions Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddScoped<IItemService>(provider => new ItemService(provider.GetService<IRepository<Item>>()));
services.AddScoped<ILoggingService, LoggingService>();
services.AddScoped<ILocalizationService, LocalizationService>();
services.AddSingleton<ISecurityService, SecurityService>();
}
}
}
60 changes: 60 additions & 0 deletions ViewModels/SecurityBulletinsViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// MIT License
// Copyright DNN Community

using System;
using System.Collections.Generic;

namespace Dnn.Modules.SecurityCenter.ViewModels
{
/// <summary>
/// A viewmodel that represents DNN Security Bulletins.
/// </summary>
public class SecurityBulletinsViewModel
{
/// <summary>
/// Gets or sets the title of the RSS feed.
/// </summary>
public string Title { get; set; }

/// <summary>
/// Gets or sets the url to download DNN Platform.
/// </summary>
public string Link { get; set; }

/// <summary>
/// Gets or sets the RSS feed description.
/// </summary>
public string Description { get; set; }

/// <summary>
/// Gets or sets the list of security bulletins.
/// </summary>
public IEnumerable<Bulletin> Bulletins { get; set; }

/// <summary>
/// Represents a single DNN Security Bulletin.
/// </summary>
public class Bulletin
{
/// <summary>
/// Gets or sets a link to the detailed security bulletin.
/// </summary>
public string Link { get; set; }

/// <summary>
/// Gets or sets the title of the bulletin.
/// </summary>
public string Title { get; set; }

/// <summary>
/// Gets or sets the short description of the bulletin.
/// </summary>
public string Description { get; set; }

/// <summary>
/// Gets or sets a string representing the date of announcement.
/// </summary>
public DateTime PublicationDateUtc { get; set; }
}
}
}

0 comments on commit 17782b8

Please sign in to comment.