diff --git a/drive/api/files.py b/drive/api/files.py index 91ea467df..09a0f2890 100644 --- a/drive/api/files.py +++ b/drive/api/files.py @@ -902,23 +902,6 @@ def get_new_title(title, parent_name, folder=False, entity=None): return f"{entity_title} ({len(sibling_entity_titles)}){entity_ext}" -@frappe.whitelist(allow_guest=True) -def get_entity_type(entity_name): - entity = frappe.db.get_value( - "Drive File", - {"is_active": 1, "name": entity_name}, - ["team", "name", "mime_type", "is_group", "document"], - as_dict=1, - ) - if entity.document or entity.mime_type == "text/markdown": - entity["type"] = "document" - elif entity.is_group: - entity["type"] = "folder" - else: - entity["type"] = "file" - return entity - - @frappe.whitelist() def get_root_folder(team): if team not in get_teams(): diff --git a/drive/api/permissions.py b/drive/api/permissions.py index b2be7906b..bab665a78 100644 --- a/drive/api/permissions.py +++ b/drive/api/permissions.py @@ -137,7 +137,10 @@ def get_teams(user=None, details=None, exclude_personal=True): @frappe.whitelist(allow_guest=True) def get_entity_with_permissions(entity_name): """ - Return file data with permissions + Return file data with permissions. Validates that the request path matches + the entity type and returns redirect information if there's a mismatch. + + :param entity_name: Name of the entity to fetch """ entity = frappe.db.get_value( "Drive File", @@ -148,6 +151,45 @@ def get_entity_with_permissions(entity_name): if not entity: frappe.throw("We couldn't find what you're looking for.", {"error": frappe.NotFound}) + # Determine actual entity type using get_file_type + file_type = get_file_type(entity) + + # Map file_type to route type (Document, Folder, or anything else is file) + if file_type == "Folder": + actual_type = "folder" + elif file_type in ["Document", "Frappe Document"]: + actual_type = "document" + else: + actual_type = "file" + + request_path = frappe.request.path + expected_type = None + + if "/w/" in request_path: + expected_type = "document" + elif "/d/" in request_path: + expected_type = "folder" + elif "/f/" in request_path: + expected_type = "file" + + # Check if type matches expected type and return redirect if mismatch + if expected_type and expected_type != actual_type: + route_map = { + "folder": f"/d/{entity_name}", + "document": f"/w/{entity_name}", + "file": f"/f/{entity_name}", + } + correct_route = route_map.get(actual_type) + if correct_route: + return { + "redirect": True, + "route": correct_route, + "entity_type": actual_type, + "expected_type": expected_type + } + # If no valid route found, throw error + frappe.throw("Invalid entity type.", frappe.ValidationError) + entity["in_home"] = entity.team == get_default_team() user_access = get_user_access(entity) if user_access.get("read") == 0: diff --git a/frontend/src/pages/Document.vue b/frontend/src/pages/Document.vue index c15b4b4ce..f6de72054 100644 --- a/frontend/src/pages/Document.vue +++ b/frontend/src/pages/Document.vue @@ -284,7 +284,13 @@ const document = createResource({ params: { entity_name: props.entityName, }, - onSuccess, + onSuccess(data) { + if (data.redirect) { + router.push(data.route) + return + } + onSuccess(data) + }, }) store.commit("setCurrentResource", document) diff --git a/frontend/src/pages/File.vue b/frontend/src/pages/File.vue index f32fd83e1..9cfcf6e91 100644 --- a/frontend/src/pages/File.vue +++ b/frontend/src/pages/File.vue @@ -126,11 +126,16 @@ const onSuccess = async (entity) => { const file = createResource({ url: "drive.api.permissions.get_entity_with_permissions", params: { entity_name: props.entityName }, - transform(entity) { - store.commit("setActiveEntity", entity) - return prettyData([entity])[0] + onSuccess(data) { + if (data.redirect) { + router.push(data.route) + return + } + store.commit("setActiveEntity", data) + const prettyEntity = prettyData([data])[0] + file.setData(prettyEntity) + onSuccess(prettyEntity) }, - onSuccess, }) store.commit("setCurrentResource", file) diff --git a/frontend/src/pages/Folder.vue b/frontend/src/pages/Folder.vue index 96546f38e..43be77cea 100644 --- a/frontend/src/pages/Folder.vue +++ b/frontend/src/pages/Folder.vue @@ -53,10 +53,15 @@ const onSuccess = (entity) => { const e = computed(() => props.entityName) const currentFolder = createResource({ url: "drive.api.permissions.get_entity_with_permissions", - transform(entity) { - return prettyData([entity])[0] + onSuccess(data) { + if (data.redirect) { + router.push(data.route) + return + } + const prettyEntity = prettyData([data])[0] + currentFolder.setData(prettyEntity) + onSuccess(prettyEntity) }, - onSuccess, }) store.commit("setCurrentResource", currentFolder) watch(e, (v) => currentFolder.fetch({ entity_name: v }), { immediate: true }) diff --git a/frontend/src/router.js b/frontend/src/router.js index ef539dda7..fe23d33ec 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -111,20 +111,25 @@ const routes = [ component: Dummy, beforeEnter: async (to) => { const entity = createResource({ - url: "/api/method/drive.api.files.get_entity_type", + url: "/api/method/drive.api.permissions.get_entity_with_permissions", method: "GET", params: { entity_name: to.params.entityName, }, }) await entity.fetch() - const letter = { - folder: "d", - document: "w", - file: "f", - }[entity.data.type] + + const file_type = entity.data.file_type + let letter = "f" // default to file + + if (file_type === "Folder") { + letter = "d" + } else if (file_type === "Document" || file_type === "Frappe Document") { + letter = "w" + } + return { - path: `/${letter}/${entity.data.name}`, + path: `/${letter}/${to.params.entityName}`, } }, }, @@ -156,8 +161,8 @@ const routes = [ name: "Document", meta: { documentPage: true, allowGuest: true }, component: () => import("@/pages/Document.vue"), - props: true, beforeEnter: [manageBreadcrumbs], + props: true, }, ]