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

Expose server settings to Innkeeper UI and Tenant UI via plugin routes #914

Merged
merged 11 commits into from
Nov 16, 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: 0 additions & 1 deletion charts/traction/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,6 @@ kubectl delete secret,pvc --selector "app.kubernetes.io/instance"=my-release
| `ui.ux.copyright` | | `""` |
| `ui.ux.owner` | | `""` |
| `ui.ux.coverImageCopyright` | | `Photo by Kristoffer Fredriksson on StockSnap` |
| `ui.ariesDetails.ledgerDescription` | Ledger description | `bcovrin-test` |
| `ui.oidc.showInnkeeperAdminLogin` | Show Innkeeper Admin Login | `true` |
| `ui.oidc.showWritableComponents` | Show ledger-write UI components | `true` |
| `ui.oidc.active` | Enable OIDC authentication | `true` |
Expand Down
1 change: 0 additions & 1 deletion charts/traction/templates/ui/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ metadata:
labels:
{{- include "tenant-ui.labels" . | nindent 4 }}
data:
FRONTEND_ARIES_LEDGER_DESCRIPTION: {{ .Values.ui.ariesDetails.ledgerDescription | quote }}
FRONTEND_INNKEEPER_OIDC_ACTIVE: {{ .Values.ui.oidc.active | quote }}
FRONTEND_INNKEEPER_OIDC_AUTHORITY: {{ .Values.ui.oidc.authority | quote }}
FRONTEND_INNKEEPER_OIDC_CLIENT: {{ .Values.ui.oidc.client | quote }}
Expand Down
4 changes: 0 additions & 4 deletions charts/traction/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -622,10 +622,6 @@ ui:
## @param ui.ux.infoBanner.showMessage Show the info banner <boolean>
showMessage: false

ariesDetails:
## @param ui.ariesDetails.ledgerDescription Ledger description
ledgerDescription: "bcovrin-test"

## Backend Configuration
##
oidc:
Expand Down
2 changes: 0 additions & 2 deletions deploy/traction/values-development.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ ui:
]
}
}
ariesDetails:
ledgerDescription: "bcovrin-test"
smtp:
server: apps.smtp.gov.bc.ca
port: 25
Expand Down
2 changes: 0 additions & 2 deletions deploy/traction/values-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ ui:
]
}
}
ariesDetails:
ledgerDescription: "bcovrin-test"
smtp:
server: apps.smtp.gov.bc.ca
port: 25
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use_kwargs,
)
from aries_cloudagent.admin.request_context import AdminRequestContext
from aries_cloudagent.admin.server import AdminConfigSchema
from aries_cloudagent.messaging.models.base import BaseModelError
from aries_cloudagent.messaging.models.openapi import OpenAPISchema
from aries_cloudagent.messaging.valid import JSONWebToken, UUIDFour
Expand All @@ -21,6 +22,7 @@
from aries_cloudagent.multitenant.base import BaseMultitenantManager
from aries_cloudagent.multitenant.error import WalletKeyMissingError
from aries_cloudagent.storage.error import StorageError, StorageNotFoundError
from aries_cloudagent.version import __version__
from aries_cloudagent.wallet.error import WalletSettingsError
from aries_cloudagent.wallet.models.wallet_record import WalletRecord
from marshmallow import fields, validate
Expand Down Expand Up @@ -917,6 +919,41 @@ async def innkeeper_authentications_api_delete(request: web.BaseRequest):
return web.json_response({"success": result})


@docs(tags=[SWAGGER_CATEGORY], summary="Fetch the server configuration")
@response_schema(AdminConfigSchema(), 200, description="")
@innkeeper_only
@error_handler
async def innkeeper_config_handler(request: web.BaseRequest):
context: AdminRequestContext = request["context"]
# use base/root profile for server config, use Tenant Manager profile
# this is to not get the Innkeeper tenant's config, but the server cfg
mgr = context.inject(TenantManager)
profile = mgr.profile

config = {
key: (
profile.context.settings[key]
)
for key in profile.context.settings
if key
not in [
"admin.admin_api_key",
"multitenant.jwt_secret",
"wallet.key",
"wallet.rekey",
"wallet.seed",
"wallet.storage_creds",
]
}
try:
del config["plugin_config"]["traction_innkeeper"]["innkeeper_wallet"]["wallet_key"]
except KeyError as e:
LOGGER.warn(f"The key to be removed: '{e.args[0]}' is missing from the dictionary.")
config["version"] = __version__

