Skip to content

SciCat Dataset widget #427

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

Merged
merged 2 commits into from
Apr 28, 2025
Merged

SciCat Dataset widget #427

merged 2 commits into from
Apr 28, 2025

Conversation

omkar-ethz
Copy link
Member

@omkar-ethz omkar-ethz commented Mar 26, 2025

Overview

This PR implements a widget that displays a user-selected dataset from SciCat. An interceptor is implemented to detect a call to scicat backend, and if unauthorized, to fetch a scicat token for the OIDC user.

Implementation details

We use support added in SciCatProject/scicat-backend-next#1714 and pass scilog as clientId and the current path as returnURL to SciCat (to /auth/oidc/login). SciCat then returns the access token to <scilog-frontend>/auth-callback (configured as successURL for clientId scilog in SciCat i.e. OIDC_SCILOG_SUCCESS_URL) along with the passed returnUrl. The AuthCallback component in Scilog then stores the scicat token and routes the frontend to /returnUrl.

A first implementation of Dataset viewer is added, along with link to the corresponding dataset page in SciCat.

Added dependency on scicat-sdk-ts-fetch to get typing support for Scicat backend calls.

JIRA issues addressed

Testing

Added tests for AuthInterceptor and AuthCallbackComponent.

@omkar-ethz omkar-ethz requested a review from minottic March 26, 2025 14:05
@omkar-ethz omkar-ethz marked this pull request as draft March 26, 2025 14:10
@omkar-ethz omkar-ethz marked this pull request as ready for review March 26, 2025 16:01
@minottic
Copy link
Member

minottic commented Apr 3, 2025

@omkar-ethz I have had a first preliminary look, I'll have better feedback in the next days. Something I am not sure I understand why is auth-callback a component? Isn't it enough to be a service or guard?

Copy link
Member

@minottic minottic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! some small comments + I don't fully get why auth-callback needs to be a component

if (!this.isRequestToSciCatBackend(err.url)) {
logout();
} else {
window.location.href = `${this.serverSettingsService.getSciCatServerAddress()}/api/v3/auth/oidc?client=scilog&returnURL=${
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this URLs should be composed in the config service?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Composing this in server settings service now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the login be part of the dataset service too? The SDK does not have functions for the HTTP calls?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dataset service is mainly responsible for fetching data with AJAX (i.e. API) requests, whereas login is a browser redirect. For API requests, the SDK provides Fetch API based HTTP calls, but then it bypasses Angular's interceptor chain. @scicatproject/scicat-sdk-ts-angular provides an Angular HttpClient compatible SDK, but the current scilog Angular version (i.e. v15) is not compatible with minimum required version (v16).

After an Angular upgrade, we can consider using the angular SDK, as it's done in SciCat. We can also consider generating an SDK for SciLog backend calls. Created a discussion to track this: #430

});

this.datasetService.getDatasets().subscribe((data: DatasetSummary[]) => {
this.datasetSummary = data.sort(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think one could add sorting on the server side

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that would be more efficient, done!

}

get scicatDatasetUrl(): string {
return `${this.serverSettingsService.getScicatFrontendBaseUrl()}/datasets/${encodeURIComponent(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be clear if all URLs were composed in the dataset service or using the SDK

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, moved this URL creation to DatasetService.

logout();
} else {
window.location.href = `${this.serverSettingsService.getSciCatServerAddress()}/api/v3/auth/oidc?client=scilog&returnURL=${
window.location.pathname + window.location.search
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use fstrings consistently

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, refactored this to getScicatLoginUrl(...) method in serverSettingsService.


const idToken = localStorage.getItem("id_token");
private handle_request(handler: HttpHandler, req: HttpRequest<any>) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not super convinced the login to scicat should be part of the interceptor, rather than invoked at component creation of the scicat widget

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, the interceptor handles the case of SciCat session timing out, and re-logging in the user. As this logic is needed in the interceptor anyway, we let the interceptor also handle the initial login.

@@ -0,0 +1,62 @@
<div *ngIf="scicatUser; else unauthenticated">
<p>Your SciCat userId is {{ scicatUser.id }}.</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we maybe put the same name the user sees when logged in scicat in the avatar?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, changed to Hello {{scicatUser.username}}

private serverSettingsService: ServerSettingsService
) {}

getDatasets(): Observable<DatasetSummary[]> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't there the risk to get too many results here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added explicit limit of 100 datasets to this call, and created an issue to handle pagination/infinite scroll + linking on proposal ID: #429

@omkar-ethz omkar-ethz self-assigned this Apr 14, 2025
@omkar-ethz
Copy link
Member Author

Thanks! some small comments + I don't fully get why auth-callback needs to be a component

As discussed offline, SciCat needs a fixed URL for OIDC_SCILOG_SUCCESS_URL e.g. https://scilog-frontend.ch/auth-callback to return the access token to. This is better than allowing a dynamic route because we can keep the /auth-callback route simple and free of scripts that could potentially leak the acess-token. The dynamic aspect is handled by the returnURL parameter instead, which SciLog passes before logging in to https://scicat-backend.ch/api/v3/auth/oidc and SciCat passes back to /auth-callback after login in a query parameter. Hence, we make /auth-callback a dedicated component.

Another small addition in this revision: as discussed, to cope with V3-V4 migration, we made the scicat widget configurable using scicat.scicatWidgetEnabled config key.

@omkar-ethz omkar-ethz requested a review from minottic April 22, 2025 13:59
@omkar-ethz omkar-ethz merged commit c7be028 into main Apr 28, 2025
1 check passed
@omkar-ethz omkar-ethz deleted the scicat-widget branch April 28, 2025 12:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants