Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ env:
WEAVIATE_125: 1.25.24
WEAVIATE_126: 1.26.8
WEAVIATE_127: 1.27.1
WEAVIATE_128: 1.28.0-rc.0
WEAVIATE_128: 1.28.0-rc.0-ebcc021
jobs:
lint-and-format:
name: Run Linter and Formatter
Expand Down
40 changes: 40 additions & 0 deletions mock_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from weaviate.connect.base import ConnectionParams, ProtocolParams
from weaviate.proto.v1 import (
batch_pb2,
batch_delete_pb2,
properties_pb2,
tenants_pb2,
search_get_pb2,
Expand Down Expand Up @@ -310,3 +311,42 @@ def retries(
service = MockRetriesWeaviateService()
weaviate_pb2_grpc.add_WeaviateServicer_to_server(service, start_grpc_server)
return weaviate_client.collections.get("RetriesCollection"), service


class MockForbiddenWeaviateService(weaviate_pb2_grpc.WeaviateServicer):
def Search(
self, request: search_get_pb2.SearchRequest, context: grpc.ServicerContext
) -> search_get_pb2.SearchReply:
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
context.set_details("Permission denied")
return search_get_pb2.SearchReply()

def TenantsGet(
self, request: tenants_pb2.TenantsGetRequest, context: ServicerContext
) -> tenants_pb2.TenantsGetReply:
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
context.set_details("Permission denied")
return tenants_pb2.TenantsGetReply()

def BatchObjects(
self, request: batch_pb2.BatchObjectsRequest, context: grpc.ServicerContext
) -> batch_pb2.BatchObjectsReply:
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
context.set_details("Permission denied")
return batch_pb2.BatchObjectsReply()

def BatchDelete(
self, request: batch_delete_pb2.BatchDeleteRequest, context: grpc.ServicerContext
) -> batch_delete_pb2.BatchDeleteReply:
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
context.set_details("Permission denied")
return batch_delete_pb2.BatchDeleteReply()


@pytest.fixture(scope="function")
def forbidden(
weaviate_client: weaviate.WeaviateClient, start_grpc_server: grpc.Server
) -> weaviate.collections.Collection:
service = MockForbiddenWeaviateService()
weaviate_pb2_grpc.add_WeaviateServicer_to_server(service, start_grpc_server)
return weaviate_client.collections.get("ForbiddenCollection")
14 changes: 14 additions & 0 deletions mock_tests/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,3 +460,17 @@ def test_grpc_retry_logic(
assert len(tenants) == 1
assert tenants[0].name == "tenant1"
assert service.tenants_count == 2


def test_grpc_forbidden_exception(forbidden: weaviate.collections.Collection) -> None:
with pytest.raises(weaviate.exceptions.InsufficientPermissionsError):
forbidden.query.fetch_objects()

with pytest.raises(weaviate.exceptions.InsufficientPermissionsError):
forbidden.tenants.get()

with pytest.raises(weaviate.exceptions.InsufficientPermissionsError):
forbidden.data.delete_many(where=wvc.query.Filter.by_property("name").equal("test"))

with pytest.raises(weaviate.exceptions.InsufficientPermissionsError):
forbidden.data.insert_many([{"name": "test"}])
4 changes: 3 additions & 1 deletion weaviate/collections/batch/grpc_batch_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from weaviate.collections.grpc.shared import _BaseGRPC
from weaviate.collections.queries.base import _WeaviateUUIDInt
from weaviate.connect import ConnectionV4
from weaviate.exceptions import WeaviateDeleteManyError
from weaviate.exceptions import WeaviateDeleteManyError, InsufficientPermissionsError
from weaviate.proto.v1 import batch_delete_pb2


Expand Down Expand Up @@ -62,4 +62,6 @@ async def batch_delete(
)

except AioRpcError as e:
if e.code().name == "PERMISSION_DENIED":
raise InsufficientPermissionsError(e)
raise WeaviateDeleteManyError(str(e))
3 changes: 3 additions & 0 deletions weaviate/collections/batch/grpc_batch_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
WeaviateInsertInvalidPropertyError,
WeaviateInsertManyAllFailedError,
WeaviateInvalidInputError,
InsufficientPermissionsError,
)
from weaviate.proto.v1 import batch_pb2, base_pb2
from weaviate.util import _datetime_to_string, _get_vector_v4
Expand Down Expand Up @@ -152,6 +153,8 @@ async def __send_batch(
objects[result.index] = result.error
return objects
except AioRpcError as e:
if e.code().name == "PERMISSION_DENIED":
raise InsufficientPermissionsError(e)
raise WeaviateBatchError(str(e)) from e

def __translate_properties_from_python_to_grpc(
Expand Down
7 changes: 6 additions & 1 deletion weaviate/collections/grpc/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
from weaviate.collections.grpc.shared import _BaseGRPC
from weaviate.connect import ConnectionV4
from weaviate.exceptions import (
InsufficientPermissionsError,
WeaviateQueryError,
WeaviateUnsupportedFeatureError,
WeaviateInvalidInputError,
Expand Down Expand Up @@ -810,7 +811,11 @@ async def __call(self, request: search_get_pb2.SearchRequest) -> search_get_pb2.
timeout=self._connection.timeout_config.query,
)
return cast(search_get_pb2.SearchReply, res)
except (AioRpcError, WeaviateRetryError) as e:
except AioRpcError as e:
if e.code().name == "PERMISSION_DENIED":
raise InsufficientPermissionsError(e)
raise WeaviateQueryError(str(e), "GRPC search") # pyright: ignore
except WeaviateRetryError as e:
raise WeaviateQueryError(str(e), "GRPC search") # pyright: ignore

def _metadata_to_grpc(self, metadata: _MetadataQuery) -> search_get_pb2.MetadataRequest:
Expand Down
4 changes: 3 additions & 1 deletion weaviate/collections/grpc/tenants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from weaviate.collections.grpc.retry import _Retry
from weaviate.collections.grpc.shared import _BaseGRPC
from weaviate.connect import ConnectionV4
from weaviate.exceptions import WeaviateTenantGetError
from weaviate.exceptions import WeaviateTenantGetError, InsufficientPermissionsError
from weaviate.proto.v1 import tenants_pb2


Expand Down Expand Up @@ -38,6 +38,8 @@ async def get(self, names: Optional[Sequence[str]]) -> tenants_pb2.TenantsGetRep
timeout=self._connection.timeout_config.query,
)
except AioRpcError as e:
if e.code().name == "PERMISSION_DENIED":
raise InsufficientPermissionsError(e)
raise WeaviateTenantGetError(str(e)) from e

return cast(tenants_pb2.TenantsGetReply, res)
Expand Down
Loading