diff --git a/backend/gwells/roles.py b/backend/gwells/roles.py index 78e99d0f1..712dace9e 100644 --- a/backend/gwells/roles.py +++ b/backend/gwells/roles.py @@ -43,8 +43,11 @@ # Surveys SURVEYS_EDIT_ROLE = 'surveys_edit' +# IDIR +IDIR_ROLE = 'idir' + # These roles are excluded, as they cannot be mapped to any particular useful groups. -EXCLUDE = ('idir', 'offline_access', 'admin', 'uma_authorization', 'gwells_admin') +EXCLUDE = ('offline_access', 'admin', 'uma_authorization', 'gwells_admin') def roles_to_groups(user, roles: Tuple[str] = None): diff --git a/backend/wells/permissions.py b/backend/wells/permissions.py index aad9da439..d5734e227 100644 --- a/backend/wells/permissions.py +++ b/backend/wells/permissions.py @@ -12,7 +12,7 @@ limitations under the License. """ from rest_framework.permissions import BasePermission, SAFE_METHODS -from gwells.roles import WELLS_VIEWER_ROLE, WELLS_EDIT_ROLE, WELLS_SUBMISSION_ROLE, WELLS_SUBMISSION_VIEWER_ROLE +from gwells.roles import WELLS_VIEWER_ROLE, WELLS_EDIT_ROLE, WELLS_SUBMISSION_ROLE, WELLS_SUBMISSION_VIEWER_ROLE, IDIR_ROLE class WellsEditOrReadOnly(BasePermission): @@ -26,6 +26,17 @@ def has_permission(self, request, view): result = has_edit or request.method in SAFE_METHODS return result +class WellsIDIREditOrReadOnly(BasePermission): + """ + Allows read access to all IDIR users and write access to those with edit rights. + """ + def has_permission(self, request, view): + has_edit = request.user and request.user.is_authenticated and request.user.groups.filter( + name=WELLS_EDIT_ROLE).exists() + result = (has_edit or request.method in SAFE_METHODS) and request.user.groups.filter( + name=IDIR_ROLE).exists() + return result + class WellsDocumentViewPermissions(BasePermission): """ diff --git a/backend/wells/views_v2.py b/backend/wells/views_v2.py index b026ee57e..3cf56ff5a 100644 --- a/backend/wells/views_v2.py +++ b/backend/wells/views_v2.py @@ -54,7 +54,7 @@ CrossReferencingSerializer, RecordComplianceSerializer ) -from wells.permissions import WellsEditOrReadOnly +from wells.permissions import WellsEditOrReadOnly, WellsIDIREditOrReadOnly from wells.renderers import WellListCSVRenderer, WellListExcelRenderer from aquifers.models import ( @@ -593,7 +593,7 @@ class MislocatedWellsListView(ListAPIView): serializer_class = MislocatedWellsSerializer swagger_schema = None - permission_classes = (WellsEditOrReadOnly,) + permission_classes = (WellsIDIREditOrReadOnly,) model = Well pagination_class = APILimitOffsetPagination @@ -617,7 +617,7 @@ class RecordComplianceListView(ListAPIView): serializer_class = RecordComplianceSerializer swagger_schema = None - permission_classes = (WellsEditOrReadOnly,) + permission_classes = (WellsIDIREditOrReadOnly,) model = Well pagination_class = APILimitOffsetPagination @@ -636,7 +636,7 @@ class CrossReferencingListView(ListAPIView): serializer_class = CrossReferencingSerializer swagger_schema = None - permission_classes = (WellsEditOrReadOnly,) + permission_classes = (WellsIDIREditOrReadOnly,) model = Well pagination_class = APILimitOffsetPagination @@ -657,6 +657,7 @@ def get_queryset(self): # Download Views for QaQc class MislocatedWellsDownloadView(WellExportListAPIViewV2): + permission_classes = (WellsIDIREditOrReadOnly,) filter_backends = (WellListOrderingFilter, WellQaQcFilterBackend, filters.SearchFilter) def get_queryset(self): @@ -667,6 +668,7 @@ def get_serializer_class(self): class RecordComplianceDownloadView(WellExportListAPIViewV2): + permission_classes = (WellsIDIREditOrReadOnly,) filter_backends = (WellListOrderingFilter, WellQaQcFilterBackend, filters.SearchFilter) def get_queryset(self): @@ -677,6 +679,7 @@ def get_serializer_class(self): class CrossReferencingDownloadView(WellExportListAPIViewV2): + permission_classes = (WellsIDIREditOrReadOnly,) filter_backends = (WellListOrderingFilter, WellQaQcFilterBackend, filters.SearchFilter) def get_queryset(self): diff --git a/frontend/src/common/components/Header.vue b/frontend/src/common/components/Header.vue index 351dba1df..9c62a5332 100644 --- a/frontend/src/common/components/Header.vue +++ b/frontend/src/common/components/Header.vue @@ -91,7 +91,7 @@ export default { admin: adminMeta ? adminMeta.content === 'true' : false, aquifers: this.hasConfig && this.config.enable_aquifers_search === true, surveys: this.hasConfig && this.userRoles.surveys.edit === true, - qaqc: this.hasConfig && this.userRoles.submissions.edit === true, + qaqc: this.hasConfig && this.userRoles.idir === true && this.userRoles.submissions.edit === true, bulk } } diff --git a/frontend/src/common/store/auth.js b/frontend/src/common/store/auth.js index 08983c761..599401375 100644 --- a/frontend/src/common/store/auth.js +++ b/frontend/src/common/store/auth.js @@ -27,6 +27,7 @@ const auth = { // even if the user does have that role. // Instead, we have to look at the "raw" list of roles contained inside the keycloak instance. const clientRoles = state.keycloak.idTokenParsed['client_roles'] + const identityProvider = state.keycloak.tokenParsed['identity_provider'] return { registry: { view: clientRoles.includes('registries_viewer'), @@ -56,7 +57,8 @@ const auth = { wellDocuments: clientRoles.includes('bulk_well_documents_upload'), aquiferDocuments: clientRoles.includes('bulk_aquifer_documents_upload'), verticalAquiferExtents: clientRoles.includes('bulk_vertical_aquifer_extents_upload') - } + }, + idir: identityProvider === 'idir', } } else { return { @@ -65,13 +67,14 @@ const auth = { submissions: {}, aquifers: {}, surveys: {}, - bulk: {} + bulk: {}, + idir: false, } } }, authenticated (state) { return Boolean(state.keycloak && state.keycloak.authenticated) - } + }, } } diff --git a/frontend/src/qaqc/components/QaQcTable.vue b/frontend/src/qaqc/components/QaQcTable.vue index 1367851c7..9a0a42cc8 100644 --- a/frontend/src/qaqc/components/QaQcTable.vue +++ b/frontend/src/qaqc/components/QaQcTable.vue @@ -18,7 +18,7 @@
Created Date Range
-
+