Skip to content

Commit

Permalink
feat(website,kubernetes): make it possible to disable login and submi…
Browse files Browse the repository at this point in the history
…t flow on website (#3223)

* chore(website): delete unused function

* fix(website): delete duplicate "to" in sentence

It would show "Please select the organism for which you want to to browse data:"

* feat(website,kubernetes): make it possible to disable login and submit flow on website

resolves #3211

* chore(website): delete unused types

* docs: add missing spec for `website.runtimeConfig`
  • Loading branch information
fengelniederhammer authored Nov 19, 2024
1 parent c0959b7 commit a6b3bb7
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 48 deletions.
77 changes: 77 additions & 0 deletions docs/src/content/docs/reference/helm-chart-config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,77 @@ The configuration for the Helm chart is provided as a YAML file. It has the foll
</table>
</div>

## Website Settings

<div className='overflow-x-scroll'>
<table className='min-w-[700px]'>
<thead>
<tr>
<th className='w-56'>Field</th>
<th>Type</th>
<th className='w-32'>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>`website`</td>
<td>Object</td>
<td></td>
<td>Website specific setting</td>
</tr>
<tr>
<td>`website.websiteConfig`</td>
<td>Object</td>
<td></td>
<td>Settings for the `website_config.json`</td>
</tr>
<tr>
<td>`website.websiteConfig.enableLoginNavigationItem`</td>
<td>Boolean</td>
<td>true</td>
<td>Whether the website should show the login button.</td>
</tr>
<tr>
<td>`website.websiteConfig.enableSubmissionNavigationItem`</td>
<td>Boolean</td>
<td>true</td>
<td>Whether the website should show "Submit" link in the top navigation bar.</td>
</tr>
<tr>
<td>`website.websiteConfig.enableSubmissionPages`</td>
<td>Boolean</td>
<td>true</td>
<td>Whether to completely disable submission related pages. Setting this to false is useful when hosting Loculus for analysis-only purposes.</td>
</tr>
<tr>
<td>`website.runtimeConfig.public`</td>
<td>Object</td>
<td></td>
<td>Settings for the `public` section of the `runtime_config.json`</td>
</tr>
<tr>
<td>`website.runtimeConfig.public.backendUrl`</td>
<td>String</td>
<td>true</td>
<td>Overwrite the URL where the client-side website code expects the Loculus backend</td>
</tr>
<tr>
<td>`website.runtimeConfig.public.keycloakUrl`</td>
<td>String</td>
<td>true</td>
<td>Overwrite the URL where the client-side website code expects the Keycloak</td>
</tr>
<tr>
<td>`website.runtimeConfig.public.lapisUrlTemplate`</td>
<td>String</td>
<td>true</td>
<td>Overwrite the URLs where the client-side website code expects the LAPIS instances. Must contain `%organism%` as a placeholder.</td>
</tr>
</tbody>
</table>
</div>

## User registration and authentication

<table>
Expand Down Expand Up @@ -236,6 +307,12 @@ The configuration for the Helm chart is provided as a YAML file. It has the foll
<td>true</td>
<td>If true, allows users to reset their passwords</td>
</tr>
<tr>
<td>`auth.registrationAllowed`</td>
<td>Boolean</td>
<td>true</td>
<td>If true, allows users to register new accounts in Keycloak.</td>
</tr>
<tr>
<td>`insecureCookies`</td>
<td>Boolean</td>
Expand Down
3 changes: 3 additions & 0 deletions kubernetes/loculus/templates/_common-metadata.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ welcomeMessageHTML: {{ quote $.Values.welcomeMessageHTML }}
additionalHeadHTML: {{ quote $.Values.additionalHeadHTML }}
{{end}}

enableLoginNavigationItem: {{ $.Values.website.websiteConfig.enableLoginNavigationItem }}
enableSubmissionNavigationItem: {{ $.Values.website.websiteConfig.enableSubmissionNavigationItem }}
enableSubmissionPages: {{ $.Values.website.websiteConfig.enableSubmissionPages }}
enableSeqSets: {{ $.Values.seqSets.enabled }}
accessionPrefix: {{ quote $.Values.accessionPrefix }}
{{- $commonMetadata := (include "loculus.commonMetadata" . | fromYaml).fields }}
Expand Down
5 changes: 5 additions & 0 deletions kubernetes/loculus/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ disableBackend: false
disablePreprocessing: false
disableIngest: false
disableEnaSubmission: true
website:
websiteConfig:
enableLoginNavigationItem: true
enableSubmissionNavigationItem: true
enableSubmissionPages: true
siloImportLimitSeconds: 3600
ingestLimitSeconds: 1800
getSubmissionListLimitSeconds: 600
Expand Down
4 changes: 0 additions & 4 deletions website/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ export function getWebsiteConfig(): WebsiteConfig {
return _config;
}

export function getWebsiteName(): string {
return getWebsiteConfig().name;
}

export function getMetadataDisplayNames(organism: string): Map<string, string> {
return new Map(
getWebsiteConfig().organisms[organism].schema.metadata.map(({ name, displayName }) => [
Expand Down
9 changes: 8 additions & 1 deletion website/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { sequence } from 'astro:middleware';

import { getWebsiteConfig } from './config.ts';
import { authMiddleware } from './middleware/authMiddleware.ts';
import { catchErrorMiddleware } from './middleware/catchErrorMiddleware.ts';
import { organismValidatorMiddleware } from './middleware/organismValidatorMiddleware.ts';
import { submissionPagesDisablingMiddleware } from './middleware/submissionPagesDisablingMiddleware.ts';

const middlewares = [catchErrorMiddleware, organismValidatorMiddleware, authMiddleware];
if (!getWebsiteConfig().enableSubmissionPages) {
middlewares.push(submissionPagesDisablingMiddleware);
}

// Astro middleware
export const onRequest = sequence(catchErrorMiddleware, organismValidatorMiddleware, authMiddleware);
export const onRequest = sequence(...middlewares);
11 changes: 11 additions & 0 deletions website/src/middleware/submissionPagesDisablingMiddleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineMiddleware } from 'astro/middleware';

export const submissionPagesDisablingMiddleware = defineMiddleware(async (context, next) => {
const organism = context.params.organism;

if (organism !== undefined && context.url.pathname.includes(`${organism}/submission`)) {
return context.rewrite('/404');
}

return next();
});
29 changes: 16 additions & 13 deletions website/src/pages/organism-selector/[redirectTo].astro
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
---
import { NeedAGroup } from '../../components/common/NeedAGroup.tsx';
import NeedToLogin from '../../components/common/NeedToLogin.astro';
import { getConfiguredOrganisms } from '../../config';
import { getConfiguredOrganisms, getWebsiteConfig } from '../../config';
import BaseLayout from '../../layouts/BaseLayout.astro';
import { routes } from '../../routes/routes';
import { GroupManagementClient } from '../../services/groupManagementClient';
import { getAccessToken } from '../../utils/getAccessToken';
const redirectTo = Astro.params.redirectTo;
const accessToken = getAccessToken(Astro.locals.session)!;
const groupsResult = await GroupManagementClient.create().getGroupsOfUser(accessToken);
type ValidRedirectTo = 'submission' | 'search';
const purposes: { [key: string]: string } = {
submission: 'to access the submission portal',
const purposes: Partial<Record<ValidRedirectTo, string>> = {
search: 'to browse data',
};
if (getWebsiteConfig().enableSubmissionPages) {
purposes.submission = 'to access the submission portal';
}
interface Routes {
[key: string]: (organism: string) => string;
if (!(Astro.params.redirectTo! in purposes)) {
return Astro.rewrite('/404');
}
const redirectTo = Astro.params.redirectTo as ValidRedirectTo;
const myRoutes: Routes = {
const accessToken = getAccessToken(Astro.locals.session)!;
const groupsResult = await GroupManagementClient.create().getGroupsOfUser(accessToken);
const myRoutes = {
submission: routes.submissionPageWithoutGroup,
search: routes.searchPage,
};
const purpose = purposes[redirectTo!];
const purpose = purposes[redirectTo];
// Prevent caching to allow back button after user creates group
Astro.response.headers.append('Cache-Control', 'no-cache, no-store, must-revalidate');
Expand All @@ -45,11 +48,11 @@ const requiresGroup = redirectTo === 'submission';
<NeedAGroup />
) : (
<div>
<p class='text-gray-700 my-4'>Please select the organism for which you want to {purpose}:</p>
<p class='text-gray-700 my-4'>Please select the organism for which you want {purpose}:</p>
<div class='flex flex-wrap'>
{getConfiguredOrganisms().map(({ key, displayName }) => (
<a
href={myRoutes[redirectTo!](key)}
href={myRoutes[redirectTo](key)}
class='block rounded border border-gray-300 p-4 m-2 w-64 text-center hover:bg-gray-100'
>
<h3 class='font-semibold text-gray-700'>{displayName}</h3>
Expand Down
47 changes: 28 additions & 19 deletions website/src/routes/navigationItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,23 @@ export const navigationItems = {
export type TopNavigationItems = ReturnType<(typeof navigationItems)['top']>;

function getSequenceRelatedItems(organism: string | undefined) {
return [
{
text: 'Browse',
path: organism !== undefined ? routes.searchPage(organism) : routes.organismSelectorPage('search'),
},
{
text: 'Submit',
path:
organism !== undefined
? routes.submissionPageWithoutGroup(organism)
: routes.organismSelectorPage('submission'),
},
];
const browseItem = {
text: 'Browse',
path: organism !== undefined ? routes.searchPage(organism) : routes.organismSelectorPage('search'),
};

if (!getWebsiteConfig().enableSubmissionNavigationItem) {
return [browseItem];
}

const submitItem = {
text: 'Submit',
path:
organism !== undefined
? routes.submissionPageWithoutGroup(organism)
: routes.organismSelectorPage('submission'),
};
return [browseItem, submitItem];
}

function getSeqSetsItems() {
Expand All @@ -39,22 +43,27 @@ function getSeqSetsItems() {
];
}

function getAccountItem(isLoggedIn: boolean, loginUrl: string | undefined, organism: string | undefined) {
return isLoggedIn
function getAccountItems(isLoggedIn: boolean, loginUrl: string, organism: string | undefined) {
if (!getWebsiteConfig().enableLoginNavigationItem) {
return [];
}

const accountItem = isLoggedIn
? {
text: 'My account',
path: organism !== undefined ? routes.userOverviewPage(organism) : routes.userOverviewPage(),
}
: {
text: 'Login',
path: loginUrl!,
path: loginUrl,
};
return [accountItem];
}

function topNavigationItems(organism: string | undefined, isLoggedIn: boolean, loginUrl: string | undefined) {
function topNavigationItems(organism: string | undefined, isLoggedIn: boolean, loginUrl: string) {
const sequenceRelatedItems = getSequenceRelatedItems(organism);
const seqSetsItems = getSeqSetsItems();
const accountItem = getAccountItem(isLoggedIn, loginUrl, organism);
const accountItems = getAccountItems(isLoggedIn, loginUrl, organism);

return [...sequenceRelatedItems, ...seqSetsItems, ...extraTopNavigationItems, accountItem];
return [...sequenceRelatedItems, ...seqSetsItems, ...extraTopNavigationItems, ...accountItems];
}
14 changes: 3 additions & 11 deletions website/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,6 @@ export type GroupedMetadataFilter = {
initiallyVisible?: boolean;
};

export type AccessionFilter = {
accession?: string[];
};

export type MutationFilter = {
aminoAcidMutationQueries?: string[];
nucleotideMutationQueries?: string[];
aminoAcidInsertionQueries?: string[];
nucleotideInsertionQueries?: string[];
};

const schema = z.object({
organismName: z.string(),
image: z.string().optional(),
Expand Down Expand Up @@ -121,6 +110,9 @@ export const websiteConfig = z.object({
gitHubEditLink: z.string().optional(),
gitHubMainUrl: z.string().optional(),
enableSeqSets: z.boolean(),
enableLoginNavigationItem: z.boolean(),
enableSubmissionNavigationItem: z.boolean(),
enableSubmissionPages: z.boolean(),
});
export type WebsiteConfig = z.infer<typeof websiteConfig>;

Expand Down

0 comments on commit a6b3bb7

Please sign in to comment.