1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-12 00:28:11 -05:00

Merge branch 'main' into experiment/authorize-attribute

This commit is contained in:
Thomas Rittson 2025-04-07 11:40:59 +10:00 committed by GitHub
commit d7bdc652d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 25 additions and 186 deletions

9
.github/CODEOWNERS vendored
View File

@ -20,12 +20,19 @@
# Database Operations for database changes
src/Sql/** @bitwarden/dept-dbops
util/EfShared/** @bitwarden/dept-dbops
util/Migrator/** @bitwarden/dept-dbops
util/Migrator/** @bitwarden/team-platform-dev # The Platform team owns the Migrator project code
util/Migrator/DbScripts/** @bitwarden/dept-dbops
util/Migrator/DbScripts_finalization/** @bitwarden/dept-dbops
util/Migrator/DbScripts_transition/** @bitwarden/dept-dbops
util/Migrator/MySql/** @bitwarden/dept-dbops
util/MySqlMigrations/** @bitwarden/dept-dbops
util/PostgresMigrations/** @bitwarden/dept-dbops
util/SqlServerEFScaffold/** @bitwarden/dept-dbops
util/SqliteMigrations/** @bitwarden/dept-dbops
# Shared util projects
util/Setup/** @bitwarden/dept-bre @bitwarden/team-platform-dev
# Auth team
**/Auth @bitwarden/team-auth-dev
bitwarden_license/src/Sso @bitwarden/team-auth-dev

View File

@ -2,7 +2,6 @@
<PropertyGroup>
<UserSecretsId>bitwarden-Billing</UserSecretsId>
<MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>
</PropertyGroup>
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Billing' " />

View File

@ -87,8 +87,7 @@ public class Startup
// TODO: no longer be required - see PM-1880
services.AddScoped<IServiceAccountRepository, NoopServiceAccountRepository>();
// Mvc
services.AddMvc(config =>
services.AddControllers(config =>
{
config.Filters.Add(new LoggingExceptionHandlerFilterAttribute());
});

View File

@ -1,6 +0,0 @@
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>

View File

@ -1,21 +0,0 @@
@model LoginModel
@{
ViewData["Title"] = "Login";
}
<div class="row justify-content-md-center">
<div class="col-4">
<p>Please enter your email address below to log in.</p>
<form asp-action="" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Email" class="sr-only">Email Address</label>
<input asp-for="Email" type="email" class="form-control" placeholder="ex. john@example.com"
required autofocus>
<span asp-validation-for="Email" class="invalid-feedback"></span>
<small class="form-text text-body-secondary">We'll email you a secure login link.</small>
</div>
<button class="btn btn-primary btn-block" type="submit">Continue</button>
</form>
</div>
</div>

View File

@ -1,14 +0,0 @@
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
</p>

View File

@ -1,41 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] | Bitwarden Billing Portal</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<link rel="stylesheet" href="~/styles/billing.css">
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4">
<div class="container">
<a class="navbar-brand" href="#"><i class="fa fa-lg fa-fw fa-shield"></i> Billing</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse"
aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
</ul>
</div>
</div>
</nav>
<main role="main" class="container">
@RenderBody()
</main>
@RenderSection("Scripts", required: false)
</body>
</html>

View File

@ -1,3 +0,0 @@
@using Bit.Billing
@using Bit.Billing.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -1,3 +0,0 @@
@{
Layout = "_Layout";
}

View File

@ -1,6 +0,0 @@
.custom-select.input-validation-error ~ .invalid-feedback,
.custom-select.input-validation-error ~ .invalid-tooltip,
.form-control.input-validation-error ~ .invalid-feedback,
.form-control.input-validation-error ~ .invalid-tooltip {
display: block;
}

View File

@ -16,7 +16,6 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.RestoreUs
public class RestoreOrganizationUserCommand(
ICurrentContext currentContext,
IEventService eventService,
IFeatureService featureService,
IPushNotificationService pushNotificationService,
IOrganizationUserRepository organizationUserRepository,
IOrganizationRepository organizationRepository,
@ -41,8 +40,7 @@ public class RestoreOrganizationUserCommand(
await RepositoryRestoreUserAsync(organizationUser);
await eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored);
if (featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) &&
organizationUser.UserId.HasValue)
if (organizationUser.UserId.HasValue)
{
await pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value);
}
@ -54,8 +52,7 @@ public class RestoreOrganizationUserCommand(
await eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored,
systemUser);
if (featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) &&
organizationUser.UserId.HasValue)
if (organizationUser.UserId.HasValue)
{
await pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value);
}
@ -219,8 +216,7 @@ public class RestoreOrganizationUserCommand(
await organizationUserRepository.RestoreAsync(organizationUser.Id, status);
organizationUser.Status = status;
await eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored);
if (featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) &&
organizationUser.UserId.HasValue)
if (organizationUser.UserId.HasValue)
{
await pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value);
}

