Skip to content

Commit

Permalink
Merge branch 'main' into auth/pm-8107/remove-duo-metadata-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
ike-kottlowski authored Oct 25, 2024
2 parents f6e5261 + 53ad9df commit 7ed5aaf
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 144 deletions.
56 changes: 52 additions & 4 deletions .github/workflows/repository-management.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,61 @@ jobs:
git config --local user.email "[email protected]"
git config --local user.name "Github Actions"
- name: Create version branch
id: create-branch
run: |
NAME=version_bump_${{ github.ref_name }}_$(date +"%Y-%m-%d")
git switch -c $NAME
echo "name=$NAME" >> $GITHUB_OUTPUT
- name: Commit files
run: git commit -m "Bumped version to ${{ steps.set-final-version-output.outputs.version }}" -a

- name: Push changes
run: git push

- name: Generate GH App token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
owner: ${{ github.repository_owner }}

- name: Create version PR
id: create-pr
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
PR_BRANCH: ${{ steps.create-branch.outputs.name }}
TITLE: "Bump version to ${{ steps.set-final-version-output.outputs.version }}"
run: |
git pull -pt
git push
PR_URL=$(gh pr create --title "$TITLE" \
--base "main" \
--head "$PR_BRANCH" \
--label "version update" \
--label "automated pr" \
--body "
## Type of change
- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [X] Other
## Objective
Automated version bump to ${{ steps.set-final-version-output.outputs.version }}")
echo "pr_number=${PR_URL##*/}" >> $GITHUB_OUTPUT
- name: Approve PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }}
run: gh pr review $PR_NUMBER --approve

- name: Merge PR
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }}
run: gh pr merge $PR_NUMBER --squash --auto --delete-branch


cherry_pick:
Expand All @@ -153,7 +201,7 @@ jobs:
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
with:
ref: main

- name: Install xmllint
run: |
sudo apt-get update
Expand Down Expand Up @@ -189,7 +237,7 @@ jobs:
RC_VERSION=$(xmllint -xpath "/Project/PropertyGroup/Version/text()" Directory.Build.props)
echo "rc_version=$RC_VERSION" >> $GITHUB_OUTPUT
fi
- name: Configure Git
run: |
git config --local user.email "[email protected]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,42 +379,23 @@ public async Task<Subscription> SetupSubscription(

var subscriptionItemOptionsList = new List<SubscriptionItemOptions>();

var teamsProviderPlan =
providerPlans.SingleOrDefault(providerPlan => providerPlan.PlanType == PlanType.TeamsMonthly);

if (teamsProviderPlan == null || !teamsProviderPlan.IsConfigured())
foreach (var providerPlan in providerPlans)
{
logger.LogError("Cannot start subscription for provider ({ProviderID}) that has no configured Teams plan", provider.Id);

throw new BillingException();
}

var teamsPlan = StaticStore.GetPlan(PlanType.TeamsMonthly);

subscriptionItemOptionsList.Add(new SubscriptionItemOptions
{
Price = teamsPlan.PasswordManager.StripeProviderPortalSeatPlanId,
Quantity = teamsProviderPlan.SeatMinimum
});

var enterpriseProviderPlan =
providerPlans.SingleOrDefault(providerPlan => providerPlan.PlanType == PlanType.EnterpriseMonthly);
var plan = StaticStore.GetPlan(providerPlan.PlanType);

if (enterpriseProviderPlan == null || !enterpriseProviderPlan.IsConfigured())
{
logger.LogError("Cannot start subscription for provider ({ProviderID}) that has no configured Enterprise plan", provider.Id);
if (!providerPlan.IsConfigured())
{
logger.LogError("Cannot start subscription for provider ({ProviderID}) that has no configured {ProviderName} plan", provider.Id, plan.Name);
throw new BillingException();
}

throw new BillingException();
subscriptionItemOptionsList.Add(new SubscriptionItemOptions
{
Price = plan.PasswordManager.StripeProviderPortalSeatPlanId,
Quantity = providerPlan.SeatMinimum
});
}

var enterprisePlan = StaticStore.GetPlan(PlanType.EnterpriseMonthly);

subscriptionItemOptionsList.Add(new SubscriptionItemOptions
{
Price = enterprisePlan.PasswordManager.StripeProviderPortalSeatPlanId,
Quantity = enterpriseProviderPlan.SeatMinimum
});

