Skip to content

Commit

Permalink
PS-496 add connect param to select identity provider to use from clie…
Browse files Browse the repository at this point in the history
…nts (#259)
  • Loading branch information
4rthem authored Oct 25, 2022
1 parent d12c366 commit 26745ea
Show file tree
Hide file tree
Showing 38 changed files with 311 additions and 273 deletions.
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ AUTH_REGISTRATION_VALIDATE_EMAIL=true
DEFAULT_USER_EMAIL=[email protected]
DEFAULT_USER_PASSWORD=__CHANGE_ME_Fv2TrQZg
AUTH_RABBITMQ_VHOST=auth

# Auto redirect to identity provider when coming from a client app
AUTO_CONNECT_IDP=

# Databox
DATABOX_STORAGE_USE_PATH_STYLE_ENDPOINT=true
DATABOX_STORAGE_BUCKET_NAME=databox
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ jobs:
uses: ./.github/workflows/build.yaml
with:
images: databox-client
withLibs: true
secrets: inherit
needs:
- build_nodejs-base
Expand Down Expand Up @@ -152,6 +153,7 @@ jobs:
uses: ./.github/workflows/build.yaml
with:
images: uploader-client
withLibs: true
secrets: inherit
needs:
- build_nodejs-base
Expand Down
13 changes: 13 additions & 0 deletions auth/api/src/Controller/SecurityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ public function login(AuthenticationUtils $authenticationUtils,
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();

if ($connect = $request->query->get('connect')) {
$idp = array_values(array_filter($identityProviders, function (array $idp) use ($connect): bool {
return $idp['name'] === $connect;
}));

if (!empty($idp)) {
return $this->redirect($this->generateUrl(sprintf('%s_entrypoint', $idp[0]['type']), [
'provider' => $idp[0]['name'],
'redirect_uri' => $redirectUri,
]));
}
}

return $this->render('security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
Expand Down
6 changes: 6 additions & 0 deletions auth/api/src/Security/AppCustomAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ public function start(Request $request, AuthenticationException $authException =
{
$url = $this->getLoginUrl().'?r='.urlencode($request->getUri());

if ('fos_oauth_server_authorize' === $request->attributes->get('_route')) {
if ($connect = $request->query->get('connect')) {
$url .= '&connect='.urlencode($connect);
}
}

return new RedirectResponse($url);
}
}
1 change: 1 addition & 0 deletions databox/client/config-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
},
locales: config.available_locales,
identityProviders,
autoConnectIdP: env.AUTO_CONNECT_IDP,
baseUrl: env.DATABOX_API_BASE_URL,
uploaderApiBaseUrl: env.UPLOADER_API_BASE_URL,
uploaderTargetSlug: env.UPLOADER_TARGET_SLUG,
Expand Down
3 changes: 2 additions & 1 deletion databox/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"version": "1.0.0",
"private": true,
"dependencies": {
"@alchemy-fr/phraseanet-react-components": "^1.0.5-alpha1",
"@dnd-kit/core": "^6.0.5",
"@dnd-kit/sortable": "^7.0.1",
"@dnd-kit/utilities": "^3.2.0",
Expand All @@ -12,6 +11,7 @@
"@mui/icons-material": "^5.6.2",
"@mui/lab": "^5.0.0-alpha.80",
"@mui/material": "^5.6.4",
"react-ps": "link:./__lib/react-ps",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.2.0",
"@testing-library/user-event": "^14.1.1",
Expand Down Expand Up @@ -55,6 +55,7 @@
"web-vitals": "^2.1.4"
},
"scripts": {
"postinstall": "cd ./__lib/react-ps && yarn install && yarn build && rm -rf node_modules",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
Expand Down
4 changes: 2 additions & 2 deletions databox/client/src/api/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export async function UploadFiles(userId: string, files: File[], options: Upload
}

export async function UploadFile(targetSlug: string, userId: string, file: File): Promise<string> {
return await uploadMultipartFile(targetSlug, userId, oauthClient.getAccessToken(), {
return await uploadMultipartFile(targetSlug, userId, oauthClient.getAccessToken()!, {
file,
id: (uploadId++).toString()
}, (e) => {
Expand All @@ -48,6 +48,6 @@ export async function CommitUpload(targetSlug: string, files: string[], options:
options,
formData,
}, {
headers: makeAuthorizationHeaders(oauthClient.getAccessToken()),
headers: makeAuthorizationHeaders(oauthClient.getAccessToken()!),
});
}
6 changes: 0 additions & 6 deletions databox/client/src/auth.js

This file was deleted.

19 changes: 13 additions & 6 deletions databox/client/src/components/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, {PureComponent, Suspense} from 'react';
import {oauthClient} from "../oauth";
import {authenticate} from "../auth";
import config from "../config";
import apiClient from "../api/api-client";
import {User} from "../types";
Expand All @@ -20,23 +19,31 @@ type State = {

const scrollbarWidth = 8;

function authenticate() {
return oauthClient.authenticate();
}

export default class Root extends PureComponent<{}, State> {
state: State = {
authenticating: oauthClient.hasAccessToken(),
theme: 'default',
}

componentDidMount() {
oauthClient.registerListener('authentication', (evt: { user: User }) => {
apiClient.defaults.headers.common['Authorization'] = `Bearer ${oauthClient.getAccessToken()}`;
oauthClient.registerListener('authentication', async (evt) => {
apiClient.defaults.headers.common['Authorization'] = `Bearer ${oauthClient.getAccessToken()!}`;
this.setState({
user: evt.user,
user: (evt as unknown as {
user: User;
}).user,
authenticating: false,
});
});
oauthClient.registerListener('login', authenticate);
oauthClient.registerListener('login', async () => {
await authenticate();
});

oauthClient.registerListener('logout', () => {
oauthClient.registerListener('logout', async () => {
if (config.isDirectLoginForm()) {
this.setState({
user: undefined,
Expand Down
27 changes: 0 additions & 27 deletions databox/client/src/decs.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion databox/client/src/oauth.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, {useEffect} from "react";
import {OAuthClient} from "@alchemy-fr/phraseanet-react-components";
import config from "./config";
import {useNavigate} from "react-router-dom";
import {getPath} from "./routes";
import {toast} from "react-toastify";
import {OAuthClient} from "react-ps";

const {clientId, clientSecret} = config.getClientCredential();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React, {useEffect} from 'react';
import config from '../../config';
import {createAuthorizeUrl} from "@alchemy-fr/phraseanet-react-components/dist/oauth/funcs";
import {oauthClient} from "../../oauth";

export default function Login() {
useEffect(() => {
if (!config.isDirectLoginForm()) {
document.location.href = createAuthorizeUrl(config.getAuthBaseUrl(), config.getClientCredential().clientId);
document.location.href = oauthClient.createAuthorizeUrl({
connectTo: config.get('autoConnectIdP') || undefined,
});
}
}, []);

Expand Down
Loading

0 comments on commit 26745ea

Please sign in to comment.