Skip to content

Commit

Permalink
Merge pull request #104 from beabee-communityrm/feat/permission-changes
Browse files Browse the repository at this point in the history
chore: callout response entity permission changes
  • Loading branch information
wpf500 authored Dec 5, 2024
2 parents e8ae286 + d88c6d6 commit 3ef707f
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 38 deletions.
1 change: 1 addition & 0 deletions apps/backend/src/api/dto/CalloutResponseDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { Callout } from "@beabee/core/models";

export interface BaseGetCalloutResponseOptsDto {
callout?: Callout;
isReviewer?: boolean;
}

export enum GetCalloutResponseWith {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import { mergeRules } from "@beabee/core/utils/rules";

import { CalloutResponse } from "@beabee/core/models";

import { AuthInfo, FilterHandlers } from "@beabee/core/type";
import { FilterHandlers } from "@beabee/core/type";
import { calloutResponseFilterHandlers } from "@beabee/core/filter-handlers";
import { getReviewerRules } from "@api/utils/callouts";

export abstract class BaseCalloutResponseTransformer<
GetDto,
Expand All @@ -43,21 +42,6 @@ export abstract class BaseCalloutResponseTransformer<
];
}

protected async getNonAdminAuthRules(
auth: AuthInfo,
query: GetOptsDto
): Promise<RuleGroup> {
return {
condition: "OR",
rules: [
// User's can always see their own responses
{ field: "contact", operator: "equal", value: ["me"] },
// And any responses for callouts they are reviewers for
...(await getReviewerRules(auth.contact, "calloutId"))
]
};
}

protected transformQuery<T extends GetOptsDto & PaginatedQuery>(query: T): T {
return {
...query,
Expand Down
13 changes: 12 additions & 1 deletion apps/backend/src/api/transformers/CalloutResponseExporter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
RoleType,
RuleGroup,
getCalloutComponents,
stringifyAnswer
} from "@beabee/beabee-common";
Expand All @@ -16,7 +17,7 @@ import {
} from "@api/dto/CalloutResponseDto";
import { BaseCalloutResponseTransformer } from "@api/transformers/BaseCalloutResponseTransformer";
import { NotFoundError } from "@beabee/core/errors";
import { groupBy } from "@api/utils";
import { getReviewerRules, groupBy } from "@api/utils";

import {
CalloutResponse,
Expand Down Expand Up @@ -59,6 +60,16 @@ class CalloutResponseExporter extends BaseCalloutResponseTransformer<
];
}

protected async getNonAdminAuthRules(
auth: AuthInfo,
query: ExportCalloutResponsesOptsDto
): Promise<RuleGroup | false> {
const reviewerRules = await getReviewerRules(auth.contact, "calloutId");
return reviewerRules.length
? { condition: "OR", rules: reviewerRules }
: false;
}

protected modifyQueryBuilder(
qb: SelectQueryBuilder<CalloutResponse>,
fieldPrefix: string
Expand Down
18 changes: 0 additions & 18 deletions apps/backend/src/api/transformers/CalloutResponseMapTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { getRepository } from "@beabee/core/database";
import {
GetCalloutResponseMapDto,
GetCalloutResponseMapOptsDto,
ListCalloutResponseMapDto,
ListCalloutResponsesDto
} from "@api/dto/CalloutResponseDto";
import { PaginatedDto } from "@api/dto/PaginatedDto";
Expand All @@ -24,8 +23,6 @@ import { BaseCalloutResponseTransformer } from "@api/transformers/BaseCalloutRes

import { Callout, CalloutResponse } from "@beabee/core/models";

import { mergeRules } from "@beabee/core/utils/rules";

import { AuthInfo } from "@beabee/core/type";

class CalloutResponseMapTransformer extends BaseCalloutResponseTransformer<
Expand Down Expand Up @@ -100,21 +97,6 @@ class CalloutResponseMapTransformer extends BaseCalloutResponseTransformer<
};
}

protected transformQuery<T extends ListCalloutResponseMapDto>(query: T): T {
return {
...query,
rules: mergeRules([
query.rules,
// Only load responses for the given callout
{
field: "calloutId",
operator: "equal",
value: [query.callout.id]
}
])
};
}

/**
* Fetch the responses for a specific callout. The transformer needs the
* callout's response view schema to determine how to transform the responses.
Expand Down
28 changes: 26 additions & 2 deletions apps/backend/src/api/transformers/CalloutResponseTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import {
} from "@beabee/core/models";

import { AuthInfo } from "@beabee/core/type";
import { RuleGroup } from "@beabee/beabee-common";
import { getReviewerRules } from "@api/utils";

export class CalloutResponseTransformer extends BaseCalloutResponseTransformer<
GetCalloutResponseDto,
Expand Down Expand Up @@ -80,14 +82,36 @@ export class CalloutResponseTransformer extends BaseCalloutResponseTransformer<
};
}

protected async getNonAdminAuthRules(
auth: AuthInfo,
query: GetCalloutResponseOptsDto
): Promise<RuleGroup> {
const reviewerRules = await getReviewerRules(auth.contact, "calloutId");

// This is a hacky way to pass the reviewer status to modifyQueryBuilder
query.isReviewer = reviewerRules.length > 0;

return {
condition: "OR",
rules: [
// User's can always see their own responses
{ field: "contact", operator: "equal", value: ["me"] },
// And any responses for callouts they are reviewers for
...reviewerRules
]
};
}

protected modifyQueryBuilder(
qb: SelectQueryBuilder<CalloutResponse>,
fieldPrefix: string,
query: ListCalloutResponsesDto,
auth: AuthInfo
): void {
// TODO: Add auth check for assignee
if (query.with?.includes(GetCalloutResponseWith.Assignee)) {
if (
query.with?.includes(GetCalloutResponseWith.Assignee) &&
(query.isReviewer || auth.roles.includes("admin"))
) {
qb.leftJoinAndSelect(`${fieldPrefix}assignee`, "assignee");
}
if (query.with?.includes(GetCalloutResponseWith.Callout)) {
Expand Down

0 comments on commit 3ef707f

Please sign in to comment.