Repository: feast-dev/feast
Issue category: Bug Report

Issue:
Wrong permission asserts on materialize endpoints 
## Expected Behavior 
The `assert_permissions` function expects a `resources` of type `FeastObject`.

## Current Behavior
Materialization endpoints in `feature_server` module receive instead a `str`, as in [/materialize](https://github.com/feast-dev/feast/blob/60fbc62080950549f28b9411e00926be168bea56/sdk/python/feast/feature_server.py#L256-L258) and [/materialize_incremental](https://github.com/feast-dev/feast/blob/60fbc62080950549f28b9411e00926be168bea56/sdk/python/feast/feature_server.py#L269-L271)

## Possible Solution
Fetch the `FeatureView`s like the [/write-to-online-store](https://github.com/feast-dev/feast/blob/60fbc62080950549f28b9411e00926be168bea56/sdk/python/feast/feature_server.py#L226C9-L235C14) endpoint



Hints:

Patch:
diff --git a/sdk/python/feast/feature_server.py b/sdk/python/feast/feature_server.py
index 26ee604e79..1f4918fe7a 100644
--- a/sdk/python/feast/feature_server.py
+++ b/sdk/python/feast/feature_server.py
@@ -24,6 +24,7 @@
     FeastError,
     FeatureViewNotFoundException,
 )
+from feast.feast_object import FeastObject
 from feast.permissions.action import WRITE, AuthzedAction
 from feast.permissions.security_manager import assert_permissions
 from feast.permissions.server.rest import inject_user_details
@@ -218,21 +219,25 @@ async def push(request: PushFeaturesRequest) -> None:
         else:
             store.push(**push_params)
 
-    @app.post("/write-to-online-store", dependencies=[Depends(inject_user_details)])
-    def write_to_online_store(request: WriteToFeatureStoreRequest) -> None:
-        df = pd.DataFrame(request.df)
-        feature_view_name = request.feature_view_name
-        allow_registry_cache = request.allow_registry_cache
+    def _get_feast_object(
+        feature_view_name: str, allow_registry_cache: bool
+    ) -> FeastObject:
         try:
-            feature_view = store.get_stream_feature_view(  # type: ignore
+            return store.get_stream_feature_view(  # type: ignore
                 feature_view_name, allow_registry_cache=allow_registry_cache
             )
         except FeatureViewNotFoundException:
-            feature_view = store.get_feature_view(  # type: ignore
+            return store.get_feature_view(  # type: ignore
                 feature_view_name, allow_registry_cache=allow_registry_cache
             )
 
-        assert_permissions(resource=feature_view, actions=[AuthzedAction.WRITE_ONLINE])
+    @app.post("/write-to-online-store", dependencies=[Depends(inject_user_details)])
+    def write_to_online_store(request: WriteToFeatureStoreRequest) -> None:
+        df = pd.DataFrame(request.df)
+        feature_view_name = request.feature_view_name
+        allow_registry_cache = request.allow_registry_cache
+        resource = _get_feast_object(feature_view_name, allow_registry_cache)
+        assert_permissions(resource=resource, actions=[AuthzedAction.WRITE_ONLINE])
         store.write_to_online_store(
             feature_view_name=feature_view_name,
             df=df,
@@ -250,9 +255,8 @@ async def health():
     @app.post("/materialize", dependencies=[Depends(inject_user_details)])
     def materialize(request: MaterializeRequest) -> None:
         for feature_view in request.feature_views or []:
-            # TODO: receives a str for resource but isn't in the Union. is str actually allowed?
             assert_permissions(
-                resource=feature_view,  # type: ignore
+                resource=_get_feast_object(feature_view, True),
                 actions=[AuthzedAction.WRITE_ONLINE],
             )
         store.materialize(
@@ -264,9 +268,8 @@ def materialize(request: MaterializeRequest) -> None:
     @app.post("/materialize-incremental", dependencies=[Depends(inject_user_details)])
     def materialize_incremental(request: MaterializeIncrementalRequest) -> None:
         for feature_view in request.feature_views or []:
-            # TODO: receives a str for resource but isn't in the Union. is str actually allowed?
             assert_permissions(
-                resource=feature_view,  # type: ignore
+                resource=_get_feast_object(feature_view, True),
                 actions=[AuthzedAction.WRITE_ONLINE],
             )
         store.materialize_incremental(


Test patch: