Skip to content

Commit d6645b6

Browse files
authored
Merge pull request #1464 from weaviate/1.28/raise-insufficient-perms-err-in-grpc
Check status code of gRPC message to throw insuf perms err
2 parents 3763f29 + 532112f commit d6645b6

File tree

8 files changed

+76
-8
lines changed

8 files changed

+76
-8
lines changed

.github/workflows/main.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ env:
1717
WEAVIATE_125: 1.25.24
1818
WEAVIATE_126: 1.26.8
1919
WEAVIATE_127: 1.27.1
20-
WEAVIATE_128: 1.28.0-rc.0
20+
WEAVIATE_128: 1.28.0-rc.0-ebcc021
2121
jobs:
2222
lint-and-format:
2323
name: Run Linter and Formatter

mock_tests/conftest.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from weaviate.connect.base import ConnectionParams, ProtocolParams
1616
from weaviate.proto.v1 import (
1717
batch_pb2,
18+
batch_delete_pb2,
1819
properties_pb2,
1920
tenants_pb2,
2021
search_get_pb2,
@@ -310,3 +311,42 @@ def retries(
310311
service = MockRetriesWeaviateService()
311312
weaviate_pb2_grpc.add_WeaviateServicer_to_server(service, start_grpc_server)
312313
return weaviate_client.collections.get("RetriesCollection"), service
314+
315+
316+
class MockForbiddenWeaviateService(weaviate_pb2_grpc.WeaviateServicer):
317+
def Search(
318+
self, request: search_get_pb2.SearchRequest, context: grpc.ServicerContext
319+
) -> search_get_pb2.SearchReply:
320+
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
321+
context.set_details("Permission denied")
322+
return search_get_pb2.SearchReply()
323+
324+
def TenantsGet(
325+
self, request: tenants_pb2.TenantsGetRequest, context: ServicerContext
326+
) -> tenants_pb2.TenantsGetReply:
327+
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
328+
context.set_details("Permission denied")
329+
return tenants_pb2.TenantsGetReply()
330+
331+
def BatchObjects(
332+
self, request: batch_pb2.BatchObjectsRequest, context: grpc.ServicerContext
333+
) -> batch_pb2.BatchObjectsReply:
334+
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
335+
context.set_details("Permission denied")
336+
return batch_pb2.BatchObjectsReply()
337+
338+
def BatchDelete(
339+
self, request: batch_delete_pb2.BatchDeleteRequest, context: grpc.ServicerContext
340+
) -> batch_delete_pb2.BatchDeleteReply:
341+
context.set_code(grpc.StatusCode.PERMISSION_DENIED)
342+
context.set_details("Permission denied")
343+
return batch_delete_pb2.BatchDeleteReply()
344+
345+
346+
@pytest.fixture(scope="function")
347+
def forbidden(
348+
weaviate_client: weaviate.WeaviateClient, start_grpc_server: grpc.Server
349+
) -> weaviate.collections.Collection:
350+
service = MockForbiddenWeaviateService()
351+
weaviate_pb2_grpc.add_WeaviateServicer_to_server(service, start_grpc_server)
352+
return weaviate_client.collections.get("ForbiddenCollection")

mock_tests/test_collection.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,3 +460,17 @@ def test_grpc_retry_logic(
460460
assert len(tenants) == 1
461461
assert tenants[0].name == "tenant1"
462462
assert service.tenants_count == 2
463+
464+
465+
def test_grpc_forbidden_exception(forbidden: weaviate.collections.Collection) -> None:
466+
with pytest.raises(weaviate.exceptions.InsufficientPermissionsError):
467+
forbidden.query.fetch_objects()
468+
469+
with pytest.raises(weaviate.exceptions.InsufficientPermissionsError):
470+
forbidden.tenants.get()
471+
472+
with pytest.raises(weaviate.exceptions.InsufficientPermissionsError):
473+
forbidden.data.delete_many(where=wvc.query.Filter.by_property("name").equal("test"))
474+
475+
with pytest.raises(weaviate.exceptions.InsufficientPermissionsError):
476+
forbidden.data.insert_many([{"name": "test"}])

weaviate/collections/batch/grpc_batch_delete.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
from weaviate.collections.classes.config import ConsistencyLevel
1010
from weaviate.collections.classes.filters import _Filters
1111
from weaviate.collections.filters import _FilterToGRPC
12-
from weaviate.collections.grpc.shared import _BaseGRPC
12+
from weaviate.collections.grpc.shared import _BaseGRPC, PERMISSION_DENIED
1313
from weaviate.collections.queries.base import _WeaviateUUIDInt
1414
from weaviate.connect import ConnectionV4
15-
from weaviate.exceptions import WeaviateDeleteManyError
15+
from weaviate.exceptions import WeaviateDeleteManyError, InsufficientPermissionsError
1616
from weaviate.proto.v1 import batch_delete_pb2
1717

1818

@@ -62,4 +62,6 @@ async def batch_delete(
6262
)
6363

6464
except AioRpcError as e:
65+
if e.code().name == PERMISSION_DENIED:
66+
raise InsufficientPermissionsError(e)
6567
raise WeaviateDeleteManyError(str(e))

weaviate/collections/batch/grpc_batch_objects.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
from weaviate.collections.classes.config import ConsistencyLevel
1616
from weaviate.collections.classes.internal import ReferenceToMulti, ReferenceInputs
1717
from weaviate.collections.classes.types import GeoCoordinate, PhoneNumber
18-
from weaviate.collections.grpc.shared import _BaseGRPC
18+
from weaviate.collections.grpc.shared import _BaseGRPC, PERMISSION_DENIED
1919
from weaviate.connect import ConnectionV4
2020
from weaviate.exceptions import (
2121
WeaviateBatchError,
2222
WeaviateInsertInvalidPropertyError,
2323
WeaviateInsertManyAllFailedError,
2424
WeaviateInvalidInputError,
25+
InsufficientPermissionsError,
2526
)
2627
from weaviate.proto.v1 import batch_pb2, base_pb2
2728
from weaviate.util import _datetime_to_string, _get_vector_v4
@@ -152,6 +153,8 @@ async def __send_batch(
152153
objects[result.index] = result.error
153154
return objects
154155
except AioRpcError as e:
156+
if e.code().name == PERMISSION_DENIED:
157+
raise InsufficientPermissionsError(e)
155158
raise WeaviateBatchError(str(e)) from e
156159

157160
def __translate_properties_from_python_to_grpc(

weaviate/collections/grpc/query.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@
4848
)
4949
from weaviate.collections.filters import _FilterToGRPC
5050
from weaviate.collections.grpc.retry import _Retry
51-
from weaviate.collections.grpc.shared import _BaseGRPC
51+
from weaviate.collections.grpc.shared import _BaseGRPC, PERMISSION_DENIED
5252
from weaviate.connect import ConnectionV4
5353
from weaviate.exceptions import (
54+
InsufficientPermissionsError,
5455
WeaviateQueryError,
5556
WeaviateUnsupportedFeatureError,
5657
WeaviateInvalidInputError,
@@ -810,7 +811,11 @@ async def __call(self, request: search_get_pb2.SearchRequest) -> search_get_pb2.
810811
timeout=self._connection.timeout_config.query,
811812
)
812813
return cast(search_get_pb2.SearchReply, res)
813-
except (AioRpcError, WeaviateRetryError) as e:
814+
except AioRpcError as e:
815+
if e.code().name == PERMISSION_DENIED:
816+
raise InsufficientPermissionsError(e)
817+
raise WeaviateQueryError(str(e), "GRPC search") # pyright: ignore
818+
except WeaviateRetryError as e:
814819
raise WeaviateQueryError(str(e), "GRPC search") # pyright: ignore
815820

816821
def _metadata_to_grpc(self, metadata: _MetadataQuery) -> search_get_pb2.MetadataRequest:

weaviate/collections/grpc/shared.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from weaviate.connect import ConnectionV4
55
from weaviate.proto.v1 import base_pb2
66

7+
PERMISSION_DENIED = "PERMISSION_DENIED"
8+
79

810
class _BaseGRPC:
911
def __init__(

weaviate/collections/grpc/tenants.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
from weaviate.collections.classes.config import ConsistencyLevel
66
from weaviate.collections.classes.tenants import TenantActivityStatus
77
from weaviate.collections.grpc.retry import _Retry
8-
from weaviate.collections.grpc.shared import _BaseGRPC
8+
from weaviate.collections.grpc.shared import _BaseGRPC, PERMISSION_DENIED
99
from weaviate.connect import ConnectionV4
10-
from weaviate.exceptions import WeaviateTenantGetError
10+
from weaviate.exceptions import WeaviateTenantGetError, InsufficientPermissionsError
1111
from weaviate.proto.v1 import tenants_pb2
1212

1313

@@ -38,6 +38,8 @@ async def get(self, names: Optional[Sequence[str]]) -> tenants_pb2.TenantsGetRep
3838
timeout=self._connection.timeout_config.query,
3939
)
4040
except AioRpcError as e:
41+
if e.code().name == PERMISSION_DENIED:
42+
raise InsufficientPermissionsError(e)
4143
raise WeaviateTenantGetError(str(e)) from e
4244

4345
return cast(tenants_pb2.TenantsGetReply, res)

0 commit comments

Comments
 (0)