mirror of
https://github.com/QuivrHQ/quivr.git
synced 2024-09-11 14:36:35 +03:00
feat: check user role on brain before file upload (#709)
This commit is contained in:
parent
87458d8de1
commit
aa7bc483c2
@ -10,6 +10,11 @@ from models.users import User
|
||||
from utils.file import convert_bytes, get_file_size
|
||||
from utils.processors import filter_file
|
||||
|
||||
from routes.authorizations.brain_authorization import (
|
||||
RoleEnum,
|
||||
validate_brain_authorization,
|
||||
)
|
||||
|
||||
upload_router = APIRouter()
|
||||
|
||||
|
||||
@ -33,8 +38,10 @@ async def upload_file(
|
||||
and ensures that the file size does not exceed the maximum capacity. If the file is within the allowed size limit,
|
||||
it can optionally apply summarization to the file's content. The response message will indicate the status of the upload.
|
||||
"""
|
||||
validate_brain_authorization(
|
||||
brain_id, current_user.id, [RoleEnum.Editor, RoleEnum.Owner]
|
||||
)
|
||||
|
||||
# [TODO] check if the user is the owner/editor of the brain
|
||||
brain = Brain(id=brain_id)
|
||||
commons = common_dependencies()
|
||||
|
||||
|
@ -7,6 +7,7 @@ import { useSupabase } from "@/lib/context/SupabaseProvider";
|
||||
import { useAxios, useToast } from "@/lib/hooks";
|
||||
import { redirectToLogin } from "@/lib/router/redirectToLogin";
|
||||
import { useEventTracking } from "@/services/analytics/useEventTracking";
|
||||
import axios from "axios";
|
||||
import { UUID } from "crypto";
|
||||
|
||||
export const useFileUploader = () => {
|
||||
@ -41,11 +42,24 @@ export const useFileUploader = () => {
|
||||
? "File uploaded successfully: "
|
||||
: "") + JSON.stringify(response.data.message),
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
publish({
|
||||
variant: "danger",
|
||||
text: "Failed to upload file: " + JSON.stringify(error),
|
||||
});
|
||||
} catch (e: unknown) {
|
||||
if (axios.isAxiosError(e) && e.response?.status === 403) {
|
||||
publish({
|
||||
variant: "danger",
|
||||
text: `${JSON.stringify(
|
||||
(
|
||||
e.response as {
|
||||
data: { detail: string };
|
||||
}
|
||||
).data.detail
|
||||
)}`,
|
||||
});
|
||||
} else {
|
||||
publish({
|
||||
variant: "danger",
|
||||
text: "Failed to upload file: " + JSON.stringify(e),
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
[session.access_token, publish]
|
||||
@ -85,8 +99,8 @@ export const useFileUploader = () => {
|
||||
}
|
||||
setIsPending(true);
|
||||
if (currentBrain?.id !== undefined) {
|
||||
setFiles([]);
|
||||
await Promise.all(files.map((file) => upload(file, currentBrain?.id)));
|
||||
setFiles([]);
|
||||
} else {
|
||||
publish({
|
||||
text: "Please, select or create a brain to upload a file",
|
||||
|
@ -6,10 +6,47 @@ import Button from "@/lib/components/ui/Button";
|
||||
import { Divider } from "@/lib/components/ui/Divider";
|
||||
import PageHeading from "@/lib/components/ui/PageHeading";
|
||||
|
||||
import { BrainRoleType } from "@/lib/components/NavBar/components/NavItems/components/BrainsDropDown/components/BrainActions/types";
|
||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||
import { Crawler } from "./components/Crawler";
|
||||
import { FileUploader } from "./components/FileUploader";
|
||||
|
||||
const requiredRolesForUpload: BrainRoleType[] = ["Editor", "Owner"];
|
||||
|
||||
const UploadPage = (): JSX.Element => {
|
||||
const { currentBrain } = useBrainContext();
|
||||
|
||||
if (currentBrain === undefined) {
|
||||
return (
|
||||
<div className="flex justify-center items-center mt-5">
|
||||
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative max-w-md">
|
||||
<strong className="font-bold mr-1">Oh no!</strong>
|
||||
<span className="block sm:inline">
|
||||
You need to select a brain first. 🧠💡🥲
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const hasUploadRights =
|
||||
currentBrain?.rights !== undefined &&
|
||||
requiredRolesForUpload.includes(currentBrain?.rights);
|
||||
|
||||
if (!hasUploadRights) {
|
||||
return (
|
||||
<div className="flex justify-center items-center mt-5">
|
||||
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative max-w-md">
|
||||
<strong className="font-bold mr-1">Oh no!</strong>
|
||||
<span className="block sm:inline">
|
||||
You don't have the necessary rights to upload content to the
|
||||
selected brain. 🧠💡🥲
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="pt-10">
|
||||
<PageHeading
|
||||
|
Loading…
Reference in New Issue
Block a user