Skip to content

Commit

Permalink
Merge pull request #144 from FS-FAST-TRACK/feature/system-modules
Browse files Browse the repository at this point in the history
Feature/System Modules
  • Loading branch information
jaymar921 authored Jan 16, 2024
2 parents 80f6c89 + ac7d025 commit 1d4aa36
Show file tree
Hide file tree
Showing 27 changed files with 1,113 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public async Task<IActionResult> Logout()
[Authorize]
[HttpGet]
[Route("info")]
public IActionResult GetCookieInfo()
public async Task<IActionResult> GetCookieInfo()
{
// grab the claims identity
var tokenClaim = User.Claims.ToList().FirstOrDefault(e => e.Type == "token");
Expand All @@ -69,7 +69,11 @@ public IActionResult GetCookieInfo()
// get the AuthStore based on token
var authStore = _authenticationServices.Validate(token);

if (authStore == null) return NotFound(new { Message = "No information found based on the token provided" });
if (authStore == null)
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return NotFound(new { Message = "No information found based on the token provided" });
}

return Ok(new { Message = "Info", authStore });
}
Expand Down
5 changes: 5 additions & 0 deletions WebApp/backend/QuizMaster.API.Gatewway/AutoMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Newtonsoft.Json;
using QuizMaster.API.Account.Models;
using QuizMaster.API.Account.Proto;
using QuizMaster.API.Gateway.Models.System;
using QuizMaster.API.Quiz.Models;
using QuizMaster.API.Quiz.Protos;
using QuizMaster.API.Quiz.SeedData;
Expand All @@ -26,6 +27,10 @@ public AutoMapper()
CreateMap<Question, QuestionDto>().ReverseMap();
CreateMap<Question, QuestionDto>();
CreateMap<QuestionCategory, CategoryDto>().ReverseMap();
CreateMap<SubmitContactModel, ContactReaching>().ReverseMap();
CreateMap<AboutModel, SystemAbout>().ReverseMap();
CreateMap<ContactModel, SystemContact>().ReverseMap();
CreateMap<ReviewModel, Reviews>().ReverseMap();
// CreateMap<QuestionCreateDto, Question>()
//.ForMember(destination => destination.QAnswer, act => act.MapFrom(src =>
//src.QTypeId == QuestionTypes.MultipleChoiceSeedData.Id
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using QuizMaster.API.Authentication.Configuration;

namespace QuizMaster.API.Gateway.Configuration
{
public class ApplicationSettings: AppSettings
{
public string SMTP_EMAIL { get; set; }
public string SMTP_PASSWORD { get; set; }
}
}
201 changes: 201 additions & 0 deletions WebApp/backend/QuizMaster.API.Gatewway/Controllers/SystemController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
using Grpc.Net.Client;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using QuizMaster.API.Authentication.Models;
using QuizMaster.API.Authentication.Proto;
using QuizMaster.API.Gateway.Attributes;
using QuizMaster.API.Gateway.Configuration;
using QuizMaster.API.Gateway.Helper;
using QuizMaster.API.Gateway.Helper.Email;
using QuizMaster.API.Gateway.Models.System;
using QuizMaster.API.Gateway.Services.Email;
using QuizMaster.API.Gateway.Services.SystemService;
using QuizMaster.API.Gatewway.Controllers;