View File

@ -1791,7 +1791,7 @@ public class OrganizationService : IOrganizationService
await RepositoryRevokeUserAsync(organizationUser);
await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked);
if (_featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) && organizationUser.UserId.HasValue)
if (organizationUser.UserId.HasValue)
{
await _pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value);
}
@ -1803,7 +1803,7 @@ public class OrganizationService : IOrganizationService
await RepositoryRevokeUserAsync(organizationUser);
await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked, systemUser);
if (_featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) && organizationUser.UserId.HasValue)
if (organizationUser.UserId.HasValue)
{
await _pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value);
}
@ -1872,7 +1872,7 @@ public class OrganizationService : IOrganizationService
await _organizationUserRepository.RevokeAsync(organizationUser.Id);
organizationUser.Status = OrganizationUserStatusType.Revoked;
await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked);
if (_featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) && organizationUser.UserId.HasValue)
if (organizationUser.UserId.HasValue)
{
await _pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value);
}

View File

@ -56,6 +56,7 @@ public class NotificationPushNotification
public Guid? UserId { get; set; }
public Guid? OrganizationId { get; set; }
public Guid? InstallationId { get; set; }
public Guid? TaskId { get; set; }
public string? Title { get; set; }
public string? Body { get; set; }
public DateTime CreationDate { get; set; }

View File

@ -212,6 +212,7 @@ public class NotificationHubPushNotificationService : IPushNotificationService
UserId = notification.UserId,
OrganizationId = notification.OrganizationId,
InstallationId = installationId,
TaskId = notification.TaskId,
Title = notification.Title,
Body = notification.Body,
CreationDate = notification.CreationDate,
@ -263,6 +264,7 @@ public class NotificationHubPushNotificationService : IPushNotificationService
UserId = notification.UserId,
OrganizationId = notification.OrganizationId,
InstallationId = installationId,
TaskId = notification.TaskId,
Title = notification.Title,
Body = notification.Body,
CreationDate = notification.CreationDate,

View File

@ -188,6 +188,7 @@ public class AzureQueuePushNotificationService : IPushNotificationService
UserId = notification.UserId,
OrganizationId = notification.OrganizationId,
InstallationId = notification.Global ? _globalSettings.Installation.Id : null,
TaskId = notification.TaskId,
Title = notification.Title,
Body = notification.Body,
CreationDate = notification.CreationDate,
@ -208,6 +209,7 @@ public class AzureQueuePushNotificationService : IPushNotificationService
UserId = notification.UserId,
OrganizationId = notification.OrganizationId,
InstallationId = notification.Global ? _globalSettings.Installation.Id : null,
TaskId = notification.TaskId,
Title = notification.Title,
Body = notification.Body,
CreationDate = notification.CreationDate,

View File

@ -201,6 +201,7 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
UserId = notification.UserId,
OrganizationId = notification.OrganizationId,
InstallationId = notification.Global ? _globalSettings.Installation.Id : null,
TaskId = notification.TaskId,
Title = notification.Title,
Body = notification.Body,
CreationDate = notification.CreationDate,
@ -221,6 +222,7 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
UserId = notification.UserId,
OrganizationId = notification.OrganizationId,
InstallationId = notification.Global ? _globalSettings.Installation.Id : null,
TaskId = notification.TaskId,
Title = notification.Title,
Body = notification.Body,
CreationDate = notification.CreationDate,

View File

@ -210,6 +210,7 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
UserId = notification.UserId,
OrganizationId = notification.OrganizationId,
InstallationId = notification.Global ? _globalSettings.Installation.Id : null,
TaskId = notification.TaskId,
Title = notification.Title,
Body = notification.Body,
CreationDate = notification.CreationDate,
@ -247,6 +248,7 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
UserId = notification.UserId,
OrganizationId = notification.OrganizationId,
InstallationId = notification.Global ? _globalSettings.Installation.Id : null,
TaskId = notification.TaskId,
Title = notification.Title,
Body = notification.Body,
CreationDate = notification.CreationDate,

