identity: prevent users with disposable emails from signing up
while this is not a perfect way to prevent abuse of service, we do want to avoid getting spammed with fake accounts. Creating a valid email account is significantly more cumbersome than using a disposable email address. Currently the list of blacklisted domains is extracted from https://github.com/disposable/disposable and it is refreshed after every 24 hours.
This commit is contained in:
@@ -54,7 +54,7 @@ namespace Streetwriters.Identity.Controllers
|
|||||||
public async Task<IActionResult> Signup([FromForm] SignupForm form)
|
public async Task<IActionResult> Signup([FromForm] SignupForm form)
|
||||||
{
|
{
|
||||||
var client = Clients.FindClientById(form.ClientId);
|
var client = Clients.FindClientById(form.ClientId);
|
||||||
if (client == null) return BadRequest("Invalid client_id.");
|
if (client == null) return BadRequest(new string[] { "Invalid client id." });
|
||||||
|
|
||||||
await AddClientRoleAsync(client.Id);
|
await AddClientRoleAsync(client.Id);
|
||||||
|
|
||||||
@@ -62,6 +62,8 @@ namespace Streetwriters.Identity.Controllers
|
|||||||
form.Email = form.Email.ToLowerInvariant();
|
form.Email = form.Email.ToLowerInvariant();
|
||||||
form.Username = form.Username?.ToLowerInvariant();
|
form.Username = form.Username?.ToLowerInvariant();
|
||||||
|
|
||||||
|
if (!await EmailAddressValidator.IsEmailAddressValidAsync(form.Email)) return BadRequest(new string[] { "Invalid email address." });
|
||||||
|
|
||||||
var result = await UserManager.CreateAsync(new User
|
var result = await UserManager.CreateAsync(new User
|
||||||
{
|
{
|
||||||
Email = form.Email,
|
Email = form.Email,
|
||||||
@@ -85,7 +87,7 @@ namespace Streetwriters.Identity.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return BadRequest(new string[] { "Email is invalid or already taken." });
|
return BadRequest(new string[] { "Invalid email address." });
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(new
|
return Ok(new
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Streetwriters.Common;
|
||||||
|
|
||||||
|
namespace Streetwriters.Identity.Services
|
||||||
|
{
|
||||||
|
public class EmailAddressValidator
|
||||||
|
{
|
||||||
|
private static DateTimeOffset LAST_FETCH_TIME = DateTimeOffset.MinValue;
|
||||||
|
private static HashSet<string> BLACKLISTED_DOMAINS = new HashSet<string>();
|
||||||
|
|
||||||
|
public static async Task<bool> IsEmailAddressValidAsync(string email)
|
||||||
|
{
|
||||||
|
var domain = email.ToLowerInvariant().Split("@")[1];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (LAST_FETCH_TIME.AddDays(1) < DateTimeOffset.UtcNow)
|
||||||
|
{
|
||||||
|
var httpClient = new HttpClient();
|
||||||
|
var domainsList = await httpClient.GetStringAsync("https://disposable.github.io/disposable-email-domains/domains.txt");
|
||||||
|
BLACKLISTED_DOMAINS = new HashSet<string>(domainsList.Split('\n'));
|
||||||
|
LAST_FETCH_TIME = DateTimeOffset.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !BLACKLISTED_DOMAINS.Contains(domain);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await Slogger<EmailAddressValidator>.Error("IsEmailAddressValidAsync", ex.ToString());
|
||||||
|
return BLACKLISTED_DOMAINS.Count > 0 ? !BLACKLISTED_DOMAINS.Contains(domain) : true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user