1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-21 12:05:42 +01:00

[AC-1585] Automatically verify managed members on an organization with a verified domain (#3207)

This commit is contained in:
Rui Tomé 2023-08-30 07:23:45 +01:00 committed by GitHub
parent 6d078851dc
commit e679d3127a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 6 deletions

View File

@ -47,6 +47,7 @@ public class AccountController : Controller
private readonly IGlobalSettings _globalSettings; private readonly IGlobalSettings _globalSettings;
private readonly Core.Services.IEventService _eventService; private readonly Core.Services.IEventService _eventService;
private readonly IDataProtectorTokenFactory<SsoTokenable> _dataProtector; private readonly IDataProtectorTokenFactory<SsoTokenable> _dataProtector;
private readonly IOrganizationDomainRepository _organizationDomainRepository;
public AccountController( public AccountController(
IAuthenticationSchemeProvider schemeProvider, IAuthenticationSchemeProvider schemeProvider,
@ -65,7 +66,8 @@ public class AccountController : Controller
UserManager<User> userManager, UserManager<User> userManager,
IGlobalSettings globalSettings, IGlobalSettings globalSettings,
Core.Services.IEventService eventService, Core.Services.IEventService eventService,
IDataProtectorTokenFactory<SsoTokenable> dataProtector) IDataProtectorTokenFactory<SsoTokenable> dataProtector,
IOrganizationDomainRepository organizationDomainRepository)
{ {
_schemeProvider = schemeProvider; _schemeProvider = schemeProvider;
_clientStore = clientStore; _clientStore = clientStore;
@ -84,6 +86,7 @@ public class AccountController : Controller
_eventService = eventService; _eventService = eventService;
_globalSettings = globalSettings; _globalSettings = globalSettings;
_dataProtector = dataProtector; _dataProtector = dataProtector;
_organizationDomainRepository = organizationDomainRepository;
} }
[HttpGet] [HttpGet]
@ -513,11 +516,21 @@ public class AccountController : Controller
} }
} }
// If the email domain is verified, we can mark the email as verified
var emailVerified = false;
var emailDomain = CoreHelpers.GetEmailDomain(email);
if (!string.IsNullOrWhiteSpace(emailDomain))
{
var organizationDomain = await _organizationDomainRepository.GetDomainByOrgIdAndDomainNameAsync(orgId, emailDomain);
emailVerified = organizationDomain?.VerifiedDate.HasValue ?? false;
}
// Create user record - all existing user flows are handled above // Create user record - all existing user flows are handled above
var user = new User var user = new User
{ {
Name = name, Name = name,
Email = email, Email = email,
EmailVerified = emailVerified,
ApiKey = CoreHelpers.SecureRandomString(30) ApiKey = CoreHelpers.SecureRandomString(30)
}; };
await _userService.RegisterUserAsync(user); await _userService.RegisterUserAsync(user);

View File

@ -50,20 +50,20 @@ public static class CoreHelpers
{ {
var guidArray = startingGuid.ToByteArray(); var guidArray = startingGuid.ToByteArray();
// Get the days and milliseconds which will be used to build the byte string // Get the days and milliseconds which will be used to build the byte string
var days = new TimeSpan(time.Ticks - _baseDateTicks); var days = new TimeSpan(time.Ticks - _baseDateTicks);
var msecs = time.TimeOfDay; var msecs = time.TimeOfDay;
// Convert to a byte array // Convert to a byte array
// Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333 // Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333
var daysArray = BitConverter.GetBytes(days.Days); var daysArray = BitConverter.GetBytes(days.Days);
var msecsArray = BitConverter.GetBytes((long)(msecs.TotalMilliseconds / 3.333333)); var msecsArray = BitConverter.GetBytes((long)(msecs.TotalMilliseconds / 3.333333));
// Reverse the bytes to match SQL Servers ordering // Reverse the bytes to match SQL Servers ordering
Array.Reverse(daysArray); Array.Reverse(daysArray);
Array.Reverse(msecsArray); Array.Reverse(msecsArray);
// Copy the bytes into the guid // Copy the bytes into the guid
Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2); Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2);
Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4); Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4);
@ -817,4 +817,19 @@ public static class CoreHelpers
.ToString(); .ToString();
} }
public static string GetEmailDomain(string email)
{
if (!string.IsNullOrWhiteSpace(email))
{
var emailParts = email.Split('@', StringSplitOptions.RemoveEmptyEntries);
if (emailParts.Length == 2)
{
return emailParts[1].Trim();
}
}
return null;
}
} }

View File

@ -416,4 +416,25 @@ public class CoreHelpersTests
{ {
Assert.Equal(expected, CoreHelpers.ObfuscateEmail(input)); Assert.Equal(expected, CoreHelpers.ObfuscateEmail(input));
} }
[Theory]
[InlineData("user@example.com")]
[InlineData("user@example.com ")]
[InlineData("user.name@example.com")]
public void GetEmailDomain_Success(string email)
{
Assert.Equal("example.com", CoreHelpers.GetEmailDomain(email));
}
[Theory]
[InlineData("")]
[InlineData(null)]
[InlineData("userexample.com")]
[InlineData("user@")]
[InlineData("@example.com")]
[InlineData("user@ex@ample.com")]
public void GetEmailDomain_ReturnsNull(string wrongEmail)
{
Assert.Null(CoreHelpers.GetEmailDomain(wrongEmail));
}
} }