Skip to content

Commit

Permalink
Bug 7314: Input Validation Enhancement API-Email Parameter Manipulati…
Browse files Browse the repository at this point in the history
…on - changes done (#322)
  • Loading branch information
saranyadevi-bc authored Mar 22, 2024
1 parent bc41e9a commit e47ccfb
Showing 1 changed file with 171 additions and 146 deletions.
317 changes: 171 additions & 146 deletions Ccs.Ppg.NotificationService/Services/EmailProviderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,156 +10,181 @@

namespace Ccs.Ppg.NotificationService.Services
{
public class EmailProviderService : IEmailProviderService
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly IWrapperConfigurationService _wrapperConfigurationService;
private readonly ApplicationConfigurationInfo _applicationConfigurationInfo;
public class EmailProviderService : IEmailProviderService
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly IWrapperConfigurationService _wrapperConfigurationService;
private readonly ApplicationConfigurationInfo _applicationConfigurationInfo;

public EmailProviderService(IHttpClientFactory httpClientFactory, IWrapperConfigurationService wrapperConfigurationService,
ApplicationConfigurationInfo applicationConfigurationInfo)
{
_httpClientFactory = httpClientFactory;
_wrapperConfigurationService = wrapperConfigurationService;
_applicationConfigurationInfo = applicationConfigurationInfo;
}
public async Task SendEmailAsync(EmailInfo emailInfo)
{
try
{
//Adding log for testing purpose
Console.WriteLine("EmailInfo Properties:");
Console.WriteLine($"To: {emailInfo.To}");
Console.WriteLine($"TemplateId: {emailInfo.TemplateId}");
if (emailInfo.BodyContent != null)
{
Console.WriteLine("BodyContent:");
foreach (var kvp in emailInfo.BodyContent)
{
Console.WriteLine($" {kvp.Key}: {kvp.Value}");
}
}
else
{
Console.WriteLine("BodyContent: (null)");
}
public EmailProviderService(IHttpClientFactory httpClientFactory, IWrapperConfigurationService wrapperConfigurationService,
ApplicationConfigurationInfo applicationConfigurationInfo)
{
_httpClientFactory = httpClientFactory;
_wrapperConfigurationService = wrapperConfigurationService;
_applicationConfigurationInfo = applicationConfigurationInfo;
}
public async Task SendEmailAsync(EmailInfo emailInfo)
{
try
{
//Adding log for testing purpose
Console.WriteLine("EmailInfo Properties:");
Console.WriteLine($"To: {emailInfo.To}");
Console.WriteLine($"TemplateId: {emailInfo.TemplateId}");
if (emailInfo.BodyContent != null)
{
Console.WriteLine("BodyContent:");
foreach (var kvp in emailInfo.BodyContent)
{
Console.WriteLine($" {kvp.Key}: {kvp.Value}");
}
}
else
{
Console.WriteLine("BodyContent: (null)");
}

var bodyContent = new Dictionary<string, dynamic>();
emailInfo.BodyContent.ToList().ForEach(pair => bodyContent.Add(pair.Key, pair.Value));
bool isValidationEnbled = _applicationConfigurationInfo.NotificationValidationConfigurations.EnableValidation;
if (isValidationEnbled && !await ValidateEmailMessage(bodyContent))
{
Console.WriteLine(ErrorConstant.ErrorInvalidDetails);
throw new CcsSsoException(ErrorConstant.ErrorInvalidDetails);
}
var bodyContent = new Dictionary<string, dynamic>();
emailInfo.BodyContent.ToList().ForEach(pair => bodyContent.Add(pair.Key, pair.Value));
bool isValidationEnbled = _applicationConfigurationInfo.NotificationValidationConfigurations.EnableValidation;
//Validate Email Headers
if (isValidationEnbled && !ValidateEmailHeaders(emailInfo))
{
Console.WriteLine(ErrorConstant.ErrorInvalidDetails);
throw new CcsSsoException(ErrorConstant.ErrorInvalidDetails);
}
if (isValidationEnbled && !await ValidateEmailMessage(bodyContent))
{
Console.WriteLine(ErrorConstant.ErrorInvalidDetails);
throw new CcsSsoException(ErrorConstant.ErrorInvalidDetails);
}

var apiKey = _applicationConfigurationInfo.EmailSettings.ApiKey;
var client = _httpClientFactory.CreateClient();
var httpClientWithProxy = new HttpClientWrapper(client);
var notificationClient = new NotificationClient(httpClientWithProxy, apiKey);

EmailNotificationResponse response = await notificationClient.SendEmailAsync(emailInfo.To, emailInfo.TemplateId, bodyContent);
}
catch (CcsSsoException ex)
{
throw ex;
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw new Exception(ex.Message);
}
}
var apiKey = _applicationConfigurationInfo.EmailSettings.ApiKey;
var client = _httpClientFactory.CreateClient();
var httpClientWithProxy = new HttpClientWrapper(client);
var notificationClient = new NotificationClient(httpClientWithProxy, apiKey);

public async Task<bool> ValidateEmailMessage(Dictionary<string, dynamic> msgBody)
{
foreach (var msg in msgBody)
{
switch (msg.Key.ToLower())
{
case "orgname":
{
var orgNameLength = _applicationConfigurationInfo.NotificationValidationConfigurations.OrgNameLegnth;
if (!string.IsNullOrEmpty(msg.Value) && msg.Value.Length > orgNameLength)
return false;
break;
}
case "emailaddress":
case "emailid":
{
var emailRegex = _applicationConfigurationInfo.NotificationValidationConfigurations.EmailRegex;
Regex re = new Regex(emailRegex);
if (!string.IsNullOrEmpty(msg.Value) && !re.IsMatch(msg.Value))
return (false);
break;
}
case "firstname":
{
var firstNameLength = _applicationConfigurationInfo.NotificationValidationConfigurations.FirstNameLength;
if (!string.IsNullOrEmpty(msg.Value) && msg.Value.Length > firstNameLength)
return false;
break;
}
case "lastname":
{
var lastNameLength = _applicationConfigurationInfo.NotificationValidationConfigurations.LastNameLength;
if (!string.IsNullOrEmpty(msg.Value) && msg.Value.Length > lastNameLength)
return false;
break;
}
case "link":
case "mfaresetlink":
case "federatedlogin":
{
var linkRegex = _applicationConfigurationInfo.NotificationValidationConfigurations.LinkRegex;
Regex re = new Regex(linkRegex);
if (!string.IsNullOrEmpty(msg.Value) && !re.IsMatch(msg.Value))
return (false);
break;
}
case "servicenames":
{
if (!string.IsNullOrEmpty(msg.Value))
{
var selectedServices = msg.Value.Split(',');
List<string> delegatedServices = new List<string>();
foreach (var service in selectedServices)
{
delegatedServices.Add(service.Trim());
}
var services = await _wrapperConfigurationService.GetServices();
var result = delegatedServices.Except(services).ToList();
if (result.Count > 0) return false;
}
break;
}
case "sigininproviders":
{
if (!string.IsNullOrEmpty(msg.Value))
{
//validate against list of signin providers
var signinProviders = _applicationConfigurationInfo.NotificationValidationConfigurations.SignInProviders;
var selectedProviders = msg.Value.Split(',');
List<string> providers = new List<string>();
providers.AddRange(selectedProviders);
var result = providers.Except(signinProviders).ToList();
if (result.Count > 0) return false;
}
break;
}
case "ccsmsg":
{
string ccsMsg = _applicationConfigurationInfo.NotificationValidationConfigurations.CcsMsg;
if (!string.IsNullOrEmpty(msg.Value) && msg.Value != ccsMsg)
return false;
break;
}
EmailNotificationResponse response = await notificationClient.SendEmailAsync(emailInfo.To, emailInfo.TemplateId, bodyContent);
}
catch (CcsSsoException ex)
{
throw ex;
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw new Exception(ex.Message);
}
}

}
}
return true;
}
}
}
private bool ValidateEmailHeaders(EmailInfo emailInfo)
{
if (!string.IsNullOrEmpty(emailInfo.To))
{
var emailRegex = _applicationConfigurationInfo.NotificationValidationConfigurations.EmailRegex;
Regex re = new Regex(emailRegex);
if (!re.IsMatch(emailInfo.To))
return false;
}
if (!string.IsNullOrEmpty(emailInfo.TemplateId))
{
Guid result;
bool isValid = Guid.TryParse(emailInfo.TemplateId, out result);
if (!isValid) return false;
}
return true;
}

