Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permission checks for pages #166

Merged
merged 28 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
aac96e9
generic permission middleware
reyniersbram May 2, 2024
8e56508
placeholder middleware implementations
reyniersbram May 3, 2024
d822806
implement isAdmin check
reyniersbram May 3, 2024
f6d7d47
permissions on admin page + fix typo
reyniersbram May 3, 2024
19ff140
logical functions for conditions
reyniersbram May 3, 2024
1476e65
pass MiddlewareContext to conditions
reyniersbram May 3, 2024
f59fc16
permission to check if user is part of subject
reyniersbram May 3, 2024
d717c72
permission to check if user can create a project for a subject
reyniersbram May 3, 2024
f876ce1
run formatter
reyniersbram May 3, 2024
f65f4f4
Merge branch 'dev' into permission-middleware
reyniersbram May 17, 2024
2650564
restructure navigation guard middlewares
reyniersbram May 17, 2024
bcc0dc8
subject details permissions
reyniersbram May 18, 2024
3338bf0
project details permissions
reyniersbram May 18, 2024
8df7655
go to /not-found instead of /forbidden
reyniersbram May 18, 2024
50bf7e6
create project permissions
reyniersbram May 18, 2024
a5ec037
Merge branch 'dev' into permission-middleware
reyniersbram May 19, 2024
de7589b
fix project permission checks
reyniersbram May 19, 2024
9f997b7
permissions for submit page
reyniersbram May 19, 2024
ceb7f4c
permissions for groups overview
reyniersbram May 20, 2024
7fabb6e
Merge branch 'dev' into permission-middleware
reyniersbram May 20, 2024
47a0ee1
permissions for group details
reyniersbram May 20, 2024
5e7f10c
permissions for submission list of project
reyniersbram May 20, 2024
1c92def
remove unused imports
reyniersbram May 20, 2024
7a34f88
Apply suggestions from code review
reyniersbram May 20, 2024
3a291c9
Merge branch 'dev' into permission-middleware
reyniersbram May 21, 2024
ff7545e
Merge branch 'dev' into permission-middleware
reyniersbram May 22, 2024
1aa668e
permissions for new pages
reyniersbram May 22, 2024
ade32df
allow admins to visit all pages
reyniersbram May 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions frontend/src/composables/useIsAdmin.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { computed } from "vue";
import { useCurrentUserQuery } from "@/queries/User";
import type { QueryClient } from "@tanstack/vue-query";

