Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions server/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@
Base = declarative_base()
Base.metadata.reflect(engine)
else:
logging.warning("Testing mode, using local sqlite db.")
logging.warning("Testing mode, using local sqlite test db.")
engine = create_engine(
"sqlite:///" + os.path.join(basedir, "openml.db"),
"sqlite:///" + os.path.join(basedir, "openml.test.db"),
echo=False,
)
Config.SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "openml.db")
Config.SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "openml.test.db")
Base = declarative_base()
Base.metadata.reflect(engine)

Expand Down
Binary file added server/openml.test.db
Binary file not shown.
12 changes: 6 additions & 6 deletions server/public/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
CORS(blueprint)


DO_SEND_EMAIL = strtobool(os.environ.get("SEND_EMAIL", "True"))

def email_enabled():
return strtobool(os.getenv("SEND_EMAIL", "True"))

@blueprint.route("/signup", methods=["POST"])
def signupfunc():
Expand All @@ -45,7 +45,7 @@ def signupfunc():
user.remember_code = "0000"
user.created_on = "0000"
user.last_login = "0000"
user.active = "0" if DO_SEND_EMAIL else "1"
user.active = "0" if email_enabled() else "1"
user.first_name = register_obj["first_name"]
user.last_name = register_obj["last_name"]
user.company = "0000"
Expand All @@ -59,7 +59,7 @@ def signupfunc():
user.password_hash = "0000"
token = secrets.token_hex()
user.update_activation_code(token)
if DO_SEND_EMAIL:
if email_enabled():
confirmation_email(user.email, token)
session.add(user)
session.commit()
Expand All @@ -81,7 +81,7 @@ def password():
token = secrets.token_hex()
user.update_forgotten_code(token)
# user.update_forgotten_time(timestamp)
if DO_SEND_EMAIL:
if email_enabled():
forgot_password_email(user.email, token)
session.merge(user)
session.commit()
Expand All @@ -100,7 +100,7 @@ def confirmation_token():
return jsonify({"msg": "User confirmation token sent"}), 200
token = secrets.token_hex()
user.update_activation_code(token)
if DO_SEND_EMAIL:
if email_enabled():
confirmation_email(user.email, token)
# updating user groups here
user_group = UserGroups(user_id=user.id, group_id=2)
Expand Down
6 changes: 3 additions & 3 deletions server/src/client/app/src/pages/auth/APIKey.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ function APIKey() {
const [apikey, setApikey] = useState('');
const yourConfig = {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
Authorization: "Bearer " + localStorage.getItem("token")
}
};

