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],
};
}),