Skip to content

Commit

Permalink
chore(upload-notes): add endpoint for view authz
Browse files Browse the repository at this point in the history
  • Loading branch information
ztdevelops committed Apr 27, 2024
1 parent 40eca87 commit 5ba2af5
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 21 deletions.
10 changes: 10 additions & 0 deletions backend/complex/view-notes/protos/view_notes.proto
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,21 @@ message ViewNotesByTopicAndNameResponse {
repeated notes.NotePreview notes = 2;
}

message CanViewNoteRequest {
string user_id = 1;
string note_id = 2;
}

message CanViewNoteResponse {
bool can_view = 1;
}

service ViewNotes {
rpc ViewOneNote (ViewOneNoteRequest) returns (NoteAndContent);
rpc ViewAllNotes (ViewAllNotesRequest) returns (ViewAllNotesResponse);
rpc ViewNotesByUserId (ViewNotesByUserIdRequest) returns (ViewNotesByUserIdResponse);
rpc ViewSavedNotesByUserId (ViewNotesByUserIdRequest) returns (ViewNotesByUserIdResponse);
rpc ViewSavedNotes (ViewSavedNotesRequest) returns (ViewSavedNotesResponse);
rpc ViewNotesByTopicAndName (ViewNotesByTopicAndNameRequest) returns (ViewNotesByTopicAndNameResponse);
rpc CanViewNote (CanViewNoteRequest) returns (CanViewNoteResponse);
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,27 @@ def ViewNotesByTopicAndName(self, request, context):
grpc.StatusCode.INVALID_ARGUMENT,
e
)

def CanViewNote(self, request, context):
response = view_notes_pb2.CanViewNoteResponse()
try:
note_id = request.note_id
user_id = request.user_id

logging.info(f'Checking if user {user_id} can view note {note_id}')


notes_stub = notes_client.NotesClient().get_notes_stub()
note_metadata_request = notes_pb2.RetrieveNoteMetadataRequest()
note_metadata_request.fileId = note_id
note_metadata_response = notes_stub.RetrieveNoteMetadata(note_metadata_request)
response.can_view = note_metadata_response.noteMetadata.userId == user_id

return response

except Exception as e:
error_utils.handle_error(
context,
'Error checking if user can view note',
grpc.StatusCode.INVALID_ARGUMENT,
e
)
16 changes: 16 additions & 0 deletions backend/kong-gateway/protos/view_notes.proto
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ message ViewNotesByTopicAndNameResponse {
repeated notes.NotePreview notes = 2;
}

message CanViewNoteRequest {
string user_id = 1;
string note_id = 2;
}

message CanViewNoteResponse {
bool can_view = 1;
}

service ViewNotes {
rpc ViewOneNote (ViewOneNoteRequest) returns (NoteAndContent) {
option (google.api.http) = {
Expand Down Expand Up @@ -116,4 +125,11 @@ service ViewNotes {
body: "*"
};
};

rpc CanViewNote (CanViewNoteRequest) returns (CanViewNoteResponse) {
option (google.api.http) = {
post: "/api/v1/notes/allowed"
body: "*"
};
};
}
25 changes: 25 additions & 0 deletions client/src/features/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,3 +437,28 @@ export const getSavedNotesWithFilter = async (
console.log(error);
}
};

export const canViewNote = async (
authorization: string,
userId: string,
noteId: string
) => {
try {
const response = await api.post(
"/api/v1/notes/allowed",
{
user_id: userId,
note_id: noteId,
},
{
headers: {
Authorization: `Bearer ${authorization}`
}
}
)

return response.data;
} catch (error) {
console.log(error);
}
};
32 changes: 12 additions & 20 deletions client/src/pages/notes/GeneratedContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ import {
import { isFlashcardType } from "~shared/util";

import {
api,
commitTemporaryContents,
createTemporaryContent,
deleteTemporaryContent,
getTemporaryContents,
getTopics,
updateTemporaryContent,
canViewNote,
} from "~features/api";
import { useAuth } from "~features/auth";

Expand Down Expand Up @@ -64,7 +64,6 @@ const GeneratedContent: React.FC = () => {
const filename = localStorage.getItem("filename") || "No file uploaded";
const [isLoading, setIsLoading] = useState(true);

const [userNotes, setUserNotes] = useState([]);
const [isAuthorized, setIsAuthorized] = useState(false);
const pulseAnimation = keyframes`
0% { opacity: 0.5; }
Expand All @@ -75,14 +74,8 @@ const GeneratedContent: React.FC = () => {
useEffect(() => {
const checkAuthorization = async () => {
try {
const notes = await fetchUserNotes(user?.user_id);
setUserNotes(notes.notes);
userNotes;
isAuthorized;
const noteExists = notes.notes.some(
(note: any) => note.fileId === noteId,
);
if (!noteExists) {
const userCanView = await userCanViewNote(noteId, authorization);
if (!userCanView) {
toast({
title: "Unauthorized",
description: "You do not have access to this note.",
Expand Down Expand Up @@ -143,17 +136,16 @@ const GeneratedContent: React.FC = () => {
clearInterval(intervalIdRef.current as ReturnType<typeof setInterval>); // Clean up on component unmount
}, [noteId, authorization, isAuthorized]);

const fetchUserNotes = async (userId: any) => {
const response = await api.get(`/api/v1/notes/user/${userId}`, {
headers: {
Authorization: `Bearer ${authorization}`,
},
});
if (!response.data) {
throw new Error("Failed to fetch notes");
const userCanViewNote = async (
noteId: string | undefined,
authorization: string | null,
) => {
if (!noteId || !authorization || !user) {
return;
}
console.log(response);
return await response.data;

const response = await canViewNote(authorization, user.user_id, noteId);
return response.can_view;
};

const handleGetTemporaryContents = async (
Expand Down

0 comments on commit 5ba2af5

Please sign in to comment.