View File

@ -31,26 +31,6 @@ public class RestoreOrganizationUserCommandTests
await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id);
await sutProvider.GetDependency<IOrganizationUserRepository>()
.Received(1)
.RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited);
await sutProvider.GetDependency<IEventService>()
.Received(1)
.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored);
}
[Theory, BitAutoData]
public async Task RestoreUser_WithPushSyncOrgKeysOnRevokeRestoreEnabled_Success(Organization organization, [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.Owner)] OrganizationUser owner,
[OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, SutProvider<RestoreOrganizationUserCommand> sutProvider)
{
RestoreUser_Setup(organization, owner, organizationUser, sutProvider);
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore)
.Returns(true);
await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id);
await sutProvider.GetDependency<IOrganizationUserRepository>()
.Received(1)
.RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited);
@ -69,25 +49,6 @@ public class RestoreOrganizationUserCommandTests
await sutProvider.Sut.RestoreUserAsync(organizationUser, eventSystemUser);
await sutProvider.GetDependency<IOrganizationUserRepository>()
.Received(1)
.RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited);
await sutProvider.GetDependency<IEventService>()
.Received(1)
.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored, eventSystemUser);
}
[Theory, BitAutoData]
public async Task RestoreUser_WithEventSystemUser_WithPushSyncOrgKeysOnRevokeRestoreEnabled_Success(Organization organization, [OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, EventSystemUser eventSystemUser, SutProvider<RestoreOrganizationUserCommand> sutProvider)
{
RestoreUser_Setup(organization, null, organizationUser, sutProvider);
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore)
.Returns(true);
await sutProvider.Sut.RestoreUserAsync(organizationUser, eventSystemUser);
await sutProvider.GetDependency<IOrganizationUserRepository>()
.Received(1)
.RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited);

View File

@ -1162,26 +1162,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
await sutProvider.Sut.RevokeUserAsync(organizationUser, owner.Id);
await sutProvider.GetDependency<IOrganizationUserRepository>()
.Received(1)
.RevokeAsync(organizationUser.Id);
await sutProvider.GetDependency<IEventService>()
.Received(1)
.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked);
}
[Theory, BitAutoData]
public async Task RevokeUser_WithPushSyncOrgKeysOnRevokeRestoreEnabled_Success(Organization organization, [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.Owner)] OrganizationUser owner,
[OrganizationUser] OrganizationUser organizationUser, SutProvider<OrganizationService> sutProvider)
{
RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider);
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore)
.Returns(true);
await sutProvider.Sut.RevokeUserAsync(organizationUser, owner.Id);
await sutProvider.GetDependency<IOrganizationUserRepository>()
.Received(1)
.RevokeAsync(organizationUser.Id);
@ -1200,25 +1180,6 @@ OrganizationUserInvite invite, SutProvider<OrganizationService> sutProvider)
await sutProvider.Sut.RevokeUserAsync(organizationUser, eventSystemUser);
await sutProvider.GetDependency<IOrganizationUserRepository>()
.Received(1)
.RevokeAsync(organizationUser.Id);
await sutProvider.GetDependency<IEventService>()
.Received(1)
.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked, eventSystemUser);
}
[Theory, BitAutoData]
public async Task RevokeUser_WithEventSystemUser_WithPushSyncOrgKeysOnRevokeRestoreEnabled_Success(Organization organization, [OrganizationUser] OrganizationUser organizationUser, EventSystemUser eventSystemUser, SutProvider<OrganizationService> sutProvider)
{
RestoreRevokeUser_Setup(organization, null, organizationUser, sutProvider);
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore)
.Returns(true);
await sutProvider.Sut.RevokeUserAsync(organizationUser, eventSystemUser);
await sutProvider.GetDependency<IOrganizationUserRepository>()
.Received(1)
.RevokeAsync(organizationUser.Id);

View File

@ -507,6 +507,7 @@ public class NotificationHubPushNotificationServiceTests
UserId = notification.UserId,
OrganizationId = notification.OrganizationId,
InstallationId = installationId,
TaskId = notification.TaskId,
Title = notification.Title,
Body = notification.Body,
CreationDate = notification.CreationDate,