diff --git a/met-api/src/met_api/services/comment_service.py b/met-api/src/met_api/services/comment_service.py index fd20c9603..17ba5a82b 100644 --- a/met-api/src/met_api/services/comment_service.py +++ b/met-api/src/met_api/services/comment_service.py @@ -13,6 +13,7 @@ from met_api.schemas.comment import CommentSchema from met_api.schemas.submission import SubmissionSchema from met_api.schemas.survey import SurveySchema +from met_api.services import authorization from met_api.services.document_generation_service import DocumentGenerationService from met_api.utils.roles import Role from met_api.utils.token_info import TokenInfo @@ -157,6 +158,12 @@ def extract_comments_from_survey(cls, survey_submission: SubmissionSchema, surve @classmethod def export_comments_to_spread_sheet(cls, survey_id): """Export comments to spread sheet.""" + engagement = SurveyModel.find_by_id(survey_id) + one_of_roles = ( + MembershipType.TEAM_MEMBER.name, + Role.EXPORT_TO_CSV.value + ) + authorization.check_auth(one_of_roles=one_of_roles, engagement_id=engagement.engagement_id) comments = Comment.get_comments_by_survey_id(survey_id) formatted_comments = [ { diff --git a/met-api/src/met_api/services/engagement_metadata_service.py b/met-api/src/met_api/services/engagement_metadata_service.py index 2473ab766..9c6b209f6 100644 --- a/met-api/src/met_api/services/engagement_metadata_service.py +++ b/met-api/src/met_api/services/engagement_metadata_service.py @@ -1,7 +1,7 @@ """Service for engagement management.""" from datetime import datetime -from met_api.constants.engagement_status import SubmissionStatus +from met_api.constants.engagement_status import Status, SubmissionStatus from met_api.constants.membership_type import MembershipType from met_api.models.engagement import Engagement as EngagementModel from met_api.models.engagement_metadata import EngagementMetadataModel @@ -16,11 +16,13 @@ class EngagementMetadataService: @staticmethod def get_metadata(engagement_id) -> EngagementMetadataSchema: """Get Engagement metadata by the id.""" - one_of_roles = ( - MembershipType.TEAM_MEMBER.name, - Role.VIEW_ALL_ENGAGEMENTS.value - ) - authorization.check_auth(one_of_roles=one_of_roles, engagement_id=engagement_id) + engagement_model: EngagementModel = EngagementModel.find_by_id(engagement_id) + if engagement_model.status_id in (Status.Draft.value, Status.Scheduled.value): + one_of_roles = ( + MembershipType.TEAM_MEMBER.name, + Role.VIEW_ALL_ENGAGEMENTS.value + ) + authorization.check_auth(one_of_roles=one_of_roles, engagement_id=engagement_id) metadata_model: EngagementMetadataModel = EngagementMetadataModel.find_by_id(engagement_id) metadata = EngagementMetadataSchema().dump(metadata_model) diff --git a/met-api/src/met_api/utils/roles.py b/met-api/src/met_api/utils/roles.py index 3d47a0b4c..fda7d3707 100644 --- a/met-api/src/met_api/utils/roles.py +++ b/met-api/src/met_api/utils/roles.py @@ -54,3 +54,4 @@ class Role(Enum): VIEW_FEEDBACKS = 'view_feedbacks' VIEW_ALL_ENGAGEMENTS = 'view_all_engagements' # Allows user access to all engagements including draft SHOW_ALL_COMMENT_STATUS = 'show_all_comment_status' # Allows user to see all comment status + EXPORT_TO_CSV = 'export_to_csv' # Allows users to export comments to csv diff --git a/met-api/tests/unit/api/test_comment.py b/met-api/tests/unit/api/test_comment.py index dd3954f7a..0951638b8 100644 --- a/met-api/tests/unit/api/test_comment.py +++ b/met-api/tests/unit/api/test_comment.py @@ -177,7 +177,7 @@ def test_review_comment_review_note(client, jwt, session): # pylint:disable=unu def test_get_comments_spreadsheet(mocker, client, jwt, session): # pylint:disable=unused-argument """Assert that comments sheet can be fetched.""" - claims = TestJwtClaims.public_user_role + claims = TestJwtClaims.staff_admin_role mock_post_generate_document_response = MagicMock() mock_post_generate_document_response.content = b'mock data' diff --git a/met-api/tests/utilities/factory_scenarios.py b/met-api/tests/utilities/factory_scenarios.py index fb792e788..79291eb5e 100644 --- a/met-api/tests/utilities/factory_scenarios.py +++ b/met-api/tests/utilities/factory_scenarios.py @@ -301,6 +301,7 @@ class TestJwtClaims(dict, Enum): 'review_all_comments', 'view_all_engagements', 'toggle_user_status', + 'export_to_csv', ] } } diff --git a/met-web/src/components/comments/admin/reviewListing/Submissions.tsx b/met-web/src/components/comments/admin/reviewListing/Submissions.tsx index 2daf4ac07..3bd482601 100644 --- a/met-web/src/components/comments/admin/reviewListing/Submissions.tsx +++ b/met-web/src/components/comments/admin/reviewListing/Submissions.tsx @@ -19,6 +19,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import { useAppSelector } from 'hooks'; import { USER_ROLES } from 'services/userService/constants'; import { USER_GROUP } from 'models/user'; +import { PermissionsGate } from 'components/permissionsGate'; const Submissions = () => { const { @@ -156,9 +157,11 @@ const Submissions = () => { Read All Comments - - Export to CSV - + + + Export to CSV + + diff --git a/met-web/src/components/permissionsGate/index.tsx b/met-web/src/components/permissionsGate/index.tsx index 79e285d26..8a9a308d7 100644 --- a/met-web/src/components/permissionsGate/index.tsx +++ b/met-web/src/components/permissionsGate/index.tsx @@ -28,7 +28,7 @@ export function PermissionsGate({ errorProps, scopes = [], }: PermissionsGateProps): React.ReactElement { - const permissions = useAppSelector((state) => state.user.roles); + const { roles: permissions } = useAppSelector((state) => state.user); const permissionGranted = hasPermission({ permissions, scopes }); diff --git a/met-web/src/services/userService/constants.ts b/met-web/src/services/userService/constants.ts index b51591f53..22e821336 100644 --- a/met-web/src/services/userService/constants.ts +++ b/met-web/src/services/userService/constants.ts @@ -31,4 +31,5 @@ export const USER_ROLES = { VIEW_FEEDBACKS: 'view_feedbacks', SHOW_ALL_COMMENT_STATUS: 'show_all_comment_status', TOGGLE_USER_STATUS: 'toggle_user_status', + EXPORT_TO_CSV: 'export_to_csv', }; diff --git a/met-web/tests/unit/components/comment/CommentListing.test.tsx b/met-web/tests/unit/components/comment/CommentListing.test.tsx index a6b1f931f..1653eb0c5 100644 --- a/met-web/tests/unit/components/comment/CommentListing.test.tsx +++ b/met-web/tests/unit/components/comment/CommentListing.test.tsx @@ -68,7 +68,7 @@ jest.mock('react-redux', () => ({ ...jest.requireActual('react-redux'), useSelector: jest.fn(() => { return { - roles: [USER_ROLES.REVIEW_COMMENTS], + roles: [USER_ROLES.REVIEW_COMMENTS, USER_ROLES.EXPORT_TO_CSV], assignedEngagements: [mockSurveyOne.engagement_id], }; }),