return web.json_response({"config": config})


async def register(app: web.Application):
"""Register routes."""
LOGGER.info("> registering routes")
Expand Down Expand Up @@ -987,6 +1024,11 @@ async def register(app: web.Application):
"/innkeeper/authentications/api/{tenant_authentication_api_id}",
innkeeper_authentications_api_delete,
),
web.get(
"/innkeeper/server/status/config",
innkeeper_config_handler,
allow_head=False,
),
]
)
LOGGER.info("< registering routes")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
request_schema,
)
from aries_cloudagent.admin.request_context import AdminRequestContext
from aries_cloudagent.admin.server import AdminConfigSchema
from aries_cloudagent.messaging.models.openapi import OpenAPISchema
from aries_cloudagent.multitenant.admin.routes import (
format_wallet_record,
Expand All @@ -16,6 +17,7 @@
)
from aries_cloudagent.multitenant.base import BaseMultitenantManager
from aries_cloudagent.storage.error import StorageNotFoundError
from aries_cloudagent.version import __version__
from aries_cloudagent.wallet.models.wallet_record import (
WalletRecordSchema,
WalletRecord,
Expand Down Expand Up @@ -352,6 +354,55 @@ async def tenant_api_key_delete(request: web.BaseRequest):
return web.json_response({"success": result})


@docs(tags=[SWAGGER_CATEGORY], summary="Fetch the server configuration")
@response_schema(AdminConfigSchema(), 200, description="")
@error_handler
async def tenant_server_config_handler(request: web.BaseRequest):
context: AdminRequestContext = request["context"]
# use base/root profile for server config, use Tenant Manager profile
# this is to not get the Innkeeper tenant's config, but the server cfg
mgr = context.inject(TenantManager)
profile = mgr.profile

config = {
k: (
profile.context.settings[k]
)
for k in profile.context.settings
if k
not in [
"default_label",
"admin.admin_api_key",
"admin.admin_insecure_mode",
"admin.enabled",
"admin.host",
"admin.port",
"admin.webhook_urls",
"admin.admin_client_max_request_size",
"multitenant.jwt_secret",
"wallet.key",
"wallet.name",
"multitenant.wallet_name",
"wallet.storage_type",
"wallet.storage_config",
"wallet.rekey",
"wallet.seed",
"wallet.storage_creds",
]
}
try:
del config["plugin_config"]["traction_innkeeper"]["innkeeper_wallet"]
config["config"]["ledger.ledger_config_list"] = [
{k: v for k, v in d.items() if k != "genesis_transactions"}
for d in config["config"]["ledger.ledger_config_list"]
]
except KeyError as e:
LOGGER.warn(f"The key to be removed: '{e.args[0]}' is missing from the dictionary.")
config["version"] = __version__

return web.json_response({"config": config})


async def register(app: web.Application):
"""Register routes."""
LOGGER.info("> registering routes")
Expand All @@ -376,6 +427,11 @@ async def register(app: web.Application):
"/tenant/authentications/api/{tenant_authentication_api_id}",
tenant_api_key_delete,
),
web.get(
"/tenant/server/status/config",
tenant_server_config_handler,
allow_head=False
),
]
)
LOGGER.info("< registering routes")
Expand Down
6 changes: 0 additions & 6 deletions services/tenant-ui/config/custom-environment-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@
"messageLevel": "UX_INFO_BANNER_MESSAGE_LEVEL",
"showMessage": "UX_INFO_BANNER_SHOW_MESSAGE"
}
},
"ariesDetails": {
"acapyVersion": "FRONTEND_ACAPY_VERSION_DISPLAY",
"ledgerName": "FRONTEND_ARIES_LEDGER_DESCRIPTION",
"ledgerBrowser": "ACAPY_LEDGER_BROWSER_URL",
"tailsServer": "ACAPY_TAILS_BASE_URL"
}
},
"image": {
Expand Down
6 changes: 0 additions & 6 deletions services/tenant-ui/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@
"messageLevel": "info",
"showMessage": false
}
},
"ariesDetails": {
"acapyVersion": "0.10.3",
"ledgerName": "bcovrin-test",
"ledgerBrowser": "http://test.bcovrin.vonx.io",
"tailsServer": "https://tails-test.vonx.io"
}
},
"image": {
Expand Down
72 changes: 30 additions & 42 deletions services/tenant-ui/frontend/src/components/about/Acapy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<p class="mt-0">
{{
$t('about.acaPy.acapyVersion', {
version: config.frontend.ariesDetails.acapyVersion,
version: acapyVersion,
})
}}
</p>
Expand All @@ -16,55 +16,43 @@
</div>

<div class="grid">
<div class="col-2">
{{ $t('about.acaPy.ledger') }}
</div>
<div class="col-10">
{{ config.frontend.ariesDetails.ledgerName }}
</div>

<div class="col-2">
{{ $t('about.acaPy.ledgerBrowser') }}
</div>
<div class="col-10">
{{ config.frontend.ariesDetails.ledgerBrowser }}
</div>

<div class="col-2">
{{ $t('about.acaPy.tailsServer') }}
</div>
<div class="col-10">
{{ config.frontend.ariesDetails.tailsServer }}
</div>
</div>

<div class="grid mt-4">
<div class="col-12 md:col-6 lg:col-4">
<Accordion>
<AccordionTab :header="$t('about.acaPy.plugins')">
<div v-if="loading" class="flex justify-content-center">
<ProgressSpinner />
</div>
<vue-json-pretty v-else :data="acapyPlugins" />
</AccordionTab>
</Accordion>
<PluginList />
</div>
</div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useConfigStore } from '@/store/configStore';
import { useInnkeeperTenantsStore, useTenantStore } from '@/store';
// PrimeVue
import Accordion from 'primevue/accordion';
import AccordionTab from 'primevue/accordiontab';
import ProgressSpinner from 'primevue/progressspinner';
import VueJsonPretty from 'vue-json-pretty';

