1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-05 21:18:13 -05:00

Refactor email attributes (#1458)

* Add StrictEmailAddress attribute

* Remove duplicate checks, use attributes instead

* Rename EmailAddressListAttribute
This commit is contained in:
Thomas Rittson 2021-07-16 08:01:51 +10:00 committed by GitHub
parent 752aa70924
commit 7abb053914
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 23 deletions

View File

@ -2,36 +2,24 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Bit.Core.Models.Table; using Bit.Core.Models.Table;
using Bit.Core.Utilities;
namespace Bit.Core.Models.Api.Public namespace Bit.Core.Models.Api.Public
{ {
public class MemberCreateRequestModel : MemberUpdateRequestModel, IValidatableObject public class MemberCreateRequestModel : MemberUpdateRequestModel
{ {
/// <summary> /// <summary>
/// The member's email address. /// The member's email address.
/// </summary> /// </summary>
/// <example>jsmith@example.com</example> /// <example>jsmith@example.com</example>
[Required] [Required]
[EmailAddress] [StringLength(256)]
[StrictEmailAddress]
public string Email { get; set; } public string Email { get; set; }
public override OrganizationUser ToOrganizationUser(OrganizationUser existingUser) public override OrganizationUser ToOrganizationUser(OrganizationUser existingUser)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Email.Contains(" ") || Email.Contains("<"))
{
yield return new ValidationResult($"Email is not valid.",
new string[] { nameof(Email) });
}
else if (Email.Length > 256)
{
yield return new ValidationResult($"Email is longer than 256 characters.",
new string[] { nameof(Email) });
}
}
} }
} }

View File

@ -1,12 +1,13 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Bit.Core.Utilities;
namespace Bit.Core.Models.Api namespace Bit.Core.Models.Api
{ {
public class EmailRequestModel public class EmailRequestModel
{ {
[Required] [Required]
[EmailAddress] [StrictEmailAddress]
[StringLength(256)] [StringLength(256)]
public string NewEmail { get; set; } public string NewEmail { get; set; }
[Required] [Required]

View File

@ -4,6 +4,7 @@ using System.ComponentModel.DataAnnotations;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.Business; using Bit.Core.Models.Business;
using Bit.Core.Models.Table; using Bit.Core.Models.Table;
using Bit.Core.Utilities;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Bit.Core.Models.Api namespace Bit.Core.Models.Api
@ -13,7 +14,7 @@ namespace Bit.Core.Models.Api
[StringLength(50)] [StringLength(50)]
public string Name { get; set; } public string Name { get; set; }
[Required] [Required]
[EmailAddress] [StrictEmailAddress]
[StringLength(256)] [StringLength(256)]
public string Email { get; set; } public string Email { get; set; }
[Required] [Required]

View File

@ -12,7 +12,7 @@ namespace Bit.Core.Models.Api
public class OrganizationUserInviteRequestModel public class OrganizationUserInviteRequestModel
{ {
[Required] [Required]
[EmailAddressList] [StrictEmailAddressList]
public IEnumerable<string> Emails { get; set; } public IEnumerable<string> Emails { get; set; }
[Required] [Required]
public Enums.OrganizationUserType? Type { get; set; } public Enums.OrganizationUserType? Type { get; set; }

View File

@ -11,7 +11,7 @@ namespace Bit.Core.Models.Api
public class ProviderUserInviteRequestModel public class ProviderUserInviteRequestModel
{ {
[Required] [Required]
[EmailAddressList] [StrictEmailAddressList]
public IEnumerable<string> Emails { get; set; } public IEnumerable<string> Emails { get; set; }
[Required] [Required]
public ProviderUserType? Type { get; set; } public ProviderUserType? Type { get; set; }

View File

@ -0,0 +1,30 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
namespace Bit.Core.Utilities
{
public class StrictEmailAddressAttribute : ValidationAttribute
{
public StrictEmailAddressAttribute()
: base("The {0} field is not a valid e-mail address.")
{}
public override bool IsValid(object value)
{
var emailAddress = value?.ToString();
if (emailAddress == null)
{
return false;
}
var illegalChars = @"[\s<>()]";
if (Regex.IsMatch(emailAddress, illegalChars))
{
return false;
}
return new EmailAddressAttribute().IsValid(emailAddress);
}
}
}

View File

@ -4,11 +4,11 @@ using System.Linq;
namespace Bit.Core.Utilities namespace Bit.Core.Utilities
{ {
public class EmailAddressListAttribute : ValidationAttribute public class StrictEmailAddressListAttribute : ValidationAttribute
{ {
protected override ValidationResult IsValid(object value, ValidationContext validationContext) protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{ {
var emailAttribute = new EmailAddressAttribute(); var strictEmailAttribute = new StrictEmailAddressAttribute();
var emails = value as IList<string>; var emails = value as IList<string>;
if (!emails?.Any() ?? true) if (!emails?.Any() ?? true)
@ -24,7 +24,7 @@ namespace Bit.Core.Utilities
for (var i = 0; i < emails.Count(); i++) for (var i = 0; i < emails.Count(); i++)
{ {
var email = emails.ElementAt(i); var email = emails.ElementAt(i);
if (!emailAttribute.IsValid(email) || email.Contains(" ") || email.Contains("<")) if (!strictEmailAttribute.IsValid(email))
{ {
return new ValidationResult($"Email #{i + 1} is not valid."); return new ValidationResult($"Email #{i + 1} is not valid.");
} }