+ CERN Privacy Notice PN00915
+
+ How is your data used
+
+ Each service at CERN is responsible for compiling its own Privacy Notice
+ regarding the data it processes.
+
+
+ This Privacy Notice is part of{" "}
+
+ CERN’s Layered Privacy Notice
+ {" "}
+ and details the processing that is unique to REANA. It does not address
+ processing by other services on which this service may rely and which
+ have their own Privacy Notice.
+
+
+ Personal Data we process
+ The personal data we have, and how it's used:
+
+
+
+ Personal Data
+ Purpose
+ Basis
+ Source
+
+
+
+
+
+ Your access logs (IP address, visited URLs on REANA and
+ corresponding timestamp)
+
+
+ User support, website debugging, security auditing and to produce
+ statistics
+
+ Legitimate interest of CERN
+
+ Automatically transferred by your web browser
+
+
+
+ E-mail address
+
+ Unique identifier for your REANA account, used to sign in, grant
+ access rights, and send email communications
+
+ Legitimate interest of CERN
+ CERN Single Sign-On
+
+
+ E-group membership
+ Used for authorisation purposes
+ Legitimate interest of CERN
+ CERN Single Sign-On
+
+
+ Account name
+
+ Used for authentication and to enable the integration with CERN
+ GitLab service
+
+ Legitimate interest of CERN
+ CERN Single Sign-On
+
+
+ Access token
+
+ Used by REANA Client for REST API authentication and authorisation
+
+ Legitimate interest of CERN
+ Created by REANA at first login
+
+
+ List of REANA jobs you created
+
+ Used to manage and display information about your REANA jobs (e.g.
+ logs of running tasks, outputs, etc)
+
+ Legitimate interest of CERN
+ Your input
+
+
+
+
+
+ Description of legal basis for processing of Personal Data by REANA
+
+
+ -
+ Contract: To fulfil a contractual relationship with
+ the individual, or in preparation for a contract with the individual
+
+ -
+ Legal Obligation: To comply with a legal obligation
+ of CERN.
+
+ -
+ Consent: By having received and recorded consent from
+ the individual.
+
+ -
+ Legitimate interest of CERN: In the legitimate
+ interests of CERN supporting the professional activities of the
+ individual or their security and safety.
+
+
+
+ Personal Data we keep
+ The personal data we store, for how long and why:
+
+
+
+ Personal Data
+
+ Retention Period 1
+
+ Purpose
+
+
+
+
+
+ Your access logs (IP address, visited URLs on REANA and
+ corresponding timestamp)
+
+ Maximum 13 months from date of action
+
+ User support, website debugging, security auditing and to produce
+ statistics
+
+
+
+ E-mail address
+ Lifetime of your REANA account
+
+ Unique identifier for your REANA account, used to sign in, grant
+ access rights, and send email communications
+
+
+
+ E-group membership
+ Lifetime of your REANA account
+ Used for authorisation purposes
+
+
+ Account name
+ Lifetime of your REANA account
+
+ Used for authentication and to enable the integration with CERN
+ GitLab service
+
+
+
+ Access token
+
+ Lifetime of your REANA account or until revoked by administrators
+
+ API authentication and authorisation
+
+
+ List of REANA jobs you created
+ Lifetime of your REANA account
+
+ Used to manage and display information about your REANA jobs (e.g.
+ logs of running tasks, outputs, etc)
+
+
+
+
+
+ Who at CERN has access
+
+ In addition to yourself, personal data collected by REANA is accessible
+ by the following services, teams or individuals at CERN:
+
+
+
+
+ Personal Data
+ Who
+ Purpose
+
+
+
+
+
+ Your access logs (IP address, visited URLs on REANA, and
+ corresponding timestamp)
+
+
+ REANA administrators and CERN Services administrators (Cloud
+ Infrastructure)
+
+ User support and service operations
+
+
+ E-mail address
+
+ REANA administrators and CERN Services administrators (Database on
+ demand service)
+
+ User support and service operations
+
+
+ E-group membership
+
+ REANA administrators and CERN Services administrators (Database on
+ demand service)
+
+ User support and service operations
+
+
+ Account name
+
+ REANA administrators and CERN Services administrators (Database on
+ demand service)
+
+ User support and service operations
+
+
+ Access token
+
+ REANA administrators and CERN Services administrators (Database on
+ demand service)
+
+ User support and service operations
+
+
+ List of REANA jobs you created
+
+ REANA administrators and CERN Services administrators (Database on
+ demand service)
+
+ User support and service operations
+
+
+
+
+
+ For more detailed information about personal data and privacy please
+ refer to the{" "}
+
+ Data Privacy web site
+
+ .
+
+
+ For questions regarding this Privacy Notice, please contact{" "}
+ reana-support@cern.ch.
+
+
+ For questions regarding personal data and privacy please contact the{" "}
+
+ Office of Data Privacy
+
+ .
+
+
+ To request to exercise data subject rights please fill and submit the
+ following{" "}
+
+ online form
+
+ .
+
+ This Privacy Notice is subject to revision.
+
+ Last revision: 2020-10-09 18:04:55
+
+
+
+ 1 The retention period may be temporarily extended for
+ special circumstances, in accordance with the provisions of the
+ operation circular governing data privacy.{" "}
+
+
+ );
+}
diff --git a/reana-ui/src/pages/privacyNotice/PrivacyNotice.module.scss b/reana-ui/src/pages/privacyNotice/PrivacyNotice.module.scss
new file mode 100644
index 00000000..be6347c8
--- /dev/null
+++ b/reana-ui/src/pages/privacyNotice/PrivacyNotice.module.scss
@@ -0,0 +1,16 @@
+/*
+ -*- coding: utf-8 -*-
+
+ This file is part of REANA.
+ Copyright (C) 2020 CERN.
+
+ REANA is free software; you can redistribute it and/or modify it
+ under the terms of the MIT License; see LICENSE file for more details.
+*/
+
+@import "../../styles/palette";
+
+.container {
+ padding: 1em;
+ margin: 4em 0;
+}
diff --git a/reana-ui/src/pages/signin/Confirm.js b/reana-ui/src/pages/signin/Confirm.js
new file mode 100644
index 00000000..fdcbb417
--- /dev/null
+++ b/reana-ui/src/pages/signin/Confirm.js
@@ -0,0 +1,27 @@
+/*
+ -*- coding: utf-8 -*-
+
+ This file is part of REANA.
+ Copyright (C) 2020 CERN.
+
+ REANA is free software; you can redistribute it and/or modify it
+ under the terms of the MIT License; see LICENSE file for more details.
+*/
+
+import { useEffect } from "react";
+import { useDispatch } from "react-redux";
+import { useHistory, useParams } from "react-router-dom";
+
+import { confirmUserEmail } from "../../actions";
+
+export default function Confirm() {
+ const { token } = useParams();
+ const dispatch = useDispatch();
+ const history = useHistory();
+
+ useEffect(() => {
+ dispatch(confirmUserEmail(token)).then(() => history.replace("/"));
+ }, [dispatch, token, history]);
+
+ return null;
+}
diff --git a/reana-ui/src/pages/signin/Signin.js b/reana-ui/src/pages/signin/Signin.js
index 14a7e0b8..232a540f 100644
--- a/reana-ui/src/pages/signin/Signin.js
+++ b/reana-ui/src/pages/signin/Signin.js
@@ -10,109 +10,78 @@
import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
-import { Button, Divider, Grid, Image, Segment } from "semantic-ui-react";
-import { Link, useHistory, useLocation } from "react-router-dom";
-import PropTypes from "prop-types";
+import { Button, Divider, Segment } from "semantic-ui-react";
+import { Link } from "react-router-dom";
import { getConfig } from "~/selectors";
import SignForm from "./components/SignForm";
+import SignContainer from "./components/SignContainer";
import { api } from "~/config";
-import { userSignup, userSignin } from "~/actions";
-import LogoImg from "~/images/logo-reana.svg";
+import { triggerNotification, userSignin } from "~/actions";
+import { useSubmit } from "~/hooks";
-import styles from "./Signin.module.scss";
-
-export default function Signin({ signup }) {
+export default function Signin() {
+ const handleSubmit = useSubmit(userSignin);
const config = useSelector(getConfig);
- const [formData, setFormData] = useState({ email: "", password: "" });
const dispatch = useDispatch();
- const history = useHistory();
- const location = useLocation();
+ const [formData, setFormData] = useState({ email: "", password: "" });
const handleClick = () => {
window.location.href = api + "/oauth/login/cern";
- };
-
- const handleSubmit = (event, action) => {
- const { from } = location.state || { from: { pathname: "/" } };
- dispatch(action(formData)).then((res) => {
- if (res.isAxiosError ?? false) {
- setFormData({ ...formData, password: "" });
- } else {
- history.replace(from);
- }
- });
- event.preventDefault();
+ // FIXME: We assume that the sign-up went successfully but we actually don't know.
+ // We should upgrade Invenio-OAuthClient to latest version that supports REST apps
+ // and adapt the whole workflow.
+ if (config.userConfirmation) {
+ dispatch(
+ triggerNotification(
+ "Success!",
+ "User registered. Please confirm your email by clicking on the link we sent you."
+ )
+ );
+ }
};
const handleInputChange = (event) => {
- const target = event.target;
+ const { target } = event;
setFormData({ ...formData, [target.name]: target.value });
};
return (
- handleSubmit(e, formData, setFormData)}
+ formData={formData}
+ handleInputChange={handleInputChange}
+ />
+ )}
+
+ {config.hideSignup && (
+
+ If you do not have an account yet, please contact
+ REANA administrators
+
+ )}
+ {!config.hideSignup && config.localUsers && (
+
+ If you do not have an account yet, please
+ Sign up here
+
+ )}
+
);
}
-
-Signin.propTypes = {
- /** Whether to show signup instead of signin form. */
- signup: PropTypes.bool,
-};
-
-Signin.defatultProps = {
- signup: false,
-};
diff --git a/reana-ui/src/pages/signin/Signup.js b/reana-ui/src/pages/signin/Signup.js
new file mode 100644
index 00000000..29fc7fe9
--- /dev/null
+++ b/reana-ui/src/pages/signin/Signup.js
@@ -0,0 +1,51 @@
+/*
+ -*- coding: utf-8 -*-
+
+ This file is part of REANA.
+ Copyright (C) 2020 CERN.
+
+ REANA is free software; you can redistribute it and/or modify it
+ under the terms of the MIT License; see LICENSE file for more details.
+*/
+
+import React, { useState } from "react";
+import { useSelector } from "react-redux";
+import { Segment } from "semantic-ui-react";
+import { Link } from "react-router-dom";
+
+import SignForm from "./components/SignForm";
+import SignContainer from "./components/SignContainer";
+import { getConfig } from "../../selectors";
+import { userSignup } from "../../actions";
+import { useSubmit } from "../../hooks";
+
+export default function Signup() {
+ const handleSubmit = useSubmit(userSignup);
+ const config = useSelector(getConfig);
+ const [formData, setFormData] = useState({ email: "", password: "" });
+
+ const handleInputChange = (event) => {
+ const { target } = event;
+ setFormData({ ...formData, [target.name]: target.value });
+ };
+
+ return (
+
+
+ {config.localUsers && (
+ handleSubmit(e, formData, setFormData)}
+ formData={formData}
+ handleInputChange={handleInputChange}
+ />
+ )}
+
+ {config.localUsers && (
+
+ Already signed up? Go to Sign in
+
+ )}
+
+ );
+}
diff --git a/reana-ui/src/pages/signin/components/SignContainer.js b/reana-ui/src/pages/signin/components/SignContainer.js
new file mode 100644
index 00000000..edb4dc03
--- /dev/null
+++ b/reana-ui/src/pages/signin/components/SignContainer.js
@@ -0,0 +1,50 @@
+/*
+ -*- coding: utf-8 -*-
+
+ This file is part of REANA.
+ Copyright (C) 2020 CERN.
+
+ REANA is free software; you can redistribute it and/or modify it
+ under the terms of the MIT License; see LICENSE file for more details.
+*/
+
+import React from "react";
+import { Grid, Image } from "semantic-ui-react";
+import PropTypes from "prop-types";
+
+import Notification from "../../../components/Notification";
+
+import LogoImg from "../../../images/logo-reana.svg";
+
+import styles from "./SignContainer.module.scss";
+
+export default function SignContainer({ children }) {
+ return (
+
+
+
+
+
+ {children}
+
+
+
+ );
+}
+
+SignContainer.propTypes = {
+ children: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.node),
+ PropTypes.node,
+ ]).isRequired,
+};
diff --git a/reana-ui/src/pages/signin/Signin.module.scss b/reana-ui/src/pages/signin/components/SignContainer.module.scss
similarity index 100%
rename from reana-ui/src/pages/signin/Signin.module.scss
rename to reana-ui/src/pages/signin/components/SignContainer.module.scss
diff --git a/reana-ui/src/reducers.js b/reana-ui/src/reducers.js
index 5a37d2b7..4ac099e7 100644
--- a/reana-ui/src/reducers.js
+++ b/reana-ui/src/reducers.js
@@ -52,8 +52,12 @@ export const configInitialState = {
forumURL: null,
chatURL: null,
cernSSO: false,
+ cernRopo: false,
+ adminEmail: null,
localUsers: false,
+ hideSignup: false,
isLoaded: false,
+ userConfirmation: true,
loading: false,
};
@@ -123,7 +127,11 @@ const config = (state = configInitialState, action) => {
forumURL: action.forum_url,
chatURL: action.chat_url,
cernSSO: action.cern_sso,
+ cernRopo: action.cern_ropo,
+ adminEmail: action.admin_email,
localUsers: action.local_users,
+ hideSignup: action.hide_signup,
+ userConfirmation: action.user_confirmation,
isLoaded: true,
loading: false,
};
diff --git a/reana-ui/src/selectors.js b/reana-ui/src/selectors.js
index 4b969d46..46ea0297 100644
--- a/reana-ui/src/selectors.js
+++ b/reana-ui/src/selectors.js
@@ -16,6 +16,8 @@ export const getNotification = (state) => state.notification;
// Config
export const getConfig = (state) => state.config;
export const isConfigLoaded = (state) => state.config.isLoaded;
+export const isSignupHidden = (state) => state.config.hideSignup;
+export const loadingConfig = (state) => state.config.loading;
// Quota
export const getUserQuota = (state) => state.quota;