22import datetime
33import traceback
44from functools import partial
5+ from http import HTTPStatus
56from typing import Annotated , Any , Literal , Sequence , Type , TypeVar , Union
67from wsgiref .handlers import format_date_time
78
1314from starlette .responses import JSONResponse
1415
1516from authentication import KeycloakUser , get_user_or_none , get_user_or_raise
16- from config import KEYCLOAK_CONFIG
1717from converters .schema_converters .schema_converter import SchemaConverter
1818from database .authorization import (
1919 user_can_administer ,
2020 set_permission ,
2121 register_user ,
2222 PermissionType ,
2323 user_can_write ,
24+ user_can_read ,
2425)
2526from database .model .ai_resource .resource import AIResource
2627from database .model .concept .aiod_entry import AIoDEntryORM , EntryStatus
3233 resource_read ,
3334)
3435from database .model .serializers import deserialize_resource_relationships
35- from database .review import Decision , Review , Submission , ReviewCreate , SubmissionCreate
36+ from database .review import Submission , SubmissionCreate
3637from database .session import DbSession
3738from dependencies .filtering import ResourceFilters , ResourceFiltersParams
3839from dependencies .pagination import Pagination , PaginationParams
@@ -211,7 +212,7 @@ def get_resources(
211212 user : KeycloakUser | None = None ,
212213 platform : str | None = None ,
213214 ):
214- """Fetch all resources of this platform in given schema, using pagination"""
215+ """Fetch all published resources of this platform in given schema, using pagination"""
215216 _raise_error_on_invalid_schema (self ._possible_schemas , schema )
216217 with DbSession (autoflush = False ) as session :
217218 try :
@@ -244,6 +245,17 @@ def get_resource(
244245 resource : Any = self ._retrieve_resource_and_post_process (
245246 session , identifier , user , platform = platform
246247 )
248+ if resource .aiod_entry .status != EntryStatus .PUBLISHED :
249+ if user is None :
250+ raise HTTPException (
251+ status_code = HTTPStatus .UNAUTHORIZED ,
252+ detail = "This asset is not published. It requires authentication to access." ,
253+ )
254+ if not user_can_read (user , resource .aiod_entry ):
255+ raise HTTPException (
256+ status_code = HTTPStatus .FORBIDDEN ,
257+ detail = "You are not allowed to view this resource." ,
258+ )
247259 if schema != "aiod" :
248260 return self .schema_converters [schema ].convert (session , resource )
249261 return self ._wrap_with_headers (self .resource_class_read .from_orm (resource ))
@@ -276,7 +288,7 @@ def get_resources(
276288
277289 def get_resource_count_func (self ):
278290 """
279- Gets the total number of resources from the database.
291+ Gets the total number of published resources from the database.
280292 This function returns a function (instead of being that function directly) because the
281293 docstring and the variables are dynamic, and used in Swagger.
282294 """
@@ -291,7 +303,11 @@ def get_resource_count(
291303 if not detailed :
292304 return (
293305 session .query (self .resource_class )
294- .where (is_ (self .resource_class .date_deleted , None ))
306+ .join (self .resource_class .aiod_entry , isouter = True )
307+ .where (
308+ is_ (self .resource_class .date_deleted , None ),
309+ AIoDEntryORM .status == EntryStatus .PUBLISHED ,
310+ )
295311 .count ()
296312 )
297313 else :
@@ -300,7 +316,11 @@ def get_resource_count(
300316 self .resource_class .platform ,
301317 func .count (self .resource_class .identifier ),
302318 )
303- .where (is_ (self .resource_class .date_deleted , None ))
319+ .join (self .resource_class .aiod_entry , isouter = True )
320+ .where (
321+ is_ (self .resource_class .date_deleted , None ),
322+ AIoDEntryORM .status == EntryStatus .PUBLISHED ,
323+ )
304324 .group_by (self .resource_class .platform )
305325 .all ()
306326 )
@@ -612,8 +632,8 @@ def _retrieve_resources(
612632 platform : str | None = None ,
613633 ) -> Sequence [type [RESOURCE_MODEL ]]:
614634 """
615- Retrieve a sequence of resources from the database based on the provided identifier,
616- platform and resource filters (if applicable).
635+ Retrieve a sequence of published resources from the database based on the
636+ provided identifier, platform and resource filters (if applicable).
617637 """
618638 where_clause = and_ (
619639 is_ (self .resource_class .date_deleted , None ),
@@ -624,6 +644,7 @@ def _retrieve_resources(
624644 AIoDEntryORM .date_modified < resource_filters .date_modified_before
625645 if resource_filters .date_modified_before is not None
626646 else True ,
647+ AIoDEntryORM .status == EntryStatus .PUBLISHED ,
627648 )
628649 query = (
629650 select (self .resource_class )
0 commit comments