Skip to content

Commit

Permalink
* Google authentication is now made optional if ClientId in configura…
Browse files Browse the repository at this point in the history
…tion is set to a null or empty value.

* Added a search function that combines all events.
  • Loading branch information
n.bitounis committed Jun 10, 2020
1 parent 60c0ce5 commit e703ff3
Show file tree
Hide file tree
Showing 15 changed files with 361 additions and 34 deletions.
82 changes: 82 additions & 0 deletions Projects/SesNotifications.App/Pages/FindOperational.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
@page
@model SesNotifications.App.Pages.FindOperationalModel
@{
ViewData["Title"] = "Operational view";
}

<!DOCTYPE html>

<h1>@ViewData["Title"]</h1>
<h4>Search for events by date range and optional recipient.</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label>Starting date</label>
<input asp-for="Input.Start" class="form-control" />
<span asp-validation-for="Input.Start" class="text-danger"></span>

<label>Ending date</label>
<input asp-for="Input.End" class="form-control" />
<span asp-validation-for="Input.End" class="text-danger"></span>

<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>

<button type="submit" class="btn btn-primary">Submit</button>
</form>
<br />

<table class="table">
<tr>
<th>Notification ID</th>
<th>Notification Type</th>
<th>Source</th>
<th>Recipients</th>
<th>Sent at</th>
<th>Created at</th>
<th>Detail 1</th>
<th>Detail 2</th>
<th>Raw model</th>
<th>Raw message</th>
</tr>
@foreach (var record in Model.Operational)
{
<tr>
<td>@record.NotificationId</td>
<td>@record.NotificationType</td>
<td>@record.Source</td>
<td>@record.Recipients</td>
<td>@record.SentAt.ToString("yyyy-MM-dd HH:mm:ssZ")</td>
<td>@record.CreatedAt.ToString("yyyy-MM-dd HH:mm:ssZ")</td>
<td>@record.Detail1</td>
<td>@record.Detail2</td>
<td><a target="_blank" href="@Url.Action("FindRawById", "Searches", new {id = record.NotificationId})">RAW (MODEL)</a></td>
<td><a target="_blank" href="@string.Concat(Url.Action("FindMessageById", "Searches", new {id = record.NotificationId}), "/text")">RAW (MESSAGE)</a></td>
</tr>
}
</table>

<div>
@if (Model.Operational.Count > 0)
{
<ul class="pagination">
@for (var i = 1; i <= (int) ViewData["NumberOfPages"]; i++)
{
<li class="page-item @(i == (int) ViewData["PageNumber"] ? "active" : "")">
<a asp-page="FindOperational"
asp-route-currentpage="@i"
asp-route-start="@ViewData["Start"]"
asp-route-end ="@ViewData["End"]"
class="page-link">@i</a>
</li>
}
</ul>
}
</div>
</div>
</div>
63 changes: 63 additions & 0 deletions Projects/SesNotifications.App/Pages/FindOperational.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using SesNotifications.App.Helpers;
using SesNotifications.App.Services.Interfaces;
using SesNotifications.DataAccess.Entities;

