Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle real-world Endorser cases in Tenant UI #871

Merged
merged 8 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions charts/traction/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ kubectl delete secret,pvc --selector "app.kubernetes.io/instance"=my-release
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| `ui.enabled` | Deploy tenant-ui | `true` |
| `ui.showOIDCReservationLogin` | Use OIDC to make reservations | `false` |
| `ui.quickConnectEndorserName` | Flag a ledger as auto-accept/endorse so the Tenant UI can quick connect | `""` |
| `ui.image.repository` | | `ghcr.io/bcgov/traction-tenant-ui` |
| `ui.image.pullPolicy` | | `IfNotPresent` |
| `ui.image.pullSecrets` | | `[]` |
Expand Down
1 change: 1 addition & 0 deletions charts/traction/templates/ui/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ data:
FRONTEND_INNKEEPER_SHOW_ADMIN: {{ .Values.ui.oidc.showInnkeeperAdminLogin | quote }}
FRONTEND_TENANT_SHOW_WRITABLE_COMPONENTS: {{ .Values.ui.oidc.showWritableComponents | quote }}
FRONTEND_SHOW_OIDC_RESERVATION_LOGIN: {{ .Values.ui.showOIDCReservationLogin | quote }}
FRONTEND_QUICK_CONNECT_ENDORSER_NAME: {{ .Values.ui.quickConnectEndorserName | quote }}
FRONTEND_SESSION_TIMEOUT_SECONDS: {{ .Values.ui.oidc.session.timeoutSeconds | quote }}
FRONTEND_SESSION_COUNTDOWN_SECONDS: {{ .Values.ui.oidc.session.countdownSeconds | quote }}
FRONTEND_TENANT_PROXY_URL: https://{{ include "tenant_proxy.host" . }}
Expand Down
2 changes: 2 additions & 0 deletions charts/traction/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,8 @@ ui:
enabled: true
## @param ui.oidc.showOIDCReservationLogin OIDC reservation login
showOIDCReservationLogin: false
## @param ui.oidc.quickConnectEndorserName A ledger that has endorser auto-accept/transact enabled
quickConnectEndorserName: ""
image:
## @param ui.image.repository
repository: ghcr.io/bcgov/traction-tenant-ui
Expand Down
1 change: 1 addition & 0 deletions deploy/traction/values-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ tenant_proxy:
network.openshift.io/policy-group: ingress
ui:
showOIDCReservationLogin: false
quickConnectEndorserName: "bcovrin-test-endorser"
image:
pullPolicy: Always
oidc:
Expand Down
1 change: 1 addition & 0 deletions scripts/.env-example
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ UX_COPYRIGHT=2022 © Energy & Mines Digital Trust
UX_OWNER=Owned and operated by the B.C. Government
FRONTEND_ARIES_LEDGER_DESCRIPTION=bcovrin-test
FRONTEND_ACAPY_VERSION_DISPLAY=0.10.3
FRONTEND_QUICK_CONNECT_ENDORSER_NAME=bcovrin-test-endorser

