Feature/open id sign in (#35)

* added errorOpenIdLogin i18n key
* added openid authProvider
* added postOpenIdLogin api call
* added via-open-id component

Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2020-05-16 23:21:05 +02:00 committed by GitHub
parent d2c6ea464d
commit a50ad6e6c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 92 additions and 9 deletions

View file

@ -10,12 +10,13 @@
"google": true, "google": true,
"saml": true, "saml": true,
"oauth2": true, "oauth2": true,
"email": true "email": true,
"openid": true
}, },
"customAuthNames": { "customAuthNames": {
"ldap": "FooBar", "ldap": "FooBar",
"saml": "aufSAMLn.de", "oauth2": "Olaf2",
"oauth2": "Olaf2" "saml": "aufSAMLn.de"
}, },
"specialLinks": { "specialLinks": {
"privacy": "test", "privacy": "test",

View file

@ -123,5 +123,6 @@
"errorLdapLogin": "Benutzername oder Passwort nicht korrekt", "errorLdapLogin": "Benutzername oder Passwort nicht korrekt",
"email": "E-Mail", "email": "E-Mail",
"password": "Passwort", "password": "Passwort",
"username": "Benutzername" "username": "Benutzername",
"errorOpenIdLogin": "OpenID nicht korrekt"
} }

View file

@ -123,5 +123,6 @@
"errorLdapLogin": "Invalid username or password", "errorLdapLogin": "Invalid username or password",
"email": "Email", "email": "Email",
"password": "Password", "password": "Password",
"username": "Username" "username": "Username",
"errorOpenIdLogin": "Invalid OpenID provided"
} }

View file

@ -43,3 +43,22 @@ export const postLdapLogin = async (username: string, password: string) => {
.then(expectResponseCode()) .then(expectResponseCode())
.then(response => response.json()); .then(response => response.json());
} }
export const postOpenIdLogin = async (openId: string) => {
return fetch(getBackendUrl() + "/auth/openid", {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: JSON.stringify({
openId: openId
})
})
.then(expectResponseCode())
.then(response => response.json());
}

View file

@ -0,0 +1,54 @@
import React, {Fragment, useState} from "react";
import {Trans, useTranslation} from "react-i18next";
import {Alert, Button, Form} from "react-bootstrap";
import {postOpenIdLogin} from "../../../../../api/user";
import {getAndSetUser} from "../../../../../utils/apiUtils";
const ViaOpenId: React.FC = () => {
useTranslation();
const [openId, setOpenId] = useState("");
const [error, setError] = useState(false);
const login = (event: any) => {
postOpenIdLogin(openId)
.then(loginJson => {
console.log(loginJson)
getAndSetUser();
}).catch(_reason => {
setError(true);
}
)
event.preventDefault();
}
return (
<Fragment>
<h5 className="center">
<Trans i18nKey="signInVia" values={{service: "OpenID"}}/>
</h5>
<Form onSubmit={login}>
<Form.Group controlId="openid">
<Form.Control
isInvalid={error}
type="text"
size="sm"
placeholder={"OpenID"}
onChange={(event) => setOpenId(event.currentTarget.value)}
/>
</Form.Group>
<Alert className="small" show={error} variant="danger">
<Trans i18nKey="errorOpenIdLogin"/>
</Alert>
<Button
type="submit"
size="sm"
variant="primary">
<Trans i18nKey="signIn"/>
</Button>
</Form>
</Fragment>
);
};
export { ViaOpenId }

View file

@ -6,6 +6,7 @@ import {OneClickType, ViaOneClick} from "./auth/via-one-click";
import {ViaLdap} from "./auth/via-ldap"; import {ViaLdap} from "./auth/via-ldap";
import {useSelector} from "react-redux"; import {useSelector} from "react-redux";
import {ApplicationState} from "../../../../redux"; import {ApplicationState} from "../../../../redux";
import {ViaOpenId} from "./auth/via-open id";
const Login: React.FC = () => { const Login: React.FC = () => {
useTranslation(); useTranslation();
@ -13,7 +14,9 @@ const Login: React.FC = () => {
const customAuthNames = useSelector((state: ApplicationState) => state.backendConfig.customAuthNames); const customAuthNames = useSelector((state: ApplicationState) => state.backendConfig.customAuthNames);
const emailForm = authProviders.email ? <ViaEMail/> : null const emailForm = authProviders.email ? <ViaEMail/> : null
const ldapForm = authProviders.ldap ? <ViaLdap/> : null const ldapForm = authProviders.ldap ? <ViaLdap/> : null
const openIdForm = authProviders.openid ? <ViaOpenId/> : null
const emailLdapSeparator = authProviders.email && authProviders.ldap ? <hr className="w-100 bg-white"/> : null const emailLdapSeparator = authProviders.email && authProviders.ldap ? <hr className="w-100 bg-white"/> : null
const ldapOpenIdSeparator = authProviders.ldap && authProviders.openid ? <hr className="w-100 bg-white"/> : null
const oneClickCustomName: (type: OneClickType) => string | undefined = (type) => { const oneClickCustomName: (type: OneClickType) => string | undefined = (type) => {
switch (type) { switch (type) {
@ -36,6 +39,8 @@ const Login: React.FC = () => {
{emailForm} {emailForm}
{emailLdapSeparator} {emailLdapSeparator}
{ldapForm} {ldapForm}
{ldapOpenIdSeparator}
{openIdForm}
<hr className="w-100 d-lg-none d-block bg-white"/> <hr className="w-100 d-lg-none d-block bg-white"/>
</Col> </Col>
: null : null

View file

@ -13,12 +13,13 @@ export const initialState: BackendConfigState = {
google: false, google: false,
saml: false, saml: false,
oauth2: false, oauth2: false,
email: false email: false,
openid: false
}, },
customAuthNames: { customAuthNames: {
ldap: "", ldap: "",
saml: "", oauth2: "",
oauth2: "" saml: ""
}, },
specialLinks: { specialLinks: {
privacy: "", privacy: "",

View file

@ -20,12 +20,13 @@ export interface AuthProvidersState {
saml: boolean, saml: boolean,
oauth2: boolean, oauth2: boolean,
email: boolean, email: boolean,
openid: boolean,
} }
export interface CustomAuthNames { export interface CustomAuthNames {
ldap: string; ldap: string;
saml: string;
oauth2: string; oauth2: string;
saml: string;
} }
export interface SpecialLinks { export interface SpecialLinks {