namespace SesNotifications.App.Pages
{
public class FindOperationalModel : PageBase
{
[BindProperty]
public BaseEmailInputModel Input { get; set; }

public IList<SesOperational> Operational { get; set; } = new List<SesOperational>();

private readonly ISearchService _searchService;

public FindOperationalModel(ISearchService searchService)
{
_searchService = searchService;
}

protected override void Search()
{
var countOfResults = _searchService.FindOperationalCount(Input.Email, Input.Start.StartOfDay(), Input.End.EndOfDay());

Operational = _searchService.FindOperational(Input.Email, Input.Start.StartOfDay(), Input.End.EndOfDay(), null, 0, PageSize);

if (Operational.Count > 0)
{
FirstId = (int)Operational[0].NotificationId;
}

PageNumber = 1;
NumberOfPages = countOfResults / PageSize + 1;
Start = Input.Start;
End = Input.End;
Email = Input.Email;
}

protected override void GetPage()
{
Operational = _searchService.FindOperational(
Email,
Start.StartOfDay(),
End.EndOfDay(),
FirstId,
PageNumber - 1,
PageSize);
}

protected override void CreateModel()
{
Input = new BaseEmailInputModel();
}

protected override void SaveState()
{
SaveState(Input);
Input.Email = Email;
}
}
}
1 change: 1 addition & 0 deletions Projects/SesNotifications.App/Pages/Shared/_Layout.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
Queries
</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="~/FindOperational">Operational view</a>
<a class="dropdown-item" href="~/FindDeliveries">Deliveries</a>
<a class="dropdown-item" href="~/FindComplaints">Complaints</a>
<a class="dropdown-item" href="~/FindBounces">Bounces</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public interface ISearchService
int FindDeliveryEventsCount(string email, DateTime start, DateTime end);
int FindBounceEventsCount(string email, DateTime start, DateTime end);
int FindComplaintEventCount(string email, DateTime start, DateTime end);
int FindOperationalCount(string email, DateTime start, DateTime end);
IList<SesDelivery> FindDeliveries(string email, DateTime start, DateTime end, long? firstId, int page, int pageSize);
IList<SesComplaint> FindComplaints(string email, DateTime start, DateTime end, long? firstId, int page, int pageSize);
IList<SesBounce> FindBounces(string email, DateTime start, DateTime end, long? firstId, int page, int pageSize);
Expand All @@ -35,6 +36,7 @@ public interface ISearchService
IList<SesDeliveryEvent> FindDeliveryEvents(string email, DateTime start, DateTime end, long? firstId, int page, int pageSize);
IList<SesBounceEvent> FindBounceEvents(string email, DateTime start, DateTime end, long? firstId, int page, int pageSize);
IList<SesComplaintEvent> FindComplaintEvents(string email, DateTime start, DateTime end, long? firstId, int page, int pageSize);
IList<SesOperational> FindOperational(string email, DateTime start, DateTime end, long? firstId, int page, int pageSize);
SesNotification FindRaw(long id);
}
}
15 changes: 14 additions & 1 deletion Projects/SesNotifications.App/Services/SearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class SearchService : ISearchService
private readonly ISesDeliveryEventsRepository _sesDeliveryEventsRepository;
private readonly ISesBounceEventsRepository _sesBounceEventsRepository;
private readonly ISesComplaintEventsRepository _sesComplaintEventsRepository;
private readonly ISesOperationalRepository _sesOperationalRepository;

public SearchService(INotificationsRepository notificationsRepository,
ISesBouncesRepository sesBouncesRepository,
Expand All @@ -31,7 +32,8 @@ public SearchService(INotificationsRepository notificationsRepository,
ISesSendEventsRepository sesSendEventsRepository,
ISesDeliveryEventsRepository sesDeliveryEventsRepository,
ISesBounceEventsRepository sesBounceEventsRepository,
ISesComplaintEventsRepository sesComplaintEventsRepository)
ISesComplaintEventsRepository sesComplaintEventsRepository,
ISesOperationalRepository sesOperationalRepository)
{
_notificationsRepository = notificationsRepository;
_sesBouncesRepository = sesBouncesRepository;
Expand All @@ -42,6 +44,7 @@ public SearchService(INotificationsRepository notificationsRepository,
_sesDeliveryEventsRepository = sesDeliveryEventsRepository;
_sesBounceEventsRepository = sesBounceEventsRepository;
_sesComplaintEventsRepository = sesComplaintEventsRepository;
_sesOperationalRepository = sesOperationalRepository;
}

public IList<SesDelivery> FindDeliveries(string email, DateTime start, DateTime end)
Expand Down Expand Up @@ -155,6 +158,11 @@ public int FindComplaintEventCount(string email, DateTime start, DateTime end)
return _sesComplaintEventsRepository.Count(email, start, end);
}

public int FindOperationalCount(string email, DateTime start, DateTime end)
{
return _sesOperationalRepository.Count(email, start, end);
}

