@@ -1800,6 +1800,8 @@ async def process_text(
18001800 collection_name = form_data .collection_name
18011801 if collection_name is None :
18021802 collection_name = calculate_sha256_string (form_data .content )
1803+ else :
1804+ await _validate_collection_access ([collection_name ], user , access_type = 'write' )
18031805
18041806 docs = [
18051807 Document (
@@ -1841,6 +1843,8 @@ async def process_web(
18411843 collection_name = form_data .collection_name
18421844 if not collection_name :
18431845 collection_name = calculate_sha256_string (form_data .url )[:63 ]
1846+ else :
1847+ await _validate_collection_access ([collection_name ], user , access_type = 'write' )
18441848
18451849 if not request .app .state .config .BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL :
18461850 await run_in_threadpool (
@@ -2344,17 +2348,25 @@ async def search_query_with_semaphore(query):
23442348 )
23452349
23462350
2347- async def _validate_collection_access (collection_names : list [str ], user ) -> None :
2351+ async def _validate_collection_access (collection_names : list [str ], user , access_type : str = 'read' ) -> None :
23482352 """
2349- Prevent users from querying collections they don't own.
2350- Enforces ownership on user-memory-* and file-* collections.
2353+ Prevent users from accessing collections they don't own.
2354+ Enforces ownership on user-memory-*, file-*, and knowledge-base collections.
23512355 Admins bypass this check.
23522356 """
23532357 if user .role == 'admin' :
23542358 return
23552359
23562360 for name in collection_names :
2357- if name .startswith ('user-memory-' ) and name != f'user-memory-{ user .id } ' :
2361+ # The 'knowledge-bases' meta-collection stores embedded metadata
2362+ # (names, descriptions, UUIDs) for every KB in the instance.
2363+ # Querying it would let any user enumerate all knowledge bases.
2364+ if name == 'knowledge-bases' :
2365+ raise HTTPException (
2366+ status_code = status .HTTP_403_FORBIDDEN ,
2367+ detail = ERROR_MESSAGES .ACCESS_PROHIBITED ,
2368+ )
2369+ elif name .startswith ('user-memory-' ) and name != f'user-memory-{ user .id } ' :
23582370 raise HTTPException (
23592371 status_code = status .HTTP_403_FORBIDDEN ,
23602372 detail = ERROR_MESSAGES .ACCESS_PROHIBITED ,
@@ -2363,13 +2375,25 @@ async def _validate_collection_access(collection_names: list[str], user) -> None
23632375 file_id = name [len ('file-' ) :]
23642376 if not await has_access_to_file (
23652377 file_id = file_id ,
2366- access_type = 'read' ,
2378+ access_type = access_type ,
23672379 user = user ,
23682380 ):
23692381 raise HTTPException (
23702382 status_code = status .HTTP_403_FORBIDDEN ,
23712383 detail = ERROR_MESSAGES .ACCESS_PROHIBITED ,
23722384 )
2385+ else :
2386+ # Non-prefixed collection names may be knowledge base IDs.
2387+ # Verify the caller has the required permission on the knowledge base.
2388+ knowledge = await Knowledges .get_knowledge_by_id (name )
2389+ if knowledge is not None :
2390+ if not await Knowledges .check_access_by_user_id (
2391+ name , user .id , permission = access_type
2392+ ):
2393+ raise HTTPException (
2394+ status_code = status .HTTP_403_FORBIDDEN ,
2395+ detail = ERROR_MESSAGES .ACCESS_PROHIBITED ,
2396+ )
23732397
23742398
23752399class QueryDocForm (BaseModel ):
0 commit comments