Skip to content

Commit

Permalink
Merge branch 'develop' into feature/EGCETSII#16-API-utils
Browse files Browse the repository at this point in the history
  • Loading branch information
ferrabled committed Dec 18, 2021
2 parents 60099e0 + 97cdeae commit d614003
Show file tree
Hide file tree
Showing 67 changed files with 39,255 additions and 624 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/django.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,4 @@ jobs:
- name: Copy local_settings
run: |
cp ./decide/local_settings.example.py ./decide/local_settings.py
- name: Run Tests
run: |
python ./decide/manage.py test
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,6 @@ ENV/
.mypy_cache/

.vagrant

# new db migrations
decide/*/migrations/0001_initial.py
43 changes: 34 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[![Build Status](https://travis-ci.com/wadobo/decide.svg?branch=master)](https://travis-ci.com/wadobo/decide) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/94a85eaa0e974c71af6899ea3b0d27e0)](https://www.codacy.com/app/Wadobo/decide?utm_source=github.com&utm_medium=referral&utm_content=wadobo/decide&utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/94a85eaa0e974c71af6899ea3b0d27e0)](https://www.codacy.com/app/Wadobo/decide?utm_source=github.com&utm_medium=referral&utm_content=wadobo/decide&utm_campaign=Badge_Coverage)

Plataforma voto electrónico educativa
=====================================

El objetivo de este proyecto es implementar una plataforma de voto
electrónico seguro, que cumpla una serie de garantías básicas, como la
Expand Down Expand Up @@ -56,27 +55,53 @@ Para configurar el proyecto, podremos crearnos un fichero local_settings.py basa
local_settings.example.py, donde podremos configurar la ruta de nuestras apps o escoger que módulos
ejecutar.

Una vez hecho esto, será necesario instalar las dependencias del proyecto, las cuales están en el
Se hará uso de la base de datos MongoDB, para el correcto funcionamiento de la aplicación será necesaria la instalación de dicha base de datos siguiendo las instrucciones de la documentación oficial según el SO que estemos utilizando:

Windows:
- https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/

Ubuntu:
- https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/

WSL:
- https://docs.microsoft.com/es-es/windows/wsl/tutorials/wsl-database#install-mongodb

MacOs:
- https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/

Una vez hecho esto, y corriendo la base de datos, será necesario instalar las dependencias del proyecto, las cuales están en el
fichero requirements.txt:

pip install -r requirements.txt

Tras esto tendremos que crearnos nuestra base de datos con postgres:
En caso de fallo al instalar las dependencias, es necesario instalas el paquete wheel y volver al comando anterior:
pip install wheel

sudo su - postgres
psql -c "create user decide with password 'decide'"
psql -c "create database decide owner decide"
Entramos en la carpeta del proyecto (cd decide) y realizamos las migraciones correspondientes para preparar la base de datos:

Entramos en la carpeta del proyecto (cd decide) y realizamos la primera migración para preparar la
base de datos que utilizaremos:
Además, será necesario instalar las dependencias correspondientes al panel de control desarrollado con
React. Para ello, primero se deberán tener instaldas las siguientes librerías de js con sus correspondientes
versiones: Node=14.15.0, npm=7.8.0.

./manage.py migrate
A continuación, entramos en la carpeta del panel (cd decide_panel) y ejecutamos el siguiente comando:

npm install

Situados en el directorio raíz del proyecto, entramos en la carpeta del proyecto (cd decide) y
realizamos la primera migración para preparar la base de datos que utilizaremos:

./manage.py makemigrations
./mange.py migrate

Por último, ya podremos ejecutar el módulos o módulos seleccionados en la configuración de la
siguiente manera:

./manage.py runserver

También debemos lanzar el panel de control, para ello dentro de la carpeta decide_panel ejecutamos:

npm start

Ejecutar con docker
-------------------

Expand Down
2 changes: 1 addition & 1 deletion decide/administration/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "App.css";

const App = () => {
return (
<div className="App">
<div className="App flex justify-center">
<AppRoutes />
</div>
);
Expand Down
15 changes: 15 additions & 0 deletions decide/administration/frontend/src/api/authApiUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { axios } from "api/axios";

const authApi = {
login: (username: string, password: string) => {
return axios.post("/auth/login", {
username,
password,
});
},
logout: () => {
return axios.post("/auth/logout");
},
};

export default authApi;
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import Axios, { AxiosRequestConfig } from "axios";
import { localStore } from "store";

const API_URL = "http://localhost:8000/administration/api/";
import { sessionUtils } from "utils";

const API_URL = "http://localhost:8000/administration/api";

export const axios = Axios.create({
baseURL: API_URL,
});

// Headers interceptor
axios.interceptors.request.use((config: AxiosRequestConfig) => {
const token = localStore.getToken();
if (config.headers) {
// auth
if (token) config.headers.token = `${token}`;
// content-type
config.headers.Accept = "application/json";
config.headers.ContentType = "application/json";
config.headers["Access-Control-Allow-Origin"] = "*";
}

return config;
});

// Auth interceptor (logout)
axios.interceptors.response.use(
(response) => {
return response.data;
},
(error) => {
if (error.response?.status === 403) {
sessionUtils.removeToken();
window.location.reload();
}
return Promise.reject(error);
}
);

// Error handling interceptor
axios.interceptors.response.use(
(response) => {
Expand Down
2 changes: 1 addition & 1 deletion decide/administration/frontend/src/api/baseApiUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { axios } from "api/config";
import { axios } from "api/axios";


const baseApi = {
Expand Down
2 changes: 1 addition & 1 deletion decide/administration/frontend/src/api/userApiUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { axios } from "api/config";
import { axios } from "api/axios";

const userApi = {
// bulk operations
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";

import { FormLabel, Input } from "@mui/material";
import { FormLabel, TextField } from "@mui/material";
import { Controller } from "react-hook-form";
import { InputProps } from ".";

Expand All @@ -11,13 +11,17 @@ const ControlledInput = (props: InputProps) => {
control={props.control}
render={({ field: { onChange, value } }) => (
<div>
<FormLabel>{props.name.toUpperCase()}</FormLabel>
<Input
{props.useFormLabel && (
<FormLabel>{props.name.toUpperCase()}</FormLabel>
)}
<TextField
type={props.type}
name={props.name}
label={props.name}
value={value}
onChange={onChange}
error={props.error !== undefined}
helperText={props.error}
/>
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type FieldProps = {

export type InputProps = FieldProps & {
type?: "text" | "password";
useFormLabel?: boolean;
};

export const FormItem = { TextInput, SecretInput };
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ const Component = (props: { rows: any[]; columns: GridColDef[] }) => {
return (
<div className="w-full">
<DataGrid
autoHeight
rows={props.rows}
columns={props.columns}
pageSize={5}
rowsPerPageOptions={[5]}
checkboxSelection
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
import { authApi } from "api";
import { Button } from "components/01-atoms";
import React from "react";
import { sessionUtils } from "utils";

import Page from "../page";

const HomePage = () => {
return <Page title="Home"></Page>;
return (
<Page title="Home">
<Button
title="Logout"
onClick={() =>
authApi.logout().finally(() => {
sessionUtils.removeToken();
window.location.reload();
})
}
/>
</Page>
);
};

export default HomePage;
34 changes: 28 additions & 6 deletions decide/administration/frontend/src/components/pages/base/login.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react";
import { useForm, SubmitHandler } from "react-hook-form";

import { localStore } from "store";
import { authApi } from "api";

import Page from "../page";
import { FormItem } from "components/01-atoms/Input";
import { Button } from "components/01-atoms";
import { Box } from "@mui/material";
import { sessionUtils } from "utils";

type LoginInputs = {
username: string;
Expand All @@ -18,22 +18,44 @@ const LoginPage = () => {
const {
control,
getValues,
setError,
formState: { errors },
} = useForm<LoginInputs>();

const onSubmitFailed = (e: any) => {
if (!e.response) {
setError("password", { type: "manual", message: "Server Error" });
setError("username", { type: "manual", message: "" });
}
if (e?.response?.status === 400) {
setError("password", {
type: "manual",
message: e.response.data.non_field_errors[0],
});
setError("username", {
type: "manual",
});
}
};

const onSubmit: SubmitHandler<LoginInputs> = (data) => {
console.log("Login:", data.username);
authApi.login(data.username, data.password).then((r) => {
localStore.setToken(r.data);
window.location.reload();
});
authApi
.login(data.username, data.password)
.then((r) => {
sessionUtils.setToken(r?.headers["set-cookie"]?.[0]);
window.location.reload();
})
.catch((e) => {
onSubmitFailed(e);
});
};

return (
<Page title="Log In">
<Box className="flex flex-col w-60 mx-auto my-4">
<form
className="space-y-10"
className="space-y-5"
onSubmit={(e) => {
e.preventDefault();
onSubmit(getValues());
Expand Down
16 changes: 10 additions & 6 deletions decide/administration/frontend/src/components/pages/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ const Page = (props: {
children?: ReactElement | ReactElement[] | string;
}) => {
return (
<Box className="m-1 md:m-5 xl:m-10 justify-center">
<Title title={props.title} variant="h2" />
<Box id="content" className="m-2 inline-block w-10/12">
{props.children}
<>
<Box className="w-10/12 h-screen p-1 md:p-5 xl:p-10 justify-center">
<Title title={props.title} variant="h2" />
<Box id="content" className="m-2 inline-block w-10/12">
{props.children}
</Box>
</Box>
<Box id="actions" className="m-2 inline-block w-2/12"></Box>
</Box>
<Box id="actions" className="m-2 inline-block w-1/12">
{" "}
</Box>
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import { UserTable } from "components/templates/users";

import Page from "../page";
import { userApi } from "api";

// todo: fetch users from api and set rows to the response
const rows = [
Expand All @@ -17,9 +18,18 @@ const rows = [
];

const UsersPage = () => {
const [users, setUsers] = React.useState(rows);

React.useEffect(() => {
userApi.getUsers().then((response) => {
console.log(response);
setUsers(rows);
});
}, []);

return (
<Page title="Users">
<UserTable users={rows} />
<UserTable users={users || rows} />
</Page>
);
};
Expand Down
Loading

0 comments on commit d614003

Please sign in to comment.