Skip to content

Commit c65c259

Browse files
Merge pull request galaxyproject#21234 from nuwang/combine_psa_keycloak
Reimplement keycloak/cilogon as PSA providers and remove custos
2 parents f782a4c + ac326ef commit c65c259

41 files changed

Lines changed: 5382 additions & 3790 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

client/src/components/Login/LoginForm.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe("LoginForm", () => {
4545
axiosMock = new MockAdapter(axios);
4646
server.use(
4747
http.get("/api/configuration", ({ response }) => {
48-
return response.untyped(HttpResponse.json({ oidc: { cilogon: false, custos: false } }));
48+
return response.untyped(HttpResponse.json({ oidc: { cilogon: false } }));
4949
}),
5050
);
5151
});

client/src/components/Register/RegisterForm.vue

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ interface Props {
3232
enableOidc?: boolean;
3333
mailingJoinAddr?: string;
3434
oidcIdps?: OIDCConfig;
35-
preferCustosLogin?: boolean;
35+
preferOidcLogin?: boolean;
3636
redirect?: string;
3737
registrationWarningMessage?: string;
3838
serverMailConfigured?: boolean;
@@ -58,8 +58,8 @@ const labelSubscribe = ref(localize("Stay in the loop and join the galaxy-announ
5858
5959
const idpsWithRegistration = computed(() => (props.oidcIdps ? getOIDCIdpsWithRegistration(props.oidcIdps) : {}));
6060
61-
const custosPreferred = computed(() => {
62-
return props.enableOidc && props.preferCustosLogin;
61+
const oidcPreferred = computed(() => {
62+
return props.enableOidc && props.preferOidcLogin;
6363
});
6464
6565
/** This decides if all register options should be displayed in column style
@@ -107,30 +107,30 @@ async function submit() {
107107

108108
<BForm id="registration" @submit.prevent="submit()">
109109
<BCard no-body>
110-
<!-- OIDC and Custos enabled and prioritized: encourage users to use it instead of local registration -->
111-
<span v-if="custosPreferred">
110+
<!-- OIDC enabled and prioritized: encourage users to use it instead of local registration -->
111+
<span v-if="oidcPreferred">
112112
<BCardHeader v-b-toggle.accordion-oidc role="button">
113113
Register using institutional account
114114
</BCardHeader>
115115

116116
<BCollapse id="accordion-oidc" visible role="tabpanel" accordion="registration_acc">
117117
<BCardBody>
118118
Create a Galaxy account using an institutional account (e.g.:Google/JHU). This will
119-
redirect you to your institutional login through Custos.
119+
redirect you to your institutional login through OIDC.
120120
<ExternalLogin class="mt-2" />
121121
</BCardBody>
122122
</BCollapse>
123123
</span>
124124

125125
<!-- Local Galaxy Registration -->
126-
<BCardHeader v-if="!custosPreferred" v-localize>Create a Galaxy account</BCardHeader>
126+
<BCardHeader v-if="!oidcPreferred" v-localize>Create a Galaxy account</BCardHeader>
127127
<BCardHeader v-else v-localize v-b-toggle.accordion-register role="button">
128128
Or, register with email
129129
</BCardHeader>
130130

131131
<BCollapse
132132
id="accordion-register"
133-
:visible="!custosPreferred"
133+
:visible="!oidcPreferred"
134134
role="tabpanel"
135135
accordion="registration_acc">
136136
<BCardBody :class="{ 'd-flex w-100': !registerColumnDisplay }">

client/src/components/User/ExternalIdentities/ExternalIDHelper.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export type OIDCConfigWithRegistration = Record<
2626

2727
/** Return the per-IDP config, minus anything the caller wants to hide. */
2828
export function getFilteredOIDCIdps(oidcConfig: OIDCConfig, exclude: string[] = []): OIDCConfig {
29-
const blacklist = new Set(["cilogon", "custos", ...exclude]);
29+
const blacklist = new Set(["cilogon", ...exclude]);
3030
const filtered: OIDCConfig = {};
3131
Object.entries(oidcConfig).forEach(([idp, cfg]) => {
3232
if (!blacklist.has(idp)) {
@@ -51,11 +51,11 @@ export function getOIDCIdpsWithRegistration(oidcConfig: OIDCConfig): OIDCConfigW
5151

5252
/** Do we need to show the institution picker at all? */
5353
export const getNeedShowCilogonInstitutionList = (cfg: OIDCConfig): boolean => {
54-
return Boolean(cfg.cilogon || cfg.custos);
54+
return Boolean(cfg.cilogon);
5555
};
5656

5757
/**
58-
* Generic OIDC login (all providers *except* CILogon/Custos).
58+
* Generic OIDC login (all providers *except* CILogon).
5959
* Returns the redirect URI Galaxy gives back, or throws.
6060
*/
6161
export async function submitOIDCLogon(idp: string, redirectParam: string | null = null): Promise<string | null> {
@@ -73,13 +73,12 @@ export async function submitOIDCLogon(idp: string, redirectParam: string | null
7373
}
7474

7575
/**
76-
* CILogon/Custos login.
77-
* @param idp "cilogon" | "custos"
76+
* CILogon login.
7877
* @param useIDPHint If true, append ?idphint=
7978
* @param idpHint The entityID to hint with (ignored when useIDPHint = false)
8079
*/
81-
export async function submitCILogon(idp: string, useIDPHint = false, idpHint?: string): Promise<string | null> {
82-
let url = withPrefix(`/authnz/${idp}/login/`);
80+
export async function submitCILogon(useIDPHint = false, idpHint?: string): Promise<string | null> {
81+
let url = withPrefix("/authnz/cilogon/login/");
8382
if (useIDPHint && idpHint) {
8483
url += `?idphint=${encodeURIComponent(idpHint)}`;
8584
}
@@ -108,8 +107,8 @@ export async function redirectToSingleProvider(config: OIDCConfig): Promise<stri
108107
throw new Error("OIDC provider key is undefined.");
109108
}
110109

111-
if (idp === "cilogon" || idp === "custos") {
112-
const redirectUri = await submitCILogon(idp, false);
110+
if (idp === "cilogon") {
111+
const redirectUri = await submitCILogon(false);
113112
return redirectUri;
114113
} else {
115114
const redirectUri = await submitOIDCLogon(idp, "");

client/src/components/User/ExternalIdentities/ExternalIdentities.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ export default {
121121
doomedItem: null,
122122
errorMessage: null,
123123
enable_oidc: galaxy.config.enable_oidc,
124-
cilogonOrCustos: null,
125124
userEmail: galaxy.user.get("email"),
126125
};
127126
},

client/src/components/User/ExternalIdentities/ExternalLogin.vue

Lines changed: 15 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { errorMessageAsString } from "@/utils/simple-error";
1717
import { capitalizeFirstLetter } from "@/utils/strings";
1818
1919
import GButton from "@/components/BaseComponents/GButton.vue";
20-
import GButtonGroup from "@/components/BaseComponents/GButtonGroup.vue";
2120
import VerticalSeparator from "@/components/Common/VerticalSeparator.vue";
2221
import LoadingSpan from "@/components/LoadingSpan.vue";
2322
@@ -50,34 +49,22 @@ const messageVariant = ref<string | null>(null);
5049
const cILogonIdps = ref<Idp[]>([]);
5150
const selected = ref<Idp | null>(null);
5251
const rememberIdp = ref(false);
53-
const cilogonOrCustos = ref<"cilogon" | "custos" | null>(null);
54-
const toggleCilogon = ref(false);
5552
5653
const oIDCIdps = computed<OIDCConfig>(() => (isConfigLoaded.value ? config.value.oidc : {}));
5754
5855
const filteredOIDCIdps = computed(() => getFilteredOIDCIdps(oIDCIdps.value, props.excludeIdps));
5956
60-
const cilogonListShow = computed(() => getNeedShowCilogonInstitutionList(oIDCIdps.value));
61-
62-
const cILogonEnabled = computed(() => oIDCIdps.value.cilogon);
63-
const custosEnabled = computed(() => oIDCIdps.value.custos);
57+
const cILogonConfigured = computed(() => getNeedShowCilogonInstitutionList(oIDCIdps.value));
6458
6559
onMounted(async () => {
6660
rememberIdp.value = getIdpPreference() !== null;
6761
68-
// Only fetch CILogonIDPs if custos/cilogon configured
69-
if (cilogonListShow.value) {
62+
// Only fetch CILogonIDPs if cilogon configured
63+
if (cILogonConfigured.value) {
7064
await getCILogonIdps();
7165
}
7266
});
7367
74-
function toggleCILogon(idp: "cilogon" | "custos") {
75-
if (cilogonOrCustos.value === idp || cilogonOrCustos.value === null) {
76-
toggleCilogon.value = !toggleCilogon.value;
77-
}
78-
cilogonOrCustos.value = toggleCilogon.value ? idp : null;
79-
}
80-
8168
async function clickOIDCLogin(idp: string) {
8269
if (loading.value) {
8370
return;
@@ -99,15 +86,15 @@ async function clickOIDCLogin(idp: string) {
9986
}
10087
}
10188
102-
async function clickCILogin(idp: string | null) {
89+
async function clickCILogonLogin() {
10390
if (loading.value) {
10491
return;
10592
}
10693
if (props.loginPage) {
10794
setIdpPreference();
10895
}
10996
110-
if (!selected.value || !idp) {
97+
if (!selected.value) {
11198
messageVariant.value = "danger";
11299
messageText.value = "Please select an institution.";
113100
return;
@@ -116,9 +103,9 @@ async function clickCILogin(idp: string | null) {
116103
loading.value = true;
117104
118105
try {
119-
const redirectUri = await submitCILogon(idp, true, selected.value.EntityID);
106+
const redirectUri = await submitCILogon(true, selected.value.EntityID);
120107
121-
localStorage.setItem("galaxy-provider", idp);
108+
localStorage.setItem("galaxy-provider", "cilogon");
122109
123110
if (redirectUri) {
124111
window.location.href = redirectUri;
@@ -183,11 +170,9 @@ function getIdpPreference() {
183170
</BAlert>
184171

185172
<div :class="{ 'd-flex h-100': !props.columnDisplay }">
186-
<!-- OIDC login-->
187-
<BForm v-if="cilogonListShow" id="externalLogin" class="cilogon">
188-
<div v-if="props.loginPage">
189-
<!--Only Display if CILogon/Custos is configured-->
190-
<BFormGroup label="Use existing institutional login">
173+
<BForm v-if="cILogonConfigured" id="externalLogin" class="cilogon">
174+
<div>
175+
<BFormGroup :label="`Use ${props.loginPage ? `existing` : ``} institutional login`">
191176
<Multiselect
192177
v-model="selected"
193178
placeholder="Select your institution"
@@ -205,72 +190,23 @@ function getIdpPreference() {
205190
</BFormCheckbox>
206191
</BFormGroup>
207192

208-
<GButton
209-
v-if="cILogonEnabled"
210-
:disabled="loading || selected === null"
211-
@click="clickCILogin('cilogon')">
193+
<GButton :disabled="loading || selected === null" @click="clickCILogonLogin">
212194
<LoadingSpan v-if="loading" message="Signing In" />
213195
<span v-else>Sign in with Institutional Credentials*</span>
214196
</GButton>
215-
<!--convert to v-else-if to allow only one or the other. if both enabled, put the one that should be default first-->
216-
<GButton
217-
v-if="Object.prototype.hasOwnProperty.call(oIDCIdps, 'custos')"
218-
:disabled="loading || selected === null"
219-
@click="clickCILogin('custos')">
220-
<LoadingSpan v-if="loading" message="Signing In" />
221-
<span v-else>Sign in with Custos*</span>
222-
</GButton>
223-
</div>
224-
225-
<div v-else>
226-
<GButtonGroup class="w-100">
227-
<GButton
228-
v-if="cILogonEnabled"
229-
:pressed="cilogonOrCustos === 'cilogon'"
230-
@click="toggleCILogon('cilogon')">
231-
Sign in with Institutional Credentials*
232-
</GButton>
233-
234-
<GButton
235-
v-if="custosEnabled"
236-
:pressed="cilogonOrCustos === 'custos'"
237-
@click="toggleCILogon('custos')">
238-
Sign in with Custos*
239-
</GButton>
240-
</GButtonGroup>
241-
242-
<BFormGroup v-if="toggleCilogon" class="mt-1">
243-
<Multiselect
244-
v-model="selected"
245-
placeholder="Select your institution"
246-
:options="cILogonIdps"
247-
label="DisplayName"
248-
select-label=""
249-
deselect-label=""
250-
:allow-empty="false"
251-
track-by="EntityID" />
252-
253-
<GButton
254-
v-if="toggleCilogon"
255-
class="mt-1"
256-
:disabled="loading || selected === null"
257-
@click="clickCILogin(cilogonOrCustos)">
258-
Login via {{ cilogonOrCustos === "cilogon" ? "CILogon" : "Custos" }} *
259-
</GButton>
260-
</BFormGroup>
261197
</div>
262198

263199
<p class="mt-3">
264200
<small class="text-muted">
265-
* Galaxy uses CILogon via Custos to enable you to log in from this organization. By clicking
266-
'Sign In', you agree to the
201+
* Galaxy uses CILogon to enable you to log in from this organization. By clicking 'Sign In', you
202+
agree to the
267203
<a href="https://ca.cilogon.org/policy/privacy">CILogon</a> privacy policy and you agree to
268-
share your username, email address, and affiliation with CILogon, Custos, and Galaxy.
204+
share your username, email address, and affiliation with CILogon and Galaxy.
269205
</small>
270206
</p>
271207
</BForm>
272208

273-
<template v-if="cilogonListShow && Object.keys(filteredOIDCIdps).length > 0">
209+
<template v-if="cILogonConfigured && Object.keys(filteredOIDCIdps).length > 0">
274210
<VerticalSeparator v-if="!props.columnDisplay">
275211
<span v-localize>or</span>
276212
</VerticalSeparator>

client/src/components/User/ExternalIdentities/service.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const getUrl = (path) => getAppRoot() + path;
77
export async function disconnectIdentity(doomed) {
88
if (doomed) {
99
let url;
10-
if (doomed.provider === "custos" || doomed.provider === "cilogon") {
10+
if (doomed.provider === "cilogon") {
1111
url = getUrl(`authnz/${doomed.provider}/disconnect/${doomed.email}`);
1212
} else {
1313
url = getUrl(`authnz/${doomed.provider}/disconnect/`);

client/src/entry/analysis/modules/Login.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ beforeEach(() => {
2121
allow_local_account_creation: true,
2222
enable_oidc: true,
2323
mailing_join_addr: "mailing_join_addr",
24-
prefer_custos_login: true,
24+
prefer_oidc_login: true,
2525
registration_warning_message: "registration_warning_message",
2626
server_mail_configured: true,
2727
show_welcome_with_login: true,

client/src/entry/analysis/modules/Register.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ beforeEach(() => {
2121
allow_local_account_creation: true,
2222
enable_oidc: true,
2323
mailing_join_addr: "mailing_join_addr",
24-
prefer_custos_login: true,
24+
prefer_oidc_login: true,
2525
registration_warning_message: "registration_warning_message",
2626
server_mail_configured: true,
2727
show_welcome_with_login: true,
@@ -59,7 +59,7 @@ describe("Register", () => {
5959
expect(props.sessionCsrfToken).toBe("session_csrf_token");
6060
expect(props.enableOidc).toBe(true);
6161
expect(props.mailingJoinAddr).toBe("mailing_join_addr");
62-
expect(props.preferCustosLogin).toBe(true);
62+
expect(props.preferOidcLogin).toBe(true);
6363
expect(props.serverMailConfigured).toBe(true);
6464
expect(props.registrationWarningMessage).toBe("registration_warning_message");
6565
expect(props.termsUrl).toBe("terms_url");

client/src/entry/analysis/modules/Register.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const sessionCsrfToken = computed(() => {
2121
:enable-oidc="config.enable_oidc"
2222
:mailing-join-addr="config.mailing_join_addr"
2323
:oidc-idps="config.oidc"
24-
:prefer-custos-login="config.prefer_custos_login"
24+
:prefer-oidc-login="config.prefer_oidc_login"
2525
:registration-warning-message="config.registration_warning_message"
2626
:server-mail-configured="config.server_mail_configured"
2727
:session-csrf-token="sessionCsrfToken"

doc/source/admin/galaxy_options.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3817,11 +3817,11 @@
38173817

38183818

38193819
~~~~~~~~~~~~~~~~~~~~~~~
3820-
``prefer_custos_login``
3820+
``prefer_oidc_login``
38213821
~~~~~~~~~~~~~~~~~~~~~~~
38223822

38233823
:Description:
3824-
Controls the order of the login page to prefer Custos-based login
3824+
Controls the order of the login page to prefer OIDC-based login
38253825
and registration.
38263826
:Default: ``false``
38273827
:Type: bool

0 commit comments

Comments
 (0)