Skip to content

Commit 44869ab

Browse files
committed
fix: only show valid organizations in CreateTemplateForm
hide any organizations that the user might have view permissions for, but not permission to create a template
1 parent b80d995 commit 44869ab

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

site/src/components/OrganizationAutocomplete/OrganizationAutocomplete.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import {
99
useState,
1010
} from "react";
1111
import { useQuery } from "react-query";
12+
import { checkAuthorization } from "api/queries/authCheck";
1213
import { organizations } from "api/queries/organizations";
13-
import type { Organization } from "api/typesGenerated";
14+
import type { AuthorizationCheck, Organization } from "api/typesGenerated";
1415
import { Avatar } from "components/Avatar/Avatar";
1516
import { AvatarData } from "components/AvatarData/AvatarData";
1617
import { useDebouncedFunction } from "hooks/debounce";
@@ -22,6 +23,7 @@ export type OrganizationAutocompleteProps = {
2223
className?: string;
2324
size?: ComponentProps<typeof TextField>["size"];
2425
required?: boolean;
26+
check?: AuthorizationCheck;
2527
};
2628

2729
export const OrganizationAutocomplete: FC<OrganizationAutocompleteProps> = ({
@@ -31,6 +33,7 @@ export const OrganizationAutocomplete: FC<OrganizationAutocompleteProps> = ({
3133
className,
3234
size = "small",
3335
required,
36+
check,
3437
}) => {
3538
const [autoComplete, setAutoComplete] = useState<{
3639
value: string;
@@ -41,6 +44,22 @@ export const OrganizationAutocomplete: FC<OrganizationAutocompleteProps> = ({
4144
});
4245
const organizationsQuery = useQuery(organizations());
4346

47+
const permissionsQuery = useQuery(
48+
check && organizationsQuery.data
49+
? checkAuthorization({
50+
checks: Object.fromEntries(
51+
organizationsQuery.data.map((org) => [
52+
org.id,
53+
{
54+
...check,
55+
object: { ...check.object, organization_id: org.id },
56+
},
57+
]),
58+
),
59+
})
60+
: { enabled: false },
61+
);
62+
4463
const { debounced: debouncedInputOnChange } = useDebouncedFunction(
4564
(event: ChangeEvent<HTMLInputElement>) => {
4665
setAutoComplete((state) => ({
@@ -51,11 +70,18 @@ export const OrganizationAutocomplete: FC<OrganizationAutocompleteProps> = ({
5170
750,
5271
);
5372

73+
// If an authorization check was provided, filter the organizations based on
74+
// the results of that check.
75+
let options = organizationsQuery.data ?? [];
76+
if (check && permissionsQuery.data) {
77+
options = options.filter((org) => permissionsQuery.data[org.id]);
78+
}
79+
5480
return (
5581
<Autocomplete
5682
noOptionsText="No organizations found"
5783
className={className}
58-
options={organizationsQuery.data ?? []}
84+
options={options}
5985
loading={organizationsQuery.isLoading}
6086
value={value}
6187
data-testid="organization-autocomplete"

site/src/contexts/auth/permissions.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export const permissionsToCheck = {
3636
[checks.createTemplates]: {
3737
object: {
3838
resource_type: "template",
39+
any_org: true,
3940
},
4041
action: "update",
4142
},

site/src/pages/CreateTemplatePage/CreateTemplateForm.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,10 @@ export const CreateTemplateForm: FC<CreateTemplateFormProps> = (props) => {
267267
void form.setFieldValue("organization", newValue?.name || "");
268268
}}
269269
size="medium"
270+
check={{
271+
object: { resource_type: "template" },
272+
action: "create",
273+
}}
270274
/>
271275
</>
272276
)}

0 commit comments

Comments
 (0)