useEffect(() => {
Expand All @@ -66,7 +66,7 @@ function APIKey() {
axios
.post(
process.env.REACT_APP_URL_SITE_BACKEND + "api-key",
{ resetapikey: true },
{}, // no form data required
yourConfig
)
.then((response) => {
Expand Down
12 changes: 7 additions & 5 deletions server/src/client/app/src/pages/auth/ProfilePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,16 @@ function Public() {
setFname(response.data.first_name);
setLname(response.data.last_name);
setId(response.data.id);
if (id !== false) {
if (id) {
fetch(`${ELASTICSEARCH_SERVER}user/user/` + id.toString())
.then(response => response.json())
.then(data => {
setDataset(data._source.datasets_uploaded);
setRun(data._source.runs_uploaded);
setTask(data._source.tasks_uploaded);
setFlow(data._source.flows_uploaded);
if (data._source) {
setDataset(data._source.datasets_uploaded);
setRun(data._source.runs_uploaded);
setTask(data._source.tasks_uploaded);
setFlow(data._source.flows_uploaded);
}
});
}
})
Expand Down
31 changes: 14 additions & 17 deletions server/src/client/app/src/pages/auth/SignIn.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ function SignIn() {
const [errorlog, setError] = useState(false);
const [confirmflag, setConfirm] = useState(false);
const [errormsg, setErrorMsg] = useState(false);
const [notexist, setNotExist] = useState(false);
const [wrongpass, setWrongPass] = useState(false);
const [incorrectCredentials, setIncorrectCredentials] = useState(false);
const context = useContext(MainContext);

function sendtoflask(event) {
Expand All @@ -46,12 +45,10 @@ function SignIn() {
})
.then(response => {
console.log(response.data);
if (response.data.msg === "NotConfirmed") {
if (response.data.msg === "UserNotConfirmed") {
setConfirm(true);
} else if (response.data.msg === "Wrong username or password") {
setNotExist(true);
} else if (response.data.msg === "wrong password") {
setWrongPass(true);
} else if (response.data.msg === "WrongUsernameOrPassword") {
setIncorrectCredentials(true);
} else {
localStorage.setItem("token", response.data.access_token);
context.checkLogIn();
Expand All @@ -75,12 +72,15 @@ function SignIn() {
)}
<Grid item md={7} xs={10}>
<Wrapper>
{/** Header **/}
<Typography component="h1" variant="h4" align="center" gutterBottom>
Welcome back!
</Typography>
<Typography component="h2" variant="body1" align="center">
Sign in to continue
</Typography>

{/** Start Error Banner **/}
{errorlog && (
<Typography component="h3" align="center" style={{ color: "red" }}>
<FontAwesomeIcon
Expand All @@ -90,7 +90,8 @@ function SignIn() {
{errormsg}
</Typography>
)}
{wrongpass && (
{/* User with this email & password could not be found */}
{(incorrectCredentials) && (
<Typography component="h3" align="center" style={{ color: "red" }}>
<FontAwesomeIcon
icon="exclamation-triangle"
Expand All @@ -99,6 +100,7 @@ function SignIn() {
Wrong username or password
</Typography>
)}
{/* User's account not yet confirmed */}
{confirmflag && (
<Typography
component="h3"
Expand All @@ -110,15 +112,9 @@ function SignIn() {
<a href="/auth/confirmation-token">(resend activation token)</a>
</Typography>
)}
{notexist && (
<Typography component="h3" align="center" style={{ color: "red" }}>
<FontAwesomeIcon
icon="exclamation-triangle"
style={{ marginRight: 5 }}
/>
Wrong username or password
</Typography>
)}
{/** End Error Banner **/}

{/** Start Entry Fields **/}
<form onSubmit={sendtoflask}>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="email">Email Address</InputLabel>
Expand Down Expand Up @@ -156,6 +152,7 @@ function SignIn() {
Forgot password
</Button>
</form>
{/** End Entry Fields **/}
</Wrapper>
</Grid>
<Grid item md={7} xs={10}>
Expand Down
140 changes: 105 additions & 35 deletions server/src/client/app/src/pages/auth/SignUp.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ import { useState } from "react";

import {
FormControl,
IconButton,
Input,
InputLabel,
InputAdornment,
Button as MuiButton,
Paper,
Typography
} from "@mui/material";
import {
Visibility,
VisibilityOff
} from '@mui/icons-material';
import { spacing } from "@mui/system";
import axios from "axios";

Expand All @@ -30,53 +36,84 @@ const RedIcon = styled(FontAwesomeIcon)({
color: red[500]
});

const MIN_PASSWORD_LENGTH = 15;

function SignUp() {
const [register, setRegister] = useState(false);
const [duplicateUser, setDuplicateUser] = useState(false);
const [error, setError] = useState(false);
const [errormessage, setErrorMessage] = useState(false);
function sendflask(event) {

const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");

const [showPassword, setShowPassword] = useState(false);

function handleSubmit(event) {
event.preventDefault();
console.log(event.target.email.value);
console.log(event.target.password.value);
if (event.target.password.value.length < 8) {
var registrationData = {
email: email,
firstName: firstName,
lastName: lastName,
password: password
};

if (password.length < MIN_PASSWORD_LENGTH) {
// Password must meet minimum length
// Using NIST recommendation
setError(true);
setErrorMessage("Password too weak. Use at least 8 characters, with numbers, digits, and special characters.");
} else if (
/[a-zA-Z0-9]+@(?:[a-zA-Z0-9-]+\.)+[A-Za-z]+$/.test(
event.target.email.value
) !== true
) {
setErrorMessage(`Password too weak. Use at least ${MIN_PASSWORD_LENGTH} characters.`);
} else if ( (/[a-zA-Z0-9]+@(?:[a-zA-Z0-9-]+\.)+[A-Za-z]+$/.test(email)) === false) {
// Email must be in valid format
setError(true);
setErrorMessage("Please enter valid email");
} else {
axios
.post(process.env.REACT_APP_URL_SITE_BACKEND + "signup", {
first_name: event.target.fname.value,
last_name: event.target.lname.value,
email: event.target.email.value,
password: event.target.password.value
})
.then(function(response) {
if (response.data.msg === "User created") {
console.log(response.data);
setRegister(true);
} else if (response.data.msg === "User already exists") {
setDuplicateUser(true);
}
})
.catch(function(error) {
console.log(error.data);
});
sendflask(registrationData);
}

return false;
}

function handleMouseDownPassword(event) {
event.preventDefault(); // Prevents focus loss
}

function handleClickShowPassword() {
setShowPassword(function(prev) {
return !prev;
});
}

function sendflask(registrationData) {
axios
.post(process.env.REACT_APP_URL_SITE_BACKEND + "signup", {
first_name: registrationData.firstName,
last_name: registrationData.lastName,
email: registrationData.email,
password: registrationData.password
})
.then(function(response) {
if (response.data.msg === "User created") {
console.log(response.data);
setRegister(true);
} else if (response.data.msg === "User alredy exists") {
setDuplicateUser(true);
}
})
.catch(function(error) {
console.log(error.data);
})
}

return (
<Wrapper>
<Typography component="h1" variant="h4" align="center" gutterBottom>
Almost there
</Typography>
<form onSubmit={sendflask}>
<form onSubmit={handleSubmit}>
{/* Error Banner */}
{duplicateUser && (
<Typography component="h3" variant="body1" align="center" color="red">
User already exists
Expand All @@ -87,31 +124,64 @@ function SignUp() {
{errormessage}
</Typography>
)}

{/* Input fields */}
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="fname">First name</InputLabel>
<Input id="fname" name="fname" autoFocus />
<Input
id="fname"
name="fname"
value={firstName}
onChange={function(e) { setFirstName(e.target.value); }}
autoFocus
/>
</FormControl>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="lname">Last name</InputLabel>
<Input id="lname" name="lname" autoFocus />
<Input
id="lname"
name="lname"
value={lastName}
onChange={function(e) { setLastName(e.target.value); }}
autoFocus
/>
</FormControl>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="email">
Email Address (we never share your email)
</InputLabel>
<Input id="email" name="email" autoComplete="email" />
<Input
id="email"
name="email"
value={email}
onChange={function(e) { setEmail(e.target.value); }}
autoComplete="email"
/>
</FormControl>
<FormControl margin="normal" required fullWidth>
<InputLabel htmlFor="password">
Password (min 8 characters)
Password (min {MIN_PASSWORD_LENGTH} characters)
</InputLabel>
<Input
name="password"
type="password"
id="password"
name="password"
type={showPassword ? 'text' : 'password'}
autoComplete="current-password"
onChange={function(e) {setPassword(e.target.value)}}
endAdornment={
<InputAdornment position="end">
<IconButton
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
edge="end"
>
{showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
}
/>
</FormControl>

<Button
type="submit"
fullWidth
Expand Down
Loading