# ------------------------------------------------------------
# ------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions scripts/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ services:
- UX_OWNER=${UX_OWNER}
- FRONTEND_ARIES_LEDGER_DESCRIPTION=${FRONTEND_ARIES_LEDGER_DESCRIPTION}
- FRONTEND_ACAPY_VERSION_DISPLAY=${FRONTEND_ACAPY_VERSION_DISPLAY}
- FRONTEND_QUICK_CONNECT_ENDORSER_NAME=${FRONTEND_QUICK_CONNECT_ENDORSER_NAME}
- SERVER_SMTP_SERVER=maildev
- SERVER_SMTP_PORT=1025
ports:
Expand Down
4 changes: 2 additions & 2 deletions scripts/plugin-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ traction_innkeeper:
]
create_public_did: ["bcovrin-test", "bcovrin-dev"]
reservation:
auto_approve: false
auto_approve: true
expiry_minutes: 2880
auto_issuer: false
auto_issuer: true
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"showInnkeeperAdminLogin": "FRONTEND_INNKEEPER_SHOW_ADMIN",
"showWritableComponents": "FRONTEND_TENANT_SHOW_WRITABLE_COMPONENTS",
"showOIDCReservationLogin": "FRONTEND_SHOW_OIDC_RESERVATION_LOGIN",
"quickConnectEndorserName": "FRONTEND_QUICK_CONNECT_ENDORSER_NAME",
"session": {
"timeoutSeconds": "FRONTEND_SESSION_TIMEOUT_SECONDS",
"countdownSeconds": "FRONTEND_SESSION_COUNTDOWN_SECONDS"
Expand Down
1 change: 1 addition & 0 deletions services/tenant-ui/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"showInnkeeperAdminLogin": true,
"showOIDCReservationLogin": false,
"showWritableComponents": true,
"quickConnectEndorserName": "",
"session": {
"timeoutSeconds": "600",
"countdownSeconds": "30"
Expand Down
143 changes: 36 additions & 107 deletions services/tenant-ui/frontend/src/components/profile/issuance/Endorser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,46 @@
<div v-if="canBecomeIssuer" class="my-1">
<DataTable
v-model:loading="loading"
:value="formattedLedgers"
:value="endorserList"
:paginator="false"
:rows="TABLE_OPT.ROWS_DEFAULT"
:rows-per-page-options="TABLE_OPT.ROWS_OPTIONS"
selection-mode="single"
data-key="ledger_id"
sort-field="ledger_id"
filter-display="menu"
:sort-order="1"
>
<template #empty>{{ $t('common.noRecordsFound') }}</template>
<template #loading>{{ $t('common.loading') }}</template>
<Column :sortable="false" header="Actions">
<Column :sortable="false" header="Connect">
<template #body="{ data }">
<span v-if="isLedgerSet && data.ledger_id === currWriteLedger">
<i class="pi pi-check-circle p-tag-success"></i>
</span>
<EndorserConnect :ledger-info="data" />
</template>
</Column>
<Column :sortable="true" field="ledger_id" header="Ledger" />
<Column :sortable="true" field="endorser_alias" header="Alias">
<template #body="{ data }">
{{ data.endorser_alias }}
<span
v-if="
!isLedgerSet ||
(isLedgerSet &&
enableLedgerSwitch &&
data.ledger_id !== currWriteLedger)
config.frontend.quickConnectEndorserName === data.endorser_alias
"
class="ml-1"
>
<Button
:label="$t('profile.connectToEndorserAndRegisterDID')"
icon="pi pi-check-square"
class="p-button-rounded p-button-icon-only p-button-text"
@click="connecttoLedger(data.ledger_id)"
/>
<i
v-tooltip="
'This Endorser is marked as Quick-Connect (auto accept/endorse)'
"
class="pi pi-bolt"
style="font-size: 0.8rem"
></i>
</span>
</template>
</Column>
<Column
:sortable="true"
field="ledger_id"
header="Ledger Identifier"
></Column>
<Column
:sortable="true"
field="endorser_alias"
header="Endorser Alias"
></Column>
</DataTable>
<div v-if="showNotActiveWarn" class="inactive-endorser">
<i class="pi pi-exclamation-triangle"></i>
{{ $t('profile.connectionNotActiveYet') }}
<p class="mt-0 pl-4">
{{ $t('profile.state', [endorserConnection.state]) }}
</p>
</div>

<div class="mt-3">
Expand All @@ -77,114 +66,54 @@
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
// Vue
import { computed } from 'vue';
// PrimeVue
import DataTable from 'primevue/datatable';
import Button from 'primevue/button';
import Column from 'primevue/column';
import Accordion from 'primevue/accordion';
import AccordionTab from 'primevue/accordiontab';
import VueJsonPretty from 'vue-json-pretty';
import { useToast } from 'vue-toastification';
// State
import { useTenantStore } from '@/store';
import { useConfigStore, useTenantStore } from '@/store';
import { TABLE_OPT } from '@/helpers/constants';
import { storeToRefs } from 'pinia';
// Other Components
import EndorserConnect from './EndorserConnect.vue';

const toast = useToast();

const configStore = useConfigStore();
const tenantStore = useTenantStore();
const { config } = storeToRefs(configStore);
const { endorserConnection, endorserInfo, tenantConfig, writeLedger, loading } =
storeToRefs(tenantStore);
const endorserArr = tenantConfig.value.connect_to_endorser.map(

const endorserList = tenantConfig.value.connect_to_endorser.map(
(config: any) => ({
ledger_id: config.ledger_id,
endorser_alias: config.endorser_alias,
})
);
const formattedLedgers = computed(() => endorserArr);

// Allowed to connect to endorser and register DID?
const canBecomeIssuer = computed(() => {
if (
const canBecomeIssuer = computed(
() =>
tenantConfig.value?.connect_to_endorser?.length &&
tenantConfig.value?.create_public_did?.length
) {
return true;
}
return false;
});

const connecttoLedger = async (ledger_id: string) => {
let prevLedgerId: any = undefined;
if (!!writeLedger.value && !!writeLedger.value.ledger_id) {
prevLedgerId = writeLedger.value.ledger_id;
}
try {
await tenantStore.setWriteLedger(ledger_id);
await connectToEndorser();
await registerPublicDid();
} catch (error) {
if (prevLedgerId) {
try {
await tenantStore.setWriteLedger(prevLedgerId);
await connectToEndorser();
} catch (endorserError) {
toast.error(`${endorserError}`);
}
toast.error(
`${error}, reverting to previously set ledger ${prevLedgerId}`
);
} else {
toast.error(`${error}`);
}
}
};

// Connect to endorser
const connectToEndorser = async () => {
try {
await tenantStore.connectToEndorser();
// Give a couple seconds to wait for active. If not done by then
// a message appears to the user saying to refresh themselves
await tenantStore.waitForActiveEndorserConnection();
await tenantStore.getEndorserConnection();
toast.success('Endorser connection request sent');
} catch (error) {
throw Error(`Failure while connecting: ${error}`);
}
};

// Register DID
const registerPublicDid = async () => {
try {
await tenantStore.registerPublicDid();
toast.success('Public DID registration sent');
} catch (error) {
throw Error(`Failure while registering: ${error}`);
}
};
);

// Details about endorser connection
const showNotActiveWarn = computed(
() => endorserConnection.value && endorserConnection.value.state !== 'active'
);
const isLedgerSet = computed(
() => !!writeLedger.value && !!writeLedger.value.ledger_id
);
// Handler failure logic
const currWriteLedger = computed(() => {
if (!!writeLedger.value && !!writeLedger.value.ledger_id) {
return writeLedger.value.ledger_id;
}
return null;
});
const enableLedgerSwitch = computed(
() => tenantConfig.value.enable_ledger_switch
);
</script>

<style lang="scss" scoped>
@import '@/assets/variables.scss';
.inactive-endorser {
color: $tenant-ui-text-warning;
}

.p-datatable {
border-top: 1px solid $tenant-ui-panel-border-color;
}
</style>
Loading
Loading