const { acapyPlugins, config, loading } = storeToRefs(useConfigStore());
const configStore = useConfigStore();

configStore.getPluginList();
import PluginList from './PluginList.vue';

const route = useRoute();
const innTenantsStore = useInnkeeperTenantsStore();
const tenantsStore = useTenantStore();
const { serverConfig: innServerConfig } = storeToRefs(
useInnkeeperTenantsStore()
);
const { serverConfig } = storeToRefs(useTenantStore());

const acapyVersion = ref('');
const currentRouteName = computed(() => {
return route.name;
});

onMounted(async () => {
// Depending on if you're the innkeeper these setttings are different
if (currentRouteName.value === 'InnkeeperAbout') {
await innTenantsStore.getServerConfig();
acapyVersion.value = innServerConfig.value?.config?.version;
} else {
await tenantsStore.getServerConfig();
acapyVersion.value = serverConfig.value?.config?.version;
}
});
</script>

<style scoped>
Expand Down
31 changes: 31 additions & 0 deletions services/tenant-ui/frontend/src/components/about/PluginList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<Accordion>
<AccordionTab :header="$t('about.acaPy.plugins')">
<div v-if="loading" class="flex justify-content-center">
<ProgressSpinner />
</div>
<vue-json-pretty v-else :data="acapyPlugins" />
</AccordionTab>
</Accordion>
</template>

<script setup lang="ts">
import { storeToRefs } from 'pinia';
import { useConfigStore } from '@/store/configStore';
// PrimeVue
import Accordion from 'primevue/accordion';
import AccordionTab from 'primevue/accordiontab';
import ProgressSpinner from 'primevue/progressspinner';
import VueJsonPretty from 'vue-json-pretty';

const { acapyPlugins, loading } = storeToRefs(useConfigStore());
const configStore = useConfigStore();

configStore.getPluginList();
</script>

<style scoped>
.logo-acapy {
width: 14em;
}
</style>
32 changes: 32 additions & 0 deletions services/tenant-ui/frontend/src/components/common/ConfigItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<p>
<strong v-if="props.title">
{{ title }}{{ $t('common.configDelim') }}
</strong>
<strong v-else>
<slot name="title"></slot>{{ $t('common.configDelim') }}
</strong>

<span v-if="contentToString">{{ props.content }}</span>
<slot v-else name="content"></slot>
</p>
</template>

<script setup lang="ts">
import { computed } from 'vue';

// Can pass in the fields as props, or use slots if more customization needed
const props = withDefaults(
defineProps<{
title?: string;
content?: string | number | boolean;
}>(),
{
title: '',
content: '',
}
);
const contentToString = computed(() =>
typeof props.content === 'boolean' ? props.content.toString() : props.content
);
</script>
Loading
Loading