public IList<SesDelivery> FindDeliveries(string email, DateTime start, DateTime end, long? firstId, int page,
int pageSize)
{
Expand Down Expand Up @@ -202,6 +210,11 @@ public IList<SesComplaintEvent> FindComplaintEvents(string email, DateTime start
return _sesComplaintEventsRepository.FindById(email, start, end, firstId, page, pageSize);
}

public IList<SesOperational> FindOperational(string email, DateTime start, DateTime end, long? firstId, int page, int pageSize)
{
return _sesOperationalRepository.FindById(email, start, end, firstId, page, pageSize);
}

public SesNotification FindRaw(long id)
{
return _notificationsRepository.FindById(id);
Expand Down
67 changes: 43 additions & 24 deletions Projects/SesNotifications.App/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,46 @@ public Startup(IConfiguration configuration)

public void ConfigureServices(IServiceCollection services)
{

services.AddNHibernate(Configuration.GetConnectionString("Database"));

services.AddScopedRepositories();
ConfigureScopedRepositories(services);

var oAuth = Configuration.GetSection("GoogleOAuth").Get<GoogleOAuth>();

services
.AddAuthentication(o =>
{
o.DefaultScheme = Constants.ApplicationScheme;
o.DefaultSignInScheme = Constants.SignInScheme;
})
.AddCookie(Constants.ApplicationScheme)
.AddCookie(Constants.SignInScheme)
.AddGoogle(o =>
{
o.ClientId = oAuth.ClientId;
o.ClientSecret = oAuth.ClientSecret;
});
var oAuth = GetGoogleOAuthConfig();

if (!string.IsNullOrEmpty(oAuth.ClientId))
{

services
.AddAuthentication(o =>
{
o.DefaultScheme = Constants.ApplicationScheme;
o.DefaultSignInScheme = Constants.SignInScheme;
})
.AddCookie(Constants.ApplicationScheme)
.AddCookie(Constants.SignInScheme)
.AddGoogle(o =>
{
o.ClientId = oAuth.ClientId;
o.ClientSecret = oAuth.ClientSecret;
});
}

services.AddMvcWithUnitOfWork(0); //Note: this won't work with Razor pages.

services.AddRazorPages()
.AddRazorPagesOptions(o =>
{
o.Conventions.AuthorizeFolder("/");
o.Conventions.AllowAnonymousToPage("/Index");
});
if (!string.IsNullOrEmpty(oAuth.ClientId))
{
services.AddRazorPages()
.AddRazorPagesOptions(o =>
{
o.Conventions.AuthorizeFolder("/");
o.Conventions.AllowAnonymousToPage("/Index");
});
}
else
{
services.AddRazorPages();
}
}

public void ConfigureScopedRepositories(IServiceCollection services)
Expand All @@ -70,13 +80,17 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();
if (!string.IsNullOrEmpty(GetGoogleOAuthConfig().ClientId))
{
app.UseAuthentication();
app.UseAuthorization();
}

app.UseEndpoints(endpoints =>
{
Expand All @@ -87,5 +101,10 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}

private GoogleOAuth GetGoogleOAuthConfig()
{
return Configuration.GetSection("GoogleOAuth").Get<GoogleOAuth>();
}
}
}
4 changes: 2 additions & 2 deletions Projects/SesNotifications.App/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
}
},
"GoogleOAuth": {
"ClientId": "clientid",
"ClientSecret": "clientsecret"
"ClientId": "",
"ClientSecret": ""
}
}
4 changes: 2 additions & 2 deletions Projects/SesNotifications.App/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"AllowedHosts": "*",
"GoogleOAuth": {
"ClientId": "clientid",
"ClientSecret": "clientsecret"
"ClientId": "",
"ClientSecret": ""
}
}
16 changes: 16 additions & 0 deletions Projects/SesNotifications.DataAccess/Entities/SesOperational.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace SesNotifications.DataAccess.Entities
{
public class SesOperational
{
public virtual long NotificationId { get; set; }
public virtual string NotificationType { get; set; }
public virtual DateTime SentAt { get; set; }
public virtual string Source { get; set; }
public virtual DateTime CreatedAt { get; set; }
public virtual string Recipients { get; set; }
public virtual string Detail1 { get; set; }
public virtual string Detail2 { get; set; }
}
}
22 changes: 22 additions & 0 deletions Projects/SesNotifications.DataAccess/Mappings/SesOperationalMap.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using FluentNHibernate.Mapping;
using SesNotifications.DataAccess.Entities;

namespace SesNotifications.DataAccess.Mappings
{
public class SesOperationalMap : ClassMap<SesOperational>
{
public SesOperationalMap()
{
Table("ses_notifications.operational");
Id(x => x.NotificationId).Column("notification_id");
Map(x => x.NotificationType).Column("notification_type");
Map(x => x.Recipients).Column("recipients");
Map(x => x.CreatedAt).Column("created_at");
Map(x => x.SentAt).Column("sent_at");
Map(x => x.Source).Column("source");
Map(x => x.Detail1).Column("detail1");
Map(x => x.Detail2).Column("detail2");
ReadOnly();
}
}
}
Loading

0 comments on commit e703ff3

Please sign in to comment.