export default function useIsAdmin() {
const { data: user } = useCurrentUserQuery();
export default function useIsAdmin(queryClient?: QueryClient) {
const { data: user, isLoading } = useCurrentUserQuery(queryClient);
const isAdmin = computed(() => user.value?.is_admin || false);
return { isAdmin };
return { isAdmin, isLoading };
}
7 changes: 4 additions & 3 deletions frontend/src/composables/useIsTeacher.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { computed } from "vue";
import { useCurrentUserQuery } from "@/queries/User";
import type { QueryClient } from "@tanstack/vue-query";

export default function useIsTeacher() {
const { data: user } = useCurrentUserQuery();
export default function useIsTeacher(queryClient?: QueryClient) {
const { data: user, isLoading } = useCurrentUserQuery(queryClient);
const isTeacher = computed(() => user.value?.is_teacher || false);
return { isTeacher };
return { isTeacher, isLoading };
}
7 changes: 5 additions & 2 deletions frontend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import "@mdi/font/css/materialdesignicons.css";

import { createApp } from "vue";
import { createPinia } from "pinia";
import { VueQueryPlugin } from "@tanstack/vue-query";
import { VueQueryPlugin, QueryClient } from "@tanstack/vue-query";

import App from "./App.vue";
import router from "./router";
Expand All @@ -16,10 +16,13 @@ const app = createApp(App);

const pinia = createPinia();

const queryClient = new QueryClient();
app.provide("queryClient", queryClient);

app.use(router);
app.use(pinia);
app.use(vuetify);
app.use(i18n);
app.use(VueQueryPlugin);
app.use(VueQueryPlugin, { queryClient });

app.mount("#app");
58 changes: 36 additions & 22 deletions frontend/src/queries/Group.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { computed, toValue } from "vue";
import type { MaybeRefOrGetter } from "vue";
import { useMutation, useQuery, useQueryClient } from "@tanstack/vue-query";
import type { UseMutationReturnType, UseQueryReturnType } from "@tanstack/vue-query";
import type { QueryClient, UseMutationReturnType, UseQueryReturnType } from "@tanstack/vue-query";
import type Group from "@/models/Group";
import type { GroupForm } from "@/models/Group";
import {
Expand Down Expand Up @@ -38,26 +38,34 @@ function PROJECT_USER_GROUP_QUERY_KEY(projectId: number): (string | number)[] {
* Query composable for fetching a group by id
*/
export function useGroupQuery(
groupId: MaybeRefOrGetter<number | undefined>
groupId: MaybeRefOrGetter<number | undefined>,
queryClient?: QueryClient
): UseQueryReturnType<Group, Error> {
return useQuery<Group, Error>({
queryKey: GROUP_QUERY_KEY(toValue(groupId)!),
queryFn: () => getGroup(toValue(groupId)!),
enabled: () => !!toValue(groupId),
});
return useQuery<Group, Error>(
{
queryKey: GROUP_QUERY_KEY(toValue(groupId)!),
queryFn: () => getGroup(toValue(groupId)!),
enabled: () => !!toValue(groupId),
},
queryClient
);
}

/**
* Query composable for fetching all groups of a project
*/
export function useProjectGroupsQuery(
projectId: MaybeRefOrGetter<number | undefined>
projectId: MaybeRefOrGetter<number | undefined>,
queryClient?: QueryClient
): UseQueryReturnType<Group[], Error> {
return useQuery<Group[], Error>({
queryKey: computed(() => PROJECT_GROUPS_QUERY_KEY(toValue(projectId)!)),
queryFn: () => getProjectGroups(toValue(projectId)!),
enabled: !!toValue(projectId),
});
return useQuery<Group[], Error>(
{
queryKey: computed(() => PROJECT_GROUPS_QUERY_KEY(toValue(projectId)!)),
queryFn: () => getProjectGroups(toValue(projectId)!),
enabled: !!toValue(projectId),
},
queryClient
);
}

export function useUserGroupsQuery(): UseQueryReturnType<Group[], Error> {
Expand All @@ -73,20 +81,26 @@ export function useUserGroupsQuery(): UseQueryReturnType<Group[], Error> {
* @returns The group the user is in for the project, undefined if the user is not in a group
*/
export function useProjectGroupQuery(
projectId: MaybeRefOrGetter<number | undefined>
projectId: MaybeRefOrGetter<number | undefined>,
queryClient?: QueryClient
): UseQueryReturnType<Group | null, Error> {
const { data: projectGroups } = useProjectGroupsQuery(projectId);
const { data: user } = useCurrentUserQuery();
const userGroup = computed(
() =>
const { data: projectGroups } = useProjectGroupsQuery(projectId, queryClient);
const { data: user } = useCurrentUserQuery(queryClient);
const userGroup = computed(() => {
if (projectGroups.value === undefined || user.value === undefined) return undefined;
return (
projectGroups.value?.find((group) =>
group.members.some((member) => member.uid === user.value?.uid)
) || null
);
return useQuery({
queryKey: computed(() => PROJECT_USER_GROUP_QUERY_KEY(toValue(projectId)!)),
queryFn: () => userGroup,
);
});
return useQuery(
{
queryKey: computed(() => PROJECT_USER_GROUP_QUERY_KEY(toValue(projectId)!)),
queryFn: () => userGroup,
},
queryClient
);
}

/**
Expand Down
33 changes: 21 additions & 12 deletions frontend/src/queries/Project.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { computed, toValue } from "vue";
import type { MaybeRefOrGetter } from "vue";
import { useMutation, useQuery, useQueryClient } from "@tanstack/vue-query";
import type { UseMutationReturnType, UseQueryReturnType } from "@tanstack/vue-query";
import type { QueryClient, UseMutationReturnType, UseQueryReturnType } from "@tanstack/vue-query";
import type { ProjectForm, UserProjectList } from "@/models/Project";
import type Project from "@/models/Project";
import {
Expand Down Expand Up @@ -31,23 +31,32 @@ function TEST_FILES_QUERY_KEY(projectId: number): (string | number)[] {

// Hook for fetching project details
export function useProjectQuery(
projectId: MaybeRefOrGetter<number | undefined>
projectId: MaybeRefOrGetter<number | undefined>,
queryClient?: QueryClient
): UseQueryReturnType<Project, Error> {
return useQuery<Project, Error>({
queryKey: computed(() => PROJECT_QUERY_KEY(toValue(projectId)!)),
queryFn: () => getProject(toValue(projectId)!),
enabled: () => !!toValue(projectId),
});
return useQuery<Project, Error>(
{
queryKey: computed(() => PROJECT_QUERY_KEY(toValue(projectId)!)),
queryFn: () => getProject(toValue(projectId)!),
enabled: () => !!toValue(projectId),
},
queryClient
);
}

/**
* Query composable for fetching all projects of the current user
*/
export function useProjectsQuery(): UseQueryReturnType<UserProjectList, Error> {
return useQuery<UserProjectList>({
queryKey: PROJECTS_QUERY_KEY(),
queryFn: getProjects,
});
export function useProjectsQuery(
queryClient?: QueryClient
): UseQueryReturnType<UserProjectList, Error> {
return useQuery<UserProjectList>(
{
queryKey: PROJECTS_QUERY_KEY(),
queryFn: getProjects,
},
queryClient
);
}

/**
Expand Down
17 changes: 11 additions & 6 deletions frontend/src/queries/Subject.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { computed, toValue } from "vue";
import type { MaybeRefOrGetter } from "vue";
import { useMutation, useQuery, useQueryClient } from "@tanstack/vue-query";
import type { UseQueryReturnType, UseMutationReturnType } from "@tanstack/vue-query";
import type { UseQueryReturnType, UseMutationReturnType, QueryClient } from "@tanstack/vue-query";
import {
getSubject,
getSubjectInstructors,
Expand Down Expand Up @@ -74,11 +74,16 @@ export function useSubjectUuidQuery(
/**
* Query composable for fetching all subjects of the current user
*/
export function useSubjectsQuery(): UseQueryReturnType<UserSubjectList, Error> {
return useQuery<UserSubjectList, Error>({
queryKey: SUBJECTS_QUERY_KEY(),
queryFn: getSubjects,
});
export function useSubjectsQuery(
queryClient?: QueryClient
): UseQueryReturnType<UserSubjectList, Error> {
return useQuery<UserSubjectList, Error>(
{
queryKey: SUBJECTS_QUERY_KEY(),
queryFn: getSubjects,
},
queryClient
);
}

/**
Expand Down
15 changes: 9 additions & 6 deletions frontend/src/queries/User.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { computed, toValue } from "vue";
import type { MaybeRefOrGetter } from "vue";
import { useQuery, useMutation, useQueryClient } from "@tanstack/vue-query";
import type { UseQueryReturnType, UseMutationReturnType } from "@tanstack/vue-query";
import type { UseQueryReturnType, UseMutationReturnType, QueryClient } from "@tanstack/vue-query";
import type User from "@/models/User";
import {
getCurrentUser,
Expand All @@ -27,11 +27,14 @@
/**
* Query composable for fetching the current user
*/
export function useCurrentUserQuery(): UseQueryReturnType<User, Error> {
return useQuery<User, Error>({
queryKey: CURRENT_USER_QUERY_KEY(),
queryFn: () => getCurrentUser(),
});
export function useCurrentUserQuery(queryClient?: QueryClient): UseQueryReturnType<User, Error> {
return useQuery<User, Error>(
{
queryKey: CURRENT_USER_QUERY_KEY(),
queryFn: () => getCurrentUser(),
},
queryClient
);
}

/**
Expand Down Expand Up @@ -85,7 +88,7 @@
});
return { previousUsers: users || [] };
},
onSettled: (_, __, uid, ctx) => {

Check warning on line 91 in frontend/src/queries/User.ts

View workflow job for this annotation

GitHub Actions / Run linters

'_' is defined but never used

Check warning on line 91 in frontend/src/queries/User.ts

View workflow job for this annotation

GitHub Actions / Run linters

'__' is defined but never used

Check warning on line 91 in frontend/src/queries/User.ts

View workflow job for this annotation

GitHub Actions / Run linters

'uid' is defined but never used

Check warning on line 91 in frontend/src/queries/User.ts

View workflow job for this annotation

GitHub Actions / Run linters

'ctx' is defined but never used
queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEY() });
},
onError: (_, uid, ctx) => {
Expand Down Expand Up @@ -146,7 +149,7 @@
});
return { previousUsers: users || [] };
},
onSettled: (_, __, uid, ctx) => {

Check warning on line 152 in frontend/src/queries/User.ts

View workflow job for this annotation

GitHub Actions / Run linters

'_' is defined but never used

Check warning on line 152 in frontend/src/queries/User.ts

View workflow job for this annotation

GitHub Actions / Run linters

'__' is defined but never used

Check warning on line 152 in frontend/src/queries/User.ts

View workflow job for this annotation

GitHub Actions / Run linters

'uid' is defined but never used

Check warning on line 152 in frontend/src/queries/User.ts

View workflow job for this annotation

GitHub Actions / Run linters

'ctx' is defined but never used
queryClient.invalidateQueries({ queryKey: USERS_QUERY_KEY() });
},
onError: (err, uid, ctx) => {
Expand Down
Loading
Loading