From 7791d7633a1efdc5245c4ebed692d481d04a515e Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Tue, 16 Jul 2024 15:26:20 -0700 Subject: [PATCH 1/4] rename flags, update logs and imports --- services/common/src/utils/featureFlag.ts | 5 +- .../core-api/app/api/utils/feature_flag.py | 7 ++- .../app/api/verifiable_credentials/manager.py | 46 +++++--------- .../resources/traction_webhook.py | 7 --- .../resources/vc_connection_invitations.py | 19 +++--- .../resources/vc_connections.py | 4 -- .../resources/vc_map.py | 63 ++++++++++++------- .../resources/vc_map_detail.py | 16 ++--- .../resources/vc_revocation.py | 41 ++++++------ .../resources/w3c_map_credential_resource.py | 17 +++-- .../src/components/parties/PartyProfile.js | 53 +++++++--------- .../mine/permits/DigitalPermitsTable.tsx | 2 +- 12 files changed, 139 insertions(+), 141 deletions(-) diff --git a/services/common/src/utils/featureFlag.ts b/services/common/src/utils/featureFlag.ts index 6f1ab529fc..8f84ec0056 100644 --- a/services/common/src/utils/featureFlag.ts +++ b/services/common/src/utils/featureFlag.ts @@ -9,8 +9,9 @@ export enum Feature { ESUP_PERMIT_AMENDMENT = "esup_permit_amendment", FLAGSMITH = "flagsmith", TSF_V2 = "tsf_v2", - VERIFIABLE_CREDENTIALS = "verifiable_credentials", - VERIFIABLE_CREDENTIALS_2 = "verifiable_credentials_2.0", + VC_ANONCREDS_CORE = "vc_anoncreds_core", + VC_ANONCREDS_MINESPACE = "vc_anoncreds_minespace", + VC_W3C = "vc_w3c", MINESPACE_ESUPS = "minespace_esups", REPORT_ERROR = "report_error", MAJOR_PROJECT_LINK_PROJECTS = "major_project_link_projects", diff --git a/services/core-api/app/api/utils/feature_flag.py b/services/core-api/app/api/utils/feature_flag.py index 6289248bf9..77b958bf52 100644 --- a/services/core-api/app/api/utils/feature_flag.py +++ b/services/core-api/app/api/utils/feature_flag.py @@ -10,12 +10,13 @@ class Feature(Enum): MINE_APPLICATION_FILE_UDPATE_ALERTS = 'mine_application_file_update_alerts' TRACTION_VERIFIABLE_CREDENTIALS = 'verifiable_credentials' #if enabled the credential offer will be the current development state of all the 2.0 changes, Q1 2024 - VC_MINES_ACT_PERMIT_20 = 'vc_mines_act_permit_20' + VC_ANONCREDS_20 = 'vc_mines_act_permit_20' # pending anoncred content differences. + VC_ANONCREDS_CORE = "vc_anoncreds_core" + VC_ANONCREDS_MINESPACE = "vc_anoncreds_minespace" + VC_W3C = "vc_w3c" CODE_REQUIRED_REPORTS = 'code_required-reports' PERMIT_DOCUMENT_KEYWORD_SEARCH = 'permit_document_keyword_search' AMS_AGENT = 'ams_agent' - #technical features exist, governance is not yet in place - JSONLD_MINES_ACT_PERMIT = 'jsonld_mines_act_permit' def __str__(self): return self.value diff --git a/services/core-api/app/api/verifiable_credentials/manager.py b/services/core-api/app/api/verifiable_credentials/manager.py index d3987507ae..dc2192ab88 100644 --- a/services/core-api/app/api/verifiable_credentials/manager.py +++ b/services/core-api/app/api/verifiable_credentials/manager.py @@ -131,15 +131,15 @@ def process_all_untp_map_for_orgbook(): """).fetchall() - current_app.logger.warning("Num of results from query to process:" + - str(len(permit_amendment_query_results))) + task_logger.info("Num of results from query to process:" + + str(len(permit_amendment_query_results))) traction_service = TractionService() public_did_dict = traction_service.fetch_current_public_did() public_did = Config.CHIEF_PERMITTING_OFFICER_DID_WEB public_verkey = public_did_dict["verkey"] - current_app.logger.warning("public did: " + public_did) + task_logger.info("public did: " + public_did) records: List[Tuple[W3CCred, PermitAmendmentOrgBookPublish]] = [] # list of tuples [payload, record] @@ -147,13 +147,12 @@ def process_all_untp_map_for_orgbook(): for row in permit_amendment_query_results: pa = PermitAmendment.find_by_permit_amendment_guid(row[0], unsafe=True) if not pa: - current_app.logger.warning( - f"Permit Amendment not found for permit_amendment_guid={row[0]}") + task_logger.warning(f"Permit Amendment not found for permit_amendment_guid={row[0]}") continue pa_cred = VerifiableCredentialManager.produce_untp_cc_map_payload(public_did, pa) if not pa_cred: - current_app.logger.warning(f"pa_cred could not be created") + task_logger.warning(f"pa_cred could not be created") continue payload_hash = md5(pa_cred.json(by_alias=True).encode('utf-8')).hexdigest() @@ -172,7 +171,7 @@ def process_all_untp_map_for_orgbook(): ) records.append((pa_cred, paob)) - current_app.logger.warning(f"public_verkey={public_verkey}") + task_logger.info(f"public_verkey={public_verkey}") # send to traction to be signed for cred_payload, record in records: signed_cred = traction_service.sign_jsonld_credential_deprecated( @@ -181,13 +180,12 @@ def process_all_untp_map_for_orgbook(): record.signed_credential = json.dumps(signed_cred["signed_doc"]) record.sign_date = datetime.now() record.save() - current_app.logger.warning( - "bcreg_uri=" + - str(cred_payload.credentialSubject.issuedTo.identifiers[0].identifierURI) + - ", for permit_amendment_guid=" + str(row[0])) - current_app.logger.warning("unsigned_hash=" + str(record.unsigned_payload_hash)) + task_logger.info("bcreg_uri=" + + str(cred_payload.credentialSubject.issuedTo.identifiers[0].identifierURI) + + ", for permit_amendment_guid=" + str(row[0])) + task_logger.info("unsigned_hash=" + str(record.unsigned_payload_hash)) - print("num of records created: " + str(len(records or []))) + task_logger.info("num of records created: " + str(len(records or []))) return [record for payload, record in records] @@ -261,7 +259,7 @@ def collect_attributes_for_mines_act_permit_111( credential_attrs["mine_no"] = permit_amendment.mine.mine_no credential_attrs["issue_date"] = int( permit_amendment.issue_date.strftime("%Y%m%d")) if is_feature_enabled( - Feature.VC_MINES_ACT_PERMIT_20) else permit_amendment.issue_date + Feature.VC_ANONCREDS_20) else permit_amendment.issue_date # https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0441-present-proof-best-practices#dates-and-predicates credential_attrs["latitude"] = permit_amendment.mine.latitude credential_attrs["longitude"] = permit_amendment.mine.longitude @@ -286,10 +284,6 @@ def collect_attributes_for_mines_act_permit_111( return attributes - @classmethod - def revoke_all_credentials_for_permit(cls, permit_guid: str): - pass - @classmethod def produce_map_01_credential_payload(cls, did: str, permit_amendment: PermitAmendment): #use w3c vcdm issue_date, not as an attribute in the credential @@ -334,17 +328,11 @@ def produce_untp_cc_map_payload(cls, did: str, permit_amendment: PermitAmendment return None untp_party_cpo = base.Party( - name="Chief Permitting Officer", + name="Chief Permitting Officer of Mines", identifiers=[ base.Identifier( - scheme=ANONCRED_SCHEME, - identifierValue="did:indy:candy:A2UZSmrL9N5FDZGPu68wy", - identifierURI="https://candyscan.idlab.org/tx/CANDY_PROD/domain/321", - verificationEvidence=base.Evidence( - format=codes.EvidenceFormat.W3C_VC, - credentialReference= - "did:web:untp.traceability.site:parties:regulators:CHIEF-PERMITTING-OFFICER" #this is an anoncred - )) + identifierValue= + "did:web:untp.traceability.site:parties:regulators:CHIEF-PERMITTING-OFFICER") ]) orgbook_cred_url = f"https://orgbook.gov.bc.ca/entity/{orgbook_entity.registration_id}/credential/{orgbook_entity.credential_id}" @@ -378,7 +366,7 @@ def produce_untp_cc_map_payload(cls, did: str, permit_amendment: PermitAmendment referenceRegulation=cc.Regulation( id="https://www.bclaws.gov.bc.ca/civix/document/id/complete/statreg/96293_01", name="BC Mines Act", - issuingBody=base.Party(name="BC Government"), + issuingBody=base.Party(name="Government of British Columbia"), effectiveDate=datetime(2024, 5, 14, tzinfo=ZoneInfo("UTC")).isoformat()), # Is there a did:web that attests to that legistlation? subjectFacilities=[facility], @@ -391,7 +379,7 @@ def produce_untp_cc_map_payload(cls, did: str, permit_amendment: PermitAmendment tzinfo=ZoneInfo("UTC")).isoformat() cred = cc.ConformityAttestation( - id="http://example.com/attestation/123", + id="http://example.com/govdomain/minesactpermit/123", assessmentLevel=codes.AssessmentAssuranceCode.GovtApproval, type=codes.AttestationType.Certification, description= diff --git a/services/core-api/app/api/verifiable_credentials/resources/traction_webhook.py b/services/core-api/app/api/verifiable_credentials/resources/traction_webhook.py index 388680a242..f0068825e2 100644 --- a/services/core-api/app/api/verifiable_credentials/resources/traction_webhook.py +++ b/services/core-api/app/api/verifiable_credentials/resources/traction_webhook.py @@ -2,20 +2,16 @@ from flask import current_app, request from werkzeug.exceptions import Forbidden from flask_restx import Resource -from app.api.utils.include.user_info import User from app.config import Config from app.extensions import api from app.api.utils.resources_mixins import UserMixin -from app.api.services.traction_service import TractionService from app.api.verifiable_credentials.models.connection import PartyVerifiableCredentialConnection from app.api.verifiable_credentials.models.credentials import PartyVerifiableCredentialMinesActPermit from app.api.verifiable_credentials.aries_constants import DIDExchangeRequesterState, IssueCredentialIssuerState -from app.api.utils.feature_flag import Feature, is_feature_enabled - PRESENT_PROOF = "present_proof" CONNECTIONS = "connections" CREDENTIAL_OFFER = "issue_credential" @@ -28,9 +24,6 @@ class TractionWebhookResource(Resource, UserMixin): @api.doc(description='Endpoint to recieve webhooks from Traction.', params={}) def post(self, topic): - if not is_feature_enabled(Feature.TRACTION_VERIFIABLE_CREDENTIALS): - raise NotImplemented() - #custom auth for traction if request.headers.get("x-api-key") != Config.TRACTION_WEBHOOK_X_API_KEY: return Forbidden("bad x-api-key") diff --git a/services/core-api/app/api/verifiable_credentials/resources/vc_connection_invitations.py b/services/core-api/app/api/verifiable_credentials/resources/vc_connection_invitations.py index 99ebb79980..cee1f0449d 100644 --- a/services/core-api/app/api/verifiable_credentials/resources/vc_connection_invitations.py +++ b/services/core-api/app/api/verifiable_credentials/resources/vc_connection_invitations.py @@ -1,6 +1,5 @@ -from flask import current_app from flask_restx import Resource -from werkzeug.exceptions import NotFound, NotImplemented +from werkzeug.exceptions import NotFound, ServiceUnavailable from app.extensions import api from app.api.utils.access_decorators import requires_any_of, EDIT_PARTY, MINESPACE_PROPONENT @@ -17,8 +16,8 @@ class VerifiableCredentialConnectionInvitationsResource(Resource, UserMixin): @api.doc(description='Create a connection invitation for a party by guid', params={}) @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) def post(self, party_guid: str): - if not is_feature_enabled(Feature.TRACTION_VERIFIABLE_CREDENTIALS): - raise NotImplemented() + if not is_feature_enabled(Feature.VC_ANONCREDS_MINESPACE): + raise ServiceUnavailable() party = Party.find_by_party_guid(party_guid) if not party: raise NotFound(f"party not found with party_guid {party_guid}") @@ -32,19 +31,23 @@ def post(self, party_guid: str): @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) @api.marshal_with(PARTY_VERIFIABLE_CREDENTIAL_CONNECTION, code=200, envelope='records') def get(self, party_guid: str): - if not is_feature_enabled(Feature.TRACTION_VERIFIABLE_CREDENTIALS): - raise NotImplemented() + if not is_feature_enabled(Feature.VC_ANONCREDS_MINESPACE): + raise ServiceUnavailable() + party_vc_conn = PartyVerifiableCredentialConnection.find_by_party_guid( party_guid=party_guid) + return party_vc_conn @api.doc(description="Delete a connection for a party by guid", params={}) @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) def delete(self, party_guid): - if not is_feature_enabled(Feature.TRACTION_VERIFIABLE_CREDENTIALS): - raise NotImplemented() + if not is_feature_enabled(Feature.VC_ANONCREDS_MINESPACE): + raise ServiceUnavailable() + party_vc_conn = PartyVerifiableCredentialConnection.find_by_party_guid(party_guid) if not party_vc_conn: raise NotFound(f"party_vc_conn not found with party_guid {party_guid}") + party_vc_conn.delete() party_vc_conn.save() diff --git a/services/core-api/app/api/verifiable_credentials/resources/vc_connections.py b/services/core-api/app/api/verifiable_credentials/resources/vc_connections.py index d9730668dd..2801247130 100644 --- a/services/core-api/app/api/verifiable_credentials/resources/vc_connections.py +++ b/services/core-api/app/api/verifiable_credentials/resources/vc_connections.py @@ -4,12 +4,9 @@ from app.extensions import api from app.api.utils.access_decorators import requires_any_of, EDIT_PARTY, MINESPACE_PROPONENT -from app.api.parties.party.models.party import Party from app.api.verifiable_credentials.models.connection import PartyVerifiableCredentialConnection from app.api.services.traction_service import TractionService -from app.api.verifiable_credentials.response_models import PARTY_VERIFIABLE_CREDENTIAL_CONNECTION from app.api.utils.resources_mixins import UserMixin -from app.api.utils.feature_flag import Feature, is_feature_enabled class VerifiableCredentialConnectionResource(Resource, UserMixin): @@ -20,7 +17,6 @@ def delete(self, party_guid: str): active_conn = PartyVerifiableCredentialConnection.find_active_by_party_guid(party_guid) conns = PartyVerifiableCredentialConnection.find_by_party_guid(party_guid) - current_app.logger.warning(conns) if not active_conn: raise BadRequest(f"party has no active connection party_guid={party_guid}") diff --git a/services/core-api/app/api/verifiable_credentials/resources/vc_map.py b/services/core-api/app/api/verifiable_credentials/resources/vc_map.py index 37fcf61e6c..84370ad22d 100644 --- a/services/core-api/app/api/verifiable_credentials/resources/vc_map.py +++ b/services/core-api/app/api/verifiable_credentials/resources/vc_map.py @@ -1,6 +1,6 @@ from flask import current_app, request from flask_restx import Resource, reqparse -from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import BadRequest, ServiceUnavailable from app.extensions import api from app.config import Config @@ -19,23 +19,31 @@ class VerifiableCredentialMinesActPermitResource(Resource, UserMixin): parser = reqparse.RequestParser(trim=True) - parser.add_argument( - 'permit_amendment_guid', location='json', type=str, store_missing=False) - + parser.add_argument('permit_amendment_guid', location='json', type=str, store_missing=False) + @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) - @api.marshal_with(PARTY_VERIFIABLE_CREDENTIAL_MINES_ACT_PERMIT, code=200, envelope='records', as_list=True) + @api.marshal_with( + PARTY_VERIFIABLE_CREDENTIAL_MINES_ACT_PERMIT, code=200, envelope='records', as_list=True) def get(self, party_guid): if not party_guid: raise BadRequest("party_guid required") - party_credential_exchanges = PartyVerifiableCredentialMinesActPermit.find_by_party_guid(party_guid) + party_credential_exchanges = PartyVerifiableCredentialMinesActPermit.find_by_party_guid( + party_guid) return party_credential_exchanges - @api.doc(description="Create a connection invitation for a party by guid", params={"party_guid":"guid for party with wallet connection","permit_amendment_guid":"parmit_amendment that will be offered as a credential to the indicated party"}) + @api.doc( + description="Create a connection invitation for a party by guid", + params={ + "party_guid": + "guid for party with wallet connection", + "permit_amendment_guid": + "parmit_amendment that will be offered as a credential to the indicated party" + }) @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) def post(self, party_guid): - if not is_feature_enabled(Feature.TRACTION_VERIFIABLE_CREDENTIALS): - raise NotImplemented() + if not is_feature_enabled(Feature.VC_ANONCREDS_MINESPACE): + raise ServiceUnavailable() data = self.parser.parse_args() current_app.logger.warning(data) permit_amendment_guid = data["permit_amendment_guid"] @@ -45,38 +53,49 @@ def post(self, party_guid): if not party: raise BadRequest(f"party not found with party_guid {party_guid}") - permit_amendment = PermitAmendment.find_by_permit_amendment_guid(permit_amendment_guid) if not (permit_amendment): raise BadRequest(f"permit_amendment not found") - - existing_cred_exch = PartyVerifiableCredentialMinesActPermit.find_by_permit_amendment_guid(permit_amendment_guid=permit_amendment_guid) or [] - + + existing_cred_exch = PartyVerifiableCredentialMinesActPermit.find_by_permit_amendment_guid( + permit_amendment_guid=permit_amendment_guid) or [] + # If a user has deleted the credential from their wallet, they will need another copy so only limit on pending for UX reasons - pending_creds = [e for e in existing_cred_exch if e.cred_exch_state in IssueCredentialIssuerState.pending_credential_states] + pending_creds = [ + e for e in existing_cred_exch + if e.cred_exch_state in IssueCredentialIssuerState.pending_credential_states + ] #https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential#states-for-issuer if pending_creds: - raise BadRequest(f"There is a pending credential offer, accept or delete that offer first, cred_exch_id={existing_cred_exch.cred_exch_id}, cred_exch_state={existing_cred_exch.cred_exch_state}") + raise BadRequest( + f"There is a pending credential offer, accept or delete that offer first, cred_exch_id={existing_cred_exch.cred_exch_id}, cred_exch_state={existing_cred_exch.cred_exch_state}" + ) if permit_amendment.permit.mines_act_permit_vc_locked: raise BadRequest(f"This permit cannot be offered as a credential") - - attributes = VerifiableCredentialManager.collect_attributes_for_mines_act_permit_111(permit_amendment) + + attributes = VerifiableCredentialManager.collect_attributes_for_mines_act_permit_111( + permit_amendment) vc_conn = PartyVerifiableCredentialConnection.find_by_party_guid(party_guid) - active_connections = [con for con in vc_conn if con.connection_state in ["active","completed"]] + active_connections = [ + con for con in vc_conn if con.connection_state in ["active", "completed"] + ] if not active_connections: current_app.logger.warning("NO ACTIVE CONNECTION credential not offered") current_app.logger.warning(vc_conn) current_app.logger.warning(attributes) raise BadRequest("Party does not have an active Digital Wallet connection") - else: + else: traction_svc = TractionService() - response = traction_svc.offer_mines_act_permit_111(active_connections[0].connection_id, attributes) - map_vc = PartyVerifiableCredentialMinesActPermit(cred_exch_id = response["credential_exchange_id"],party_guid = party_guid, permit_amendment_guid=permit_amendment_guid) + response = traction_svc.offer_mines_act_permit_111(active_connections[0].connection_id, + attributes) + map_vc = PartyVerifiableCredentialMinesActPermit( + cred_exch_id=response["credential_exchange_id"], + party_guid=party_guid, + permit_amendment_guid=permit_amendment_guid) map_vc.save() return response - \ No newline at end of file diff --git a/services/core-api/app/api/verifiable_credentials/resources/vc_map_detail.py b/services/core-api/app/api/verifiable_credentials/resources/vc_map_detail.py index ce87970419..d77337ee08 100644 --- a/services/core-api/app/api/verifiable_credentials/resources/vc_map_detail.py +++ b/services/core-api/app/api/verifiable_credentials/resources/vc_map_detail.py @@ -12,17 +12,19 @@ class VerifiableCredentialCredentialExchangeResource(Resource, UserMixin): parser = reqparse.RequestParser(trim=True) - parser.add_argument( - 'permit_amendment_guid', location='json', type=str, store_missing=False) - + parser.add_argument('permit_amendment_guid', location='json', type=str, store_missing=False) + @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) def get(self, party_guid, cred_exch_id): if not party_guid: raise BadRequest("party_guid required") - party_credential_exchanges = PartyVerifiableCredentialMinesActPermit.find_by_party_guid(party_guid) + + party_credential_exchanges = PartyVerifiableCredentialMinesActPermit.find_by_party_guid( + party_guid) current_app.logger.info(party_credential_exchanges) - assert cred_exch_id in [str(x.cred_exch_id) for x in party_credential_exchanges], f"cred_exch_id={cred_exch_id} not found" - + assert cred_exch_id in [str(x.cred_exch_id) for x in party_credential_exchanges + ], f"cred_exch_id={cred_exch_id} not found" + cred_exch_details = TractionService().fetch_credential_exchange(cred_exch_id) - return cred_exch_details \ No newline at end of file + return cred_exch_details diff --git a/services/core-api/app/api/verifiable_credentials/resources/vc_revocation.py b/services/core-api/app/api/verifiable_credentials/resources/vc_revocation.py index 1dc7f15fed..af923d47d1 100644 --- a/services/core-api/app/api/verifiable_credentials/resources/vc_revocation.py +++ b/services/core-api/app/api/verifiable_credentials/resources/vc_revocation.py @@ -1,6 +1,6 @@ from flask import current_app from flask_restx import Resource, reqparse -from werkzeug.exceptions import BadRequest, NotImplemented +from werkzeug.exceptions import BadRequest, ServiceUnavailable from app.extensions import api from app.api.utils.access_decorators import requires_any_of, EDIT_PARTY, MINESPACE_PROPONENT @@ -17,24 +17,21 @@ class VerifiableCredentialRevocationResource(Resource, UserMixin): parser = reqparse.RequestParser(trim=True) parser.add_argument( - 'credential_exchange_id', - type=str, - help='GUID of the party.', - location='json', - store_missing=False) + 'credential_exchange_id', + type=str, + help='GUID of the party.', + location='json', + store_missing=False) parser.add_argument( - 'comment', - type=str, - help='GUID of the party.', - location='json', - store_missing=False) + 'comment', type=str, help='GUID of the party.', location='json', store_missing=False) @api.expect(parser) @api.doc(description='Revokes a verifiable credential by party_guid and credential_exchange_id') - @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) + @requires_any_of([EDIT_PARTY]) def post(self, party_guid: str): - if not is_feature_enabled(Feature.TRACTION_VERIFIABLE_CREDENTIALS): - raise NotImplemented() + if not is_feature_enabled(Feature.VC_ANONCREDS_CORE): + raise ServiceUnavailable() + party = Party.find_by_party_guid(party_guid) if not party: raise BadRequest(f"party not found with party_guid {party_guid}") @@ -42,15 +39,19 @@ def post(self, party_guid: str): data = self.parser.parse_args() credential_exchange_id = data["credential_exchange_id"] - credential_exchange = PartyVerifiableCredentialMinesActPermit.find_by_cred_exch_id(credential_exchange_id) + credential_exchange = PartyVerifiableCredentialMinesActPermit.find_by_cred_exch_id( + credential_exchange_id) if not credential_exchange: raise BadRequest(f"credential_exchange_id {credential_exchange_id} not found") - if credential_exchange.cred_exch_state not in ["credential_acked","done"]: - raise VerificableCredentialWorkflowError(f"credential_exchange_id {credential_exchange_id} is not in a state where it can be revoked") - + if credential_exchange.cred_exch_state not in ["credential_acked", "done"]: + raise VerificableCredentialWorkflowError( + f"credential_exchange_id {credential_exchange_id} is not in a state where it can be revoked" + ) traction_svc = TractionService() - revoke_resp = traction_svc.revoke_credential(party.active_digital_wallet_connection.connection_id,credential_exchange.rev_reg_id, credential_exchange.cred_rev_id, data["comment"]) + revoke_resp = traction_svc.revoke_credential( + party.active_digital_wallet_connection.connection_id, credential_exchange.rev_reg_id, + credential_exchange.cred_rev_id, data["comment"]) current_app.logger.info(f"traction revocation response={revoke_resp}") - return revoke_resp \ No newline at end of file + return revoke_resp diff --git a/services/core-api/app/api/verifiable_credentials/resources/w3c_map_credential_resource.py b/services/core-api/app/api/verifiable_credentials/resources/w3c_map_credential_resource.py index 1e437ac5a0..d09046e955 100644 --- a/services/core-api/app/api/verifiable_credentials/resources/w3c_map_credential_resource.py +++ b/services/core-api/app/api/verifiable_credentials/resources/w3c_map_credential_resource.py @@ -1,7 +1,7 @@ from json import dumps, loads from datetime import datetime from flask import current_app, request -from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import BadRequest, ServiceUnavailable from flask_restx import Resource, reqparse from app.api.utils.include.user_info import User from app.api.utils.access_decorators import requires_any_of, MINESPACE_PROPONENT, EDIT_PARTY, VIEW_ALL @@ -50,8 +50,8 @@ class W3CCredentialListResource(Resource, UserMixin): ) @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) def post(self): - if not is_feature_enabled(Feature.JSONLD_MINES_ACT_PERMIT): - raise NotImplementedError("This feature is not enabled.") + if not is_feature_enabled(Feature.VC_W3C): + raise ServiceUnavailable("This feature is not enabled.") data = self.parser.parse_args() permit_amendment = PermitAmendment.find_by_permit_amendment_guid( @@ -85,8 +85,8 @@ class W3CCredentialDeprecatedResource(Resource, UserMixin): ) @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) def post(self): - if not is_feature_enabled(Feature.JSONLD_MINES_ACT_PERMIT): - raise NotImplementedError("This feature is not enabled.") + if not is_feature_enabled(Feature.VC_W3C): + raise ServiceUnavailable("This feature is not enabled.") data = self.parser.parse_args() permit_amendment = PermitAmendment.find_by_permit_amendment_guid( @@ -119,13 +119,12 @@ class W3CCredentialUNTPResource(Resource, UserMixin): @api.expect(parser) @api.doc( description= - "returns a UNTP Conformity Credential for specific permit_amendment using deprecated aca-py endpoint, but with did:indy:bcovrin:test:" + "returns a UNTP Conformity Credential for specific permit_amendment using deprecated aca-py endpoint, but with DEV ONLY did:web" ) @requires_any_of([EDIT_PARTY, MINESPACE_PROPONENT]) def post(self): - if not is_feature_enabled(Feature.JSONLD_MINES_ACT_PERMIT): - raise NotImplementedError("This feature is not enabled.") - current_app.logger.warning("untp endpoint") + if not is_feature_enabled(Feature.VC_W3C): + raise ServiceUnavailable("This feature is not enabled.") data = self.parser.parse_args() permit_amendment = PermitAmendment.find_by_permit_amendment_guid( diff --git a/services/core-web/src/components/parties/PartyProfile.js b/services/core-web/src/components/parties/PartyProfile.js index 6cf1acd687..acf4db6c74 100644 --- a/services/core-web/src/components/parties/PartyProfile.js +++ b/services/core-web/src/components/parties/PartyProfile.js @@ -358,35 +358,30 @@ export class PartyProfile extends Component { )} - {isFeatureEnabled(Feature.VERIFIABLE_CREDENTIALS) && party.party_type_code === "ORG" && ( - <> -
- Digital Wallet Connection Status:{" "} - {VC_CONNECTION_STATES[party?.digital_wallet_connection_status]} - {VC_CONNECTION_STATES[party?.digital_wallet_connection_status] === "Active" && ( - -

- Are you sure you want to delete the digitial wallet connection for - ' - {party.name}'? This is irreversable and destructive. -

-
- } - onConfirm={this.deletePartyWalletConnection} - okText="Yes" - cancelText="No" - > - - - )} - - - )} +
+ Digital Wallet Connection Status:{" "} + {VC_CONNECTION_STATES[party?.digital_wallet_connection_status]} + {VC_CONNECTION_STATES[party?.digital_wallet_connection_status] === "Active" && ( + +

+ Are you sure you want to delete the digitial wallet connection for ' + {party.name}'? This is irreversable and destructive. +

+
+ } + onConfirm={this.deletePartyWalletConnection} + okText="Yes" + cancelText="No" + > + + + )} +
= (props) => { ]; const showVCColumn = - isFeatureEnabled(Feature.VERIFIABLE_CREDENTIALS) && + isFeatureEnabled(Feature.VC_ANONCREDS_MINESPACE) && props.majorMineInd && props.permits.some((p) => { // look for *any* active wallet connections to show the issuance column/action From e9ce8ef3eb54ccec593cc773bd9d71d5d48472fd Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Wed, 17 Jul 2024 11:17:05 -0700 Subject: [PATCH 2/4] missed saves --- .../components/mine/Permit/MinePermitInfo.tsx | 2 +- .../mine/Permit/MinePermitTable.tsx | 22 ------------------- .../mine/permits/PermitTabContainer.tsx | 2 +- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/services/core-web/src/components/mine/Permit/MinePermitInfo.tsx b/services/core-web/src/components/mine/Permit/MinePermitInfo.tsx index ae0c2873d6..b808744744 100644 --- a/services/core-web/src/components/mine/Permit/MinePermitInfo.tsx +++ b/services/core-web/src/components/mine/Permit/MinePermitInfo.tsx @@ -441,7 +441,7 @@ export const MinePermitInfo: FC = (props) => { - {isFeatureEnabled(Feature.VERIFIABLE_CREDENTIALS_2) && ( + {isFeatureEnabled(Feature.VC_ANONCREDS_CORE) && ( = (props) => { - const { isFeatureEnabled } = useFeatureFlag(); const permitColumns = [...columns]; - if (isFeatureEnabled(Feature.VERIFIABLE_CREDENTIALS)) { - const colourMap = { - "Not Active": "#D8292F", - Pending: "#F1C21B", - Active: "#45A776", - }; - - const issuanceColumn = { - title: "VC Issuance State", - dataIndex: "lastAmendedVC", - key: "lastAmendedVC", - render: (text) => { - const badgeText = text ? VC_CRED_ISSUE_STATES[text] : "N/A"; - const colour = colourMap[badgeText] ?? "transparent"; - return ; - }, - }; - - permitColumns.splice(5, 0, issuanceColumn); - } - const amendmentHistory = (permit) => { return permit?.permit_amendments?.map((amendment, index) => transformChildRowData( diff --git a/services/minespace-web/src/components/dashboard/mine/permits/PermitTabContainer.tsx b/services/minespace-web/src/components/dashboard/mine/permits/PermitTabContainer.tsx index c93c3fcb8f..d114e19e56 100644 --- a/services/minespace-web/src/components/dashboard/mine/permits/PermitTabContainer.tsx +++ b/services/minespace-web/src/components/dashboard/mine/permits/PermitTabContainer.tsx @@ -37,7 +37,7 @@ export const PermitTabContainer: FC = ({ permits, ...pr const result = mine.major_mine_ind && - isFeatureEnabled(Feature.VERIFIABLE_CREDENTIALS) && + isFeatureEnabled(Feature.VC_ANONCREDS_MINESPACE) && open_permits.length > 0; return result; }; From fdcd5f9ca6139d0e57f0556f12bcd6997b3e4ccb Mon Sep 17 00:00:00 2001 From: Jason Syrotuck Date: Thu, 18 Jul 2024 14:59:27 -0700 Subject: [PATCH 3/4] snapshots --- .../MinePermitInfo.spec.tsx.snap | 39 ------------------- .../MinePermitTable.spec.tsx.snap | 6 --- 2 files changed, 45 deletions(-) diff --git a/services/core-web/src/tests/components/mine/Permit/__snapshots__/MinePermitInfo.spec.tsx.snap b/services/core-web/src/tests/components/mine/Permit/__snapshots__/MinePermitInfo.spec.tsx.snap index 37bbe44021..7630f3ac46 100644 --- a/services/core-web/src/tests/components/mine/Permit/__snapshots__/MinePermitInfo.spec.tsx.snap +++ b/services/core-web/src/tests/components/mine/Permit/__snapshots__/MinePermitInfo.spec.tsx.snap @@ -198,11 +198,6 @@ exports[`MinePermitInfo renders properly 1`] = ` > Last Amended - - VC Issuance State - - - - - - N/A - - - - - - - - N/A - - - Date: Fri, 19 Jul 2024 14:18:52 -0700 Subject: [PATCH 4/4] remove unused --- .../core-web/src/components/mine/Permit/MinePermitTable.tsx | 3 --- services/core-web/src/components/parties/PartyProfile.js | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/services/core-web/src/components/mine/Permit/MinePermitTable.tsx b/services/core-web/src/components/mine/Permit/MinePermitTable.tsx index cd59ea7ac4..00ab45ba37 100644 --- a/services/core-web/src/components/mine/Permit/MinePermitTable.tsx +++ b/services/core-web/src/components/mine/Permit/MinePermitTable.tsx @@ -1,11 +1,8 @@ import React, { FC } from "react"; -import { Badge } from "antd"; import { withRouter, Link, RouteComponentProps } from "react-router-dom"; import { Menu, Dropdown, Button, Popconfirm } from "antd"; import { PlusOutlined, SafetyCertificateOutlined, ReadOutlined } from "@ant-design/icons"; import { connect } from "react-redux"; -import { Feature, VC_CRED_ISSUE_STATES } from "@mds/common/index"; -import { useFeatureFlag } from "@mds/common/providers/featureFlags/useFeatureFlag"; import { formatDate } from "@common/utils/helpers"; import { getPartyRelationships } from "@mds/common/redux/selectors/partiesSelectors"; import { diff --git a/services/core-web/src/components/parties/PartyProfile.js b/services/core-web/src/components/parties/PartyProfile.js index acf4db6c74..233d3cd156 100644 --- a/services/core-web/src/components/parties/PartyProfile.js +++ b/services/core-web/src/components/parties/PartyProfile.js @@ -45,7 +45,7 @@ import AuthorizationWrapper from "@/components/common/wrappers/AuthorizationWrap import CustomPropTypes from "@/customPropTypes"; import Address from "@/components/common/Address"; import CoreTable from "@mds/common/components/common/CoreTable"; -import { Feature, VC_CONNECTION_STATES, isFeatureEnabled } from "@mds/common"; +import { VC_CONNECTION_STATES } from "@mds/common"; /** * @class PartyProfile - profile view for personnel/companies