diff --git a/api/repositories/org_repository.go b/api/repositories/org_repository.go index 3f9e5084a..0418afe59 100644 --- a/api/repositories/org_repository.go +++ b/api/repositories/org_repository.go @@ -243,11 +243,25 @@ func (r *OrgRepo) PatchOrgMetadata(ctx context.Context, authInfo authorization.I } func (r *OrgRepo) GetDeletedAt(ctx context.Context, authInfo authorization.Info, orgGUID string) (*time.Time, error) { - org, err := r.GetOrg(ctx, authInfo, orgGUID) + userClient, err := r.userClientFactory.BuildClient(authInfo) if err != nil { - return nil, err + return nil, fmt.Errorf("get-deleted-at failed to build user client: %w", err) } - return org.DeletedAt, nil + + cfOrg := new(korifiv1alpha1.CFOrg) + err = userClient.Get(ctx, client.ObjectKey{Namespace: r.rootNamespace, Name: orgGUID}, cfOrg) + if err != nil { + return nil, apierrors.FromK8sError(err, OrgResourceType) + } + + record := cfOrgToOrgRecord(*cfOrg) + + if record.DeletedAt != nil { + return record.DeletedAt, nil + } + + _, err = r.GetOrg(ctx, authInfo, orgGUID) + return nil, err } func cfOrgToOrgRecord(cfOrg korifiv1alpha1.CFOrg) OrgRecord { diff --git a/api/repositories/org_repository_test.go b/api/repositories/org_repository_test.go index 3c89f7107..9472184ab 100644 --- a/api/repositories/org_repository_test.go +++ b/api/repositories/org_repository_test.go @@ -380,6 +380,9 @@ var _ = Describe("OrgRepository", func() { }) When("the org is being deleted", func() { + // This case occurs briefly between the CFOrg starting to delete and the finalizer deleting + // the roles in the org namespace. Once the finalizer deletes the roles, we'll be in the + // "the user does not have a role binding in the org" case below BeforeEach(func() { Expect(k8s.PatchResource(ctx, k8sClient, cfOrg, func() { cfOrg.Finalizers = append(cfOrg.Finalizers, "foo") @@ -396,8 +399,29 @@ var _ = Describe("OrgRepository", func() { }) When("the user does not have a role binding in the org", func() { - It("errors", func() { - Expect(getErr).To(matchers.WrapErrorAssignableToTypeOf(apierrors.NotFoundError{})) + When("the org is not being deleted", func() { + It("errors", func() { + Expect(getErr).To(matchers.WrapErrorAssignableToTypeOf(apierrors.NotFoundError{})) + }) + }) + + When("the org is being deleted", func() { + // This case occurs in 2 situations: + // 1. The user never has access to the Org, but another user deleted it + // 2. The user had access to the Org, deleted it, but the CFOrg finalizer has already + // deleted their role bindings + BeforeEach(func() { + Expect(k8s.PatchResource(ctx, k8sClient, cfOrg, func() { + cfOrg.Finalizers = append(cfOrg.Finalizers, "foo") + })).To(Succeed()) + + Expect(k8sClient.Delete(ctx, cfOrg)).To(Succeed()) + }) + + It("returns the deletion time", func() { + Expect(getErr).NotTo(HaveOccurred()) + Expect(deletionTime).To(PointTo(BeTemporally("~", time.Now(), time.Minute))) + }) }) })