|
8 | 8 | from fastapi import Depends, Security |
9 | 9 | from fastapi.exceptions import HTTPException |
10 | 10 | from fastapi.responses import JSONResponse |
11 | | -from libsuitecrm import Filter, SuiteCRM # type: ignore |
| 11 | +from libsuitecrm import Filter, RequestFailed, SuiteCRM # type: ignore |
12 | 12 |
|
13 | 13 | from register_your_data_api.dependencies import get_suitecrm_audit_headers |
14 | 14 |
|
|
37 | 37 | ReportingOrgUserCreateModel, |
38 | 38 | UserReportingOrgDiscoverableMetadataRelation, |
39 | 39 | UserReportingOrgRelation, |
40 | | - UserReportingOrgRelationListResponse, |
41 | 40 | UserReportingOrgRelationSingleResponse, |
42 | 41 | ) |
43 | 42 | from ..response_schemas import PaginatedResultsPage |
|
51 | 50 | def get_reporting_orgs( |
52 | 51 | request: starlette.requests.Request, |
53 | 52 | user: auth_models.UserAndCredentials = Security(authz.get_user_authnz, scopes=["ryd", "ryd:reporting_org"]), |
| 53 | + paging: PaginationQueryParams = fastapi.Depends(), |
54 | 54 | include_actions: str = "no", |
55 | | -) -> UserReportingOrgRelationListResponse: |
| 55 | +) -> PaginatedResultsPage[UserReportingOrgRelation | UserReportingOrgDiscoverableMetadataRelation]: |
56 | 56 |
|
57 | 57 | context: Context = request.app.state.context |
58 | 58 |
|
59 | | - user_reporting_org_associations = user.validator.get_users_fine_grained_associations() |
| 59 | + crm: SuiteCRM = context.suitecrm_client_factory.get_client() |
| 60 | + |
| 61 | + try: |
| 62 | + orgs_for_user = crm.get_relationship( |
| 63 | + "Contacts", |
| 64 | + user.user_id_crm, |
| 65 | + "Accounts", |
| 66 | + page_number=paging.page, |
| 67 | + page_size=paging.page_size, |
| 68 | + sort_field="name", |
| 69 | + sort_dir="ascending", |
| 70 | + filters=Filter().equal("iati_registry_discoverable", "1"), |
| 71 | + ) |
| 72 | + except RequestFailed as e: |
| 73 | + error_id = uuid.uuid4() |
| 74 | + public_error_message = ( |
| 75 | + "There was a problem fetching the list of reporting orgs you are associated with. " |
| 76 | + f"Please try again later, or contact IATI Support quoting error id: {error_id}" |
| 77 | + ) |
| 78 | + context.app_logger.error( |
| 79 | + f"Error: error id: {error_id} - user id: {user.user_id_crm} - GET /reporting-orgs - Problem when fetching " |
| 80 | + "the list of reporting organisations for this user from SuiteCRM. " |
| 81 | + f"Details: {str(e)}" |
| 82 | + ) |
| 83 | + raise HTTPException(status_code=fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR, detail=public_error_message) |
| 84 | + |
| 85 | + total_records = orgs_for_user.get("meta", {}).get("total-records", 0) |
60 | 86 |
|
61 | 87 | reporting_orgs_list: list[UserReportingOrgRelation | UserReportingOrgDiscoverableMetadataRelation] = [] |
62 | 88 |
|
63 | | - if len(user_reporting_org_associations) > 0: |
| 89 | + for reporting_org_from_suitecrm in orgs_for_user["data"]: |
| 90 | + role_for_org = user.validator.get_user_role_for_reporting_org(reporting_org_from_suitecrm["id"]) |
64 | 91 |
|
65 | | - crm: SuiteCRM = context.suitecrm_client_factory.get_client() |
| 92 | + if role_for_org is None: |
| 93 | + context.app_logger.info( |
| 94 | + f"Info: user id: {user.user_id_crm} - GET /reporting-orgs - user is associated with organisation " |
| 95 | + f"{reporting_org_from_suitecrm["id"]} in the CRM but has no role for that organisation in the FGA DB. " |
| 96 | + "Organisation was omitted from the list returned to the user." |
| 97 | + ) |
| 98 | + continue |
66 | 99 |
|
67 | | - fields = SUITECRM_REPORTING_ORG_FIELDS |
| 100 | + reporting_org_obj: ReportingOrgMetadata | DiscoverableReportingOrgMetadata |
68 | 101 |
|
69 | | - # The OR search in SuiteCRM appears to be broken; you can't search for items where id = 'A' OR id = 'B' OR ... |
70 | | - # It appears this doesn't work when the field being searched on is the same in each case. So we have to fetch |
71 | | - # the details for reporting orgs the user is associated with one at a time. |
72 | | - suitecrm_collected_responses: list[dict[str, Any]] = [] |
73 | | - for user_reporting_org_association in user_reporting_org_associations: |
74 | | - filters = Filter() |
75 | | - filters.equal("id", str(user_reporting_org_association.reporting_org)) |
76 | | - filters.equal("iati_registry_discoverable", "1") |
77 | | - crm_reporting_org = crm.get_records("Accounts", fields=fields, filters=filters) |
78 | | - if "data" in crm_reporting_org and len(crm_reporting_org["data"]) > 0: |
79 | | - suitecrm_collected_responses.append(*crm_reporting_org["data"]) |
80 | | - |
81 | | - for reporting_org_from_suitecrm in suitecrm_collected_responses: |
82 | | - role_for_org = user.validator.get_user_role_for_reporting_org(reporting_org_from_suitecrm["id"]) |
83 | | - reporting_org_obj: ReportingOrgMetadata | DiscoverableReportingOrgMetadata |
84 | | - |
85 | | - if role_for_org == fga_models.FineGrainedAuthorisationRole.CONTRIBUTOR_PENDING: |
86 | | - reporting_org_obj = get_discoverable_reporting_org_meta_from_suitecrm_response( |
87 | | - reporting_org_from_suitecrm["attributes"] |
88 | | - ) |
89 | | - else: |
90 | | - reporting_org_obj = get_reporting_org_meta_from_suitecrm_response( |
91 | | - reporting_org_from_suitecrm["attributes"] |
92 | | - ) |
| 102 | + if role_for_org == fga_models.FineGrainedAuthorisationRole.CONTRIBUTOR_PENDING: |
| 103 | + reporting_org_obj = get_discoverable_reporting_org_meta_from_suitecrm_response( |
| 104 | + reporting_org_from_suitecrm["attributes"] |
| 105 | + ) |
| 106 | + else: |
| 107 | + reporting_org_obj = get_reporting_org_meta_from_suitecrm_response( |
| 108 | + reporting_org_from_suitecrm["attributes"] |
| 109 | + ) |
93 | 110 |
|
94 | | - reporting_orgs_list.append( |
95 | | - UserReportingOrgRelation( |
96 | | - id=reporting_org_from_suitecrm["id"], |
97 | | - user_role=get_fga_role_as_str(role_for_org), # type: ignore |
98 | | - metadata=reporting_org_obj, |
99 | | - reporting_org_actions=( |
100 | | - get_reporting_org_actions(crm, reporting_org_from_suitecrm["id"]) |
101 | | - if include_actions == "yes" |
102 | | - else [] |
103 | | - ), |
104 | | - ) |
| 111 | + reporting_orgs_list.append( |
| 112 | + UserReportingOrgRelation( |
| 113 | + id=reporting_org_from_suitecrm["id"], |
| 114 | + user_role=get_fga_role_as_str(role_for_org), |
| 115 | + metadata=reporting_org_obj, |
| 116 | + reporting_org_actions=( |
| 117 | + get_reporting_org_actions(crm, reporting_org_from_suitecrm["id"]) |
| 118 | + if include_actions == "yes" |
| 119 | + else [] |
| 120 | + ), |
105 | 121 | ) |
| 122 | + ) |
106 | 123 |
|
107 | | - reporting_orgs_list.sort(key=lambda org: org.metadata.human_readable_name.lower()) |
| 124 | + reporting_orgs_list.sort(key=lambda org: org.metadata.human_readable_name.lower()) |
108 | 125 |
|
109 | | - return UserReportingOrgRelationListResponse(status="success", error=None, data=reporting_orgs_list) |
| 126 | + return PaginatedResultsPage.create(reporting_orgs_list, paging.page, paging.page_size, total_records, request) |
110 | 127 |
|
111 | 128 |
|
112 | 129 | @router.get("/{org_id}") |
|
0 commit comments