diff --git a/client/src/api/schema/schema.ts b/client/src/api/schema/schema.ts index 1f94efde46d7..0669b9c6b79f 100644 --- a/client/src/api/schema/schema.ts +++ b/client/src/api/schema/schema.ts @@ -36796,7 +36796,8 @@ export interface operations { query: { /** @description Base-64 encoded JSON used to route request within Galaxy. */ state: string; - code: string; + code?: string | null; + error?: string | null; }; header?: { /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ diff --git a/client/src/components/FileSources/Templates/CreateUserFileSource.vue b/client/src/components/FileSources/Templates/CreateUserFileSource.vue index 5cc4a9f8e3aa..af85f683434e 100644 --- a/client/src/components/FileSources/Templates/CreateUserFileSource.vue +++ b/client/src/components/FileSources/Templates/CreateUserFileSource.vue @@ -1,5 +1,6 @@ + diff --git a/client/src/entry/analysis/router.js b/client/src/entry/analysis/router.js index cfd6a815b73e..837e70a574bc 100644 --- a/client/src/entry/analysis/router.js +++ b/client/src/entry/analysis/router.js @@ -395,6 +395,11 @@ export function getRouter(Galaxy) { { path: "file_source_instances/create", component: CreateUserFileSource, + props: (route) => { + return { + error: route.params.error, + }; + }, }, { path: "file_source_instances/index", diff --git a/lib/galaxy/webapps/galaxy/api/oauth2_callback.py b/lib/galaxy/webapps/galaxy/api/oauth2_callback.py index bb7968d89c58..a24f6b127df6 100644 --- a/lib/galaxy/webapps/galaxy/api/oauth2_callback.py +++ b/lib/galaxy/webapps/galaxy/api/oauth2_callback.py @@ -1,3 +1,5 @@ +from typing import Optional + from fastapi import Query from fastapi.responses import RedirectResponse @@ -16,13 +18,19 @@ title="State information sent with auth request", description="Base-64 encoded JSON used to route request within Galaxy.", ) -CodeQueryParam: str = Query( - ..., +CodeQueryParam: Optional[str] = Query( + None, title="OAuth2 Authorization Code from remote resource", ) +ErrorQueryParam: Optional[str] = Query( + None, + title="OAuth2 Error from remote resource", +) router = Router(tags=["oauth2"]) +ERROR_REDIRECT_PATH = "file_source_instances/create" + @router.cbv class OAuth2Callback: @@ -36,8 +44,16 @@ def oauth2_callback( self, trans: SessionRequestContext = DependsOnTrans, state: str = StateQueryParam, - code: str = CodeQueryParam, + code: Optional[str] = CodeQueryParam, + error: Optional[str] = ErrorQueryParam, ): + if error: + return RedirectResponse(f"{trans.request.url_path}{ERROR_REDIRECT_PATH}?error={error}") + elif not code: + return RedirectResponse( + f"{trans.request.url_path}{ERROR_REDIRECT_PATH}?error=No credentials provided, please try again." + ) + oauth2_state = OAuth2State.decode(state) # TODO: save session information in cookie to verify not CSRF with oauth2_state.nonce route = oauth2_state.route