var subscriptionCreateOptions = new SubscriptionCreateOptions
{
AutomaticTax = new SubscriptionAutomaticTaxOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ public async Task<OrganizationUserDetailsResponseModel> Get(Guid id, bool includ
}

[HttpGet("mini-details")]
[RequireFeature(FeatureFlagKeys.Pm3478RefactorOrganizationUserApi)]
public async Task<ListResponseModel<OrganizationUserUserMiniDetailsResponseModel>> GetMiniDetails(Guid orgId)
{
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new OrganizationScope(orgId),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#nullable enable
using Bit.Core.Context;
using Bit.Core.Enums;
using Bit.Core.Services;
using Microsoft.AspNetCore.Authorization;

namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Authorization;
Expand All @@ -10,12 +9,10 @@ public class OrganizationUserUserDetailsAuthorizationHandler
: AuthorizationHandler<OrganizationUserUserDetailsOperationRequirement, OrganizationScope>
{
private readonly ICurrentContext _currentContext;
private readonly IFeatureService _featureService;

public OrganizationUserUserDetailsAuthorizationHandler(ICurrentContext currentContext, IFeatureService featureService)
public OrganizationUserUserDetailsAuthorizationHandler(ICurrentContext currentContext)
{
_currentContext = currentContext;
_featureService = featureService;
}

protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
Expand All @@ -37,29 +34,6 @@ protected override async Task HandleRequirementAsync(AuthorizationHandlerContext
}

private async Task<bool> CanReadAllAsync(Guid organizationId)
{
if (_featureService.IsEnabled(FeatureFlagKeys.Pm3478RefactorOrganizationUserApi))
{
return await CanReadAllAsync_vNext(organizationId);
}

return await CanReadAllAsync_vCurrent(organizationId);
}

private async Task<bool> CanReadAllAsync_vCurrent(Guid organizationId)
{
// All users of an organization can read all other users of that organization for collection access management
var org = _currentContext.GetOrganization(organizationId);
if (org is not null)
{
return true;
}

// Allow provider users to read all organization users if they are a provider for the target organization
return await _currentContext.ProviderUserForOrgAsync(organizationId);
}

private async Task<bool> CanReadAllAsync_vNext(Guid organizationId)
{
// Admins can access this for general user management
var organization = _currentContext.GetOrganization(organizationId);
Expand Down
2 changes: 2 additions & 0 deletions src/Core/Billing/Models/StaticStore/Plans/EnterprisePlan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ public EnterprisePasswordManagerFeatures(bool isAnnual)
AdditionalStoragePricePerGb = 4;
StripeStoragePlanId = "storage-gb-annually";
StripeSeatPlanId = "2023-enterprise-org-seat-annually";
StripeProviderPortalSeatPlanId = "password-manager-provider-portal-enterprise-annually-2024";
SeatPrice = 72;
ProviderPortalSeatPrice = 72;
}
else
{
Expand Down
1 change: 0 additions & 1 deletion src/Core/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ public static class FeatureFlagKeys
public const string EnableNewCardCombinedExpiryAutofill = "enable-new-card-combined-expiry-autofill";
public const string StorageReseedRefactor = "storage-reseed-refactor";
public const string TrialPayment = "PM-8163-trial-payment";
public const string Pm3478RefactorOrganizationUserApi = "pm-3478-refactor-organizationuser-api";
public const string RemoveServerVersionHeader = "remove-server-version-header";
public const string AccessIntelligence = "pm-13227-access-intelligence";
public const string VerifiedSsoDomainEndpoint = "pm-12337-refactor-sso-details-endpoint";
Expand Down
9 changes: 5 additions & 4 deletions src/SharedWeb/Utilities/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,11 @@ public static void AddDefaultServices(this IServiceCollection services, GlobalSe
services.AddKeyedSingleton<IPushNotificationService, RelayPushNotificationService>("implementation");
services.AddSingleton<IPushRegistrationService, RelayPushRegistrationService>();
}
else
{
services.AddSingleton<IPushRegistrationService, NoopPushRegistrationService>();
}

if (CoreHelpers.SettingHasValue(globalSettings.InternalIdentityKey) &&
CoreHelpers.SettingHasValue(globalSettings.BaseServiceUri.InternalNotifications))
{
Expand All @@ -292,10 +297,6 @@ public static void AddDefaultServices(this IServiceCollection services, GlobalSe
services.AddKeyedSingleton<IPushNotificationService, AzureQueuePushNotificationService>("implementation");
}
}
else
{
services.AddSingleton<IPushRegistrationService, NoopPushRegistrationService>();
}

if (!globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.Mail.ConnectionString))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Authorization;
using Bit.Core.Context;
using Bit.Core.Enums;
using Bit.Core.Services;
using Bit.Core.Test.AdminConsole.AutoFixture;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
Expand All @@ -24,7 +23,6 @@ public async Task ReadAll_Admins_Success(
CurrentContextOrganization organization,
SutProvider<OrganizationUserUserDetailsAuthorizationHandler> sutProvider)
{
EnableFeatureFlag(sutProvider);
organization.Type = userType;
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);

Expand All @@ -48,7 +46,6 @@ public async Task ReadAll_ProviderUser_Success(
CurrentContextOrganization organization,
SutProvider<OrganizationUserUserDetailsAuthorizationHandler> sutProvider)
{
EnableFeatureFlag(sutProvider);
organization.Type = OrganizationUserType.User;
sutProvider.GetDependency<ICurrentContext>()
.ProviderUserForOrgAsync(organization.Id)
Expand All @@ -69,7 +66,6 @@ public async Task ReadAll_User_NoSuccess(
CurrentContextOrganization organization,
SutProvider<OrganizationUserUserDetailsAuthorizationHandler> sutProvider)
{
EnableFeatureFlag(sutProvider);
organization.Type = OrganizationUserType.User;
sutProvider.GetDependency<ICurrentContext>().GetOrganization(Arg.Any<Guid>()).Returns(organization);
sutProvider.GetDependency<ICurrentContext>().ProviderUserForOrgAsync(Arg.Any<Guid>()).Returns(false);
Expand All @@ -88,78 +84,6 @@ public async Task ReadAll_User_NoSuccess(
public async Task ReadAll_NotMember_NoSuccess(
CurrentContextOrganization organization,
SutProvider<OrganizationUserUserDetailsAuthorizationHandler> sutProvider)
{
EnableFeatureFlag(sutProvider);
var context = new AuthorizationHandlerContext(
new[] { OrganizationUserUserDetailsOperations.ReadAll },
new ClaimsPrincipal(),
new OrganizationScope(organization.Id)
);

sutProvider.GetDependency<ICurrentContext>().GetOrganization(Arg.Any<Guid>()).Returns((CurrentContextOrganization)null);
sutProvider.GetDependency<ICurrentContext>().ProviderUserForOrgAsync(Arg.Any<Guid>()).Returns(false);

await sutProvider.Sut.HandleAsync(context);
Assert.False(context.HasSucceeded);
}

private void EnableFeatureFlag(SutProvider<OrganizationUserUserDetailsAuthorizationHandler> sutProvider)
{
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.Pm3478RefactorOrganizationUserApi)
.Returns(true);
}

// TESTS WITH FLAG DISABLED - TO BE DELETED IN FLAG CLEANUP

[Theory, CurrentContextOrganizationCustomize]
[BitAutoData(OrganizationUserType.Admin)]
[BitAutoData(OrganizationUserType.Owner)]
[BitAutoData(OrganizationUserType.User)]
[BitAutoData(OrganizationUserType.Custom)]
public async Task FlagDisabled_ReadAll_AnyMemberOfOrg_Success(
OrganizationUserType userType,
Guid userId, SutProvider<OrganizationUserUserDetailsAuthorizationHandler> sutProvider,
CurrentContextOrganization organization)
{
organization.Type = userType;

var context = new AuthorizationHandlerContext(
new[] { OrganizationUserUserDetailsOperations.ReadAll },
new ClaimsPrincipal(),
new OrganizationScope(organization.Id));

sutProvider.GetDependency<ICurrentContext>().UserId.Returns(userId);
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);

await sutProvider.Sut.HandleAsync(context);

Assert.True(context.HasSucceeded);
}

[Theory, BitAutoData, CurrentContextOrganizationCustomize]
public async Task FlagDisabled_ReadAll_ProviderUser_Success(
CurrentContextOrganization organization,
SutProvider<OrganizationUserUserDetailsAuthorizationHandler> sutProvider)
{
organization.Type = OrganizationUserType.User;
sutProvider.GetDependency<ICurrentContext>()
.ProviderUserForOrgAsync(organization.Id)
.Returns(true);

var context = new AuthorizationHandlerContext(
new[] { OrganizationUserUserDetailsOperations.ReadAll },
new ClaimsPrincipal(),
new OrganizationScope(organization.Id));

await sutProvider.Sut.HandleAsync(context);

Assert.True(context.HasSucceeded);
}

[Theory, BitAutoData]
public async Task FlagDisabled_ReadAll_NotMember_NoSuccess(
CurrentContextOrganization organization,
SutProvider<OrganizationUserUserDetailsAuthorizationHandler> sutProvider)
{
var context = new AuthorizationHandlerContext(
new[] { OrganizationUserUserDetailsOperations.ReadAll },
Expand Down

0 comments on commit 7ed5aaf

Please sign in to comment.