public async Task<bool> ValidateEmailMessage(Dictionary<string, dynamic> msgBody)
{
foreach (var msg in msgBody)
{
switch (msg.Key.ToLower())
{
case "orgname":
{
var orgNameLength = _applicationConfigurationInfo.NotificationValidationConfigurations.OrgNameLegnth;
if (!string.IsNullOrEmpty(msg.Value) && msg.Value.Length > orgNameLength)
return false;
break;
}
case "emailaddress":
case "emailid":
case "email":
{
var emailRegex = _applicationConfigurationInfo.NotificationValidationConfigurations.EmailRegex;
Regex re = new Regex(emailRegex);
if (!string.IsNullOrEmpty(msg.Value) && !re.IsMatch(msg.Value))
return (false);
break;
}
case "firstname":
{
var firstNameLength = _applicationConfigurationInfo.NotificationValidationConfigurations.FirstNameLength;
if (!string.IsNullOrEmpty(msg.Value) && msg.Value.Length > firstNameLength)
return false;
break;
}
case "lastname":
{
var lastNameLength = _applicationConfigurationInfo.NotificationValidationConfigurations.LastNameLength;
if (!string.IsNullOrEmpty(msg.Value) && msg.Value.Length > lastNameLength)
return false;
break;
}
case "link":
case "mfaresetlink":
case "federatedlogin":
case "conclaveloginlink":
{
var linkRegex = _applicationConfigurationInfo.NotificationValidationConfigurations.LinkRegex;
Regex re = new Regex(linkRegex);
if (!string.IsNullOrEmpty(msg.Value) && !re.IsMatch(msg.Value))
return (false);
break;
}
case "servicenames":
case "servicename":
{
if (!string.IsNullOrEmpty(msg.Value))
{
var selectedServices = msg.Value.Split(',');
List<string> delegatedServices = new List<string>();
foreach (var service in selectedServices)
{
delegatedServices.Add(service.Trim());
}
var services = await _wrapperConfigurationService.GetServices();
var result = delegatedServices.Except(services).ToList();
if (result.Count > 0) return false;
}
break;
}
case "sigininproviders":
{
if (!string.IsNullOrEmpty(msg.Value))
{
//validate against list of signin providers
var signinProviders = _applicationConfigurationInfo.NotificationValidationConfigurations.SignInProviders;
var selectedProviders = msg.Value.Split(',');
List<string> providers = new List<string>();
providers.AddRange(selectedProviders);
var result = providers.Except(signinProviders).ToList();
if (result.Count > 0) return false;
}
break;
}
case "ccsmsg":
{
string ccsMsg = _applicationConfigurationInfo.NotificationValidationConfigurations.CcsMsg;
if (!string.IsNullOrEmpty(msg.Value) && msg.Value != ccsMsg)
return false;
break;
}

}
}
return true;
}
}
}

0 comments on commit e47ccfb

Please sign in to comment.