namespace QuizMaster.API.Gateway.Controllers
{
[Route("gateway/api/[controller]")]
public class SystemController : Controller
{
private readonly SystemRepository systemRepository;
private readonly EmailService emailService;
private readonly GrpcChannel _authChannel;
private readonly AuthService.AuthServiceClient _authChannelClient;
private readonly ILogger<SystemController> logger;

public SystemController(SystemRepository systemRepository, EmailService emailService, IOptions<GrpcServerConfiguration> options, ILogger<SystemController> logger)
{
this.systemRepository = systemRepository;
this.emailService = emailService;

var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
_authChannel = GrpcChannel.ForAddress(options.Value.Authentication_Service, new GrpcChannelOptions { HttpHandler = handler });
_authChannelClient = new AuthService.AuthServiceClient(_authChannel);
this.logger = logger;
}

// Get System About
[HttpGet("information")]
public async Task<IActionResult> GetSystemInformationAsync()
{
return Ok(new { Status = "Success", Message = "Retrieved System Information", Data = await systemRepository.GetSystemAboutAsync() });
}

// Update System About
[QuizMasterAdminAuthorization]
[HttpPost("information")]
public async Task<IActionResult> UpdateSystemInformationAsync([FromBody] AboutModel model)
{
if(!ModelState.IsValid)
{
return BadRequest(ModelState);
}
await systemRepository.EditSystemAboutAsync(model);
return Ok(new { Status = "Success", Message = "Saved", Data = await systemRepository.GetSystemAboutAsync() });
}

// Get System Contact
[HttpGet("contact_information")]
public async Task<IActionResult> GetContactInformationAsync()
{
return Ok(new { Status = "Success", Message = "Retrieved Contact Information", Data = await systemRepository.GetContactInformationAsync() });
}

// Update System Contact
[QuizMasterAdminAuthorization]
[HttpPost("contact_information")]
public async Task<IActionResult> UpdateContactInformation([FromBody] ContactModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
await systemRepository.EditSystemContactInformationAsync(model);
return Ok(new { Status = "Success", Message = "Saved", Data = await systemRepository.GetContactInformationAsync() });
}

// Submit Contact
[HttpPost("reachOut")]
public async Task<IActionResult> ReachOutAsync([FromBody] SubmitContactModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
await systemRepository.SaveReachingContactAsync(model);

#region Send Email
// I'll run this in a thread
var contactInformation = await systemRepository.GetContactInformationAsync();
Task.Run(async () =>
{
// Lets try sending the email the the user authenticated, otherwise we'll send it to the email specified in the model
var token = this.GetToken();
var email = model.Email;
if (!string.IsNullOrEmpty(token))
{
var authStore = await GetAuthStoreInfo(token);
if (authStore != null) email = authStore.UserData.Email;
}

// Create the templates and send the corresponding emails
var clientEmail = EmailDefaults.SUBMIT_CONTACT_CLIENT(email);
emailService.SendEmail(clientEmail);

logger.LogInformation("Sending Email Copy to: " + contactInformation.Email);
var registeredAdminContactCopy = EmailDefaults.SUBMIT_CONTACT_ADMIN(contactInformation.Email, model.Firstname + " " + model.Lastname, model.Message);
emailService.SendEmail(registeredAdminContactCopy);
emailService.SendEmailToAdmin(registeredAdminContactCopy);
});
#endregion



return Ok(new { Status = "Success", Message = "Successfully submitted a contact request." });
}

// Get All Submitted Contact
[QuizMasterAdminAuthorization]
[HttpGet("reachOut")]
public async Task<IActionResult> GetAllReachOutAsync()
{
return Ok(new { Status = "Success", Message = "Retrieved Contacting Users", Data = await systemRepository.GetContactReachingsAsync() });
}

// Submit Review
[HttpPost("review")]
public async Task<IActionResult> SubmitReviewAsync([FromBody] ReviewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
await systemRepository.SaveReviewsAsync(model);

#region Send Email
var contactInformation = await systemRepository.GetContactInformationAsync();
// I'll run this in a separate thread
Task.Run(async () =>
{
var token = this.GetToken();
if (!string.IsNullOrEmpty(token))
{
var AuthStore = await GetAuthStoreInfo(token);

if (AuthStore != null)
{
var clientEmail = EmailDefaults.SUBMIT_REVIEW_CLIENT(AuthStore.UserData.Email, model.Comment, model.StarRating);
emailService.SendEmail(clientEmail);

}
}
/*
*
* This code right here will send an email to the SMTP account, which I commented it out first since we priority on
* the admin that will receive the email must be the email specified in the contact us
var adminEmailCopy = EmailDefaults.SUBMIT_REVIEW_ADMIN("", model.Comment, model.StarRating);
emailService.SendEmailToAdmin(adminEmailCopy);
*/
var registeredAdminContactCopy = EmailDefaults.SUBMIT_REVIEW_ADMIN(contactInformation.Email, model.Comment, model.StarRating);
logger.LogInformation("Sending Email Copy to: " + contactInformation.Email);
emailService.SendEmail(registeredAdminContactCopy);
emailService.SendEmailToAdmin(registeredAdminContactCopy);
});
#endregion

return Ok(new { Status = "Success", Message = "Successfully submitted a system review." });
}

// Get All Submitted Review
[QuizMasterAdminAuthorization]
[HttpGet("review")]
public async Task<IActionResult> GetAllReviewsAsync()
{
return Ok(new { Status = "Success", Message = "Retrieved System Reviews", Data = await systemRepository.GetReviewsAsync() });
}

[HttpGet("review/client")]
public async Task<IActionResult> GetAllReviewsClientCopyAsync()
{
var data = await systemRepository.GetReviewsAsync();
data = data.Where(r => r.StarRating >= 4).ToList();
return Ok(new { Status = "Success", Message = "Retrieved System Reviews", Data = data });
}



private async Task<AuthStore> GetAuthStoreInfo(string token)
{
var requestValidation = new ValidationRequest()
{
Token = token
};

var authStore = await _authChannelClient.ValidateAuthenticationAsync(requestValidation);

return !string.IsNullOrEmpty(authStore?.AuthStore) ? JsonConvert.DeserializeObject<AuthStore>(authStore.AuthStore) : null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace QuizMaster.API.Gateway.Helper.Email
{
public class EmailTemplate
{
public string Body { get; set; } = string.Empty;
public string ToEmail { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;
}

public class EmailDefaults
{
public static EmailTemplate SUBMIT_REVIEW_ADMIN(string ToEmail, string Message, int Rating)
{
return new EmailTemplate { Body = $"Someone reviewed: {Message}, Rating: {Rating}/5", ToEmail = ToEmail, Subject = "[QuizMaster] System Review" };
}

public static EmailTemplate SUBMIT_REVIEW_CLIENT(string ToEmail, string Message, int Rating)
{
return new EmailTemplate { Body = $"You reviewed: {Message}, Rating: {Rating}/5", ToEmail = ToEmail, Subject = "[QuizMaster] System Review" };
}

public static EmailTemplate SUBMIT_CONTACT_ADMIN(string ToEmail, string Name, string Message)
{
return new EmailTemplate { Body = $"Hello admin, this {Name} would like to reach us out with a following message: {Message}", ToEmail = ToEmail, Subject = "[QuizMaster] Someone's reaching us" };
}

public static EmailTemplate SUBMIT_CONTACT_CLIENT(string ToEmail)
{
return new EmailTemplate { Body = $"Thank you for reaching us, we will reach you out soonest.", ToEmail = ToEmail, Subject = "[QuizMaster] Thanks for reaching us" };
}
}
}
Loading

0 comments on commit 1d4aa36

Please sign in to comment.