This device manager was developed as part of the course Advanced Software Engineering (module code: 36632b) at the University of Regensburg.
The Device Manager is a web-based solution for managing devices at the University of Regensburg. For this purpose, a backend with FastAPI ⚡ and a SQLite database as well as a frontend with React.js ⚛️ were implemented.
Name | Contact | |
---|---|---|
Nils Constantin Hellwig | Nils-Constantin.Hellwig@student.ur.de |
For both of the following installation guides (Docker / Manual Installation), clone this repository:
git clone https://git.uni-regensburg.de/ase22ws/abschlussprojekt-device-manager-nils-constantin-hellwig.git
By default, there are two users with whom you can log in:
Username | Password |
---|---|
admin |
vollgeheim |
user |
test123 |
In the main directory there is a docker-compose.yml
. The containers described in it can be started as follows:
docker-compose up
The backend (API) is accessible via http://localhost:8000 (documentation via http://localhost:8000/api/docs). The frontend can be opened in the browser via this link: http://localhost:3000.
Additional Note: For Production proposes, a database file, logging file and the folder with the device's images can be mounted using the volumes
key in docker-compose.yml:
...
backend_device_manager:
...
volumes:
- ./backend/public_images:/public_images
- ./backend/logger.csv:/logger.csv
- ./backend/device_manager_app.db:/device_manager_app.db
These files can then be stored on the host file system instead of being stored inside of the container.
Requirements:
- Node.js
- Python 3 environment (e.g. using a Virtual Environment or Conda) to install required packages
- Navigate to
/backend
:
cd backend
- Install required packages:
pip install -r requirements.txt
- Start API (Frontend listens to
locahost:8000
):
uvicorn --host 0.0.0.0 --port 8000 device_manager_app.main:app --reload
- Add a second command line session and navigate to
/frontend
:
cd frontend
- Install required packages:
npm install
- Start development server (Development server should be accessable at http://localhost:3000):
npm start
(Optional) For production run:
npm run build
In order to test a wide range of the backend's functionalities, a testsuite has been implemented which can be found in the /tests
folder. It tests post, get, update API requests as well as the routes for authentication. To execute the tests, pytest must be used.
To perform the tests the following steps must be followed:
- Navigate to the directory with all tests
cd tests
- Install all required packages
pip install -r requirements.txt
- Execute all Tests (Detailled Report)
pytest . --no-header -vv
Important note: Running this script will delete all entries from the database used by the backend.
There are some environment variables that can be specified optionally. Default values are specified in the project. However, it is highly recommended to use other passwords and hashing codes for production.
Variable | Default Value |
---|---|
FRONTEND_URL |
http://localhost:3000 |
REACT_APP_BACKEND_URL |
http://0.0.0.0:8000 |
SECRET_KEY_HASHING |
be23577f58d27f38c6ef90693dadcb00148c37810af6849ce11bcfcbc450803e |
ALGORITHM_HASHING |
HS256 |
ADMIN_PASSWORD |
vollgeheim |
TEST_STANDARD_USER_PASSWORD |
test123 |
ACCESS_TOKEN_EXPIRE_MINUTES |
120 |
PUBLIC_IMAGES_DIR |
./public_images |
Example for adding a environmental variable:
export REACT_APP_BACKEND_URL=http://0.0.0.0:8000
Every request to the backend is logged. A middleware (at the end of backend/device_manager_app/main.py
) was implmented in FastAPI for this purpose. Logs stored in backend/logger.csv
.
Example:
timestamp request,request route,request method,response code,duration in ms
Wed Apr 5 09:43:42 2023,/api/check_auth,GET,401,0.7119178771972656
Optionally, the body request / response of the routes could also be saved. For this, the marked positions from the middleware must be commented out.
- FastAPI is used for developing a RESTful API
- Detailled Documentation regarding all available routes should be acessible via
/api/docs
- Via
/api/login
, one is able to authenticate via POST request with user/password - All actions that change data are only possible if authenticated, wherby devices/users can only be deleted with the authenticated user having admin privileges
- If the backend is started, the two user accounts admin (with admin privileges) and user123 are created (if they do not exist)
- An endpoint
/api/export
, which outputs the complete database content as JSON data. - An endpoint
/api/import
, which transfers all transferred JSON data into the database into the database, data gets validated in backend (only if valid, entires are persisted in the database). This route should be able to accept the dummy data that is available here. - With the help of
/api/purge
it should be possible to delete all available entries in the database - All actions are to be stored in a log file, a middleware was implemented for this purpose (execution times and status code are stored, among other things).
Column | Type | Unique | Required |
---|---|---|---|
rz_username PK |
String | Yes | Yes |
full_name | String | No | Yes |
organisation_unit | String | No | Yes |
has_admin_privileges | Boolean | No | Yes |
hashed_password | String | No | Yes |
Column | Type | Unique | Required |
---|---|---|---|
device_id PK |
String | Yes | Yes |
title | String | No | Yes |
device_type | String | No | Yes |
description | String | No | No |
accessories | String | No | No |
rz_username_buyer | String | Yes | Yes |
serial_number | String | No | Yes |
image_url | String | No | Yes |
Column | Type | Unique | Required |
---|---|---|---|
owner_transaction_id PK |
String | Yes | Yes |
rz_username | String | No | Yes |
timestamp_owner_since | Integer (Unix Timestamp) | No | Yes |
device_id FK |
String | No | Yes |
Column | Type | Unique | Required |
---|---|---|---|
location_transaction_id PK |
String | Yes | Yes |
room_code | String | No | Yes |
timestamp_located_since | Integer (Unix Timestamp) | No | Yes |
device_id FK |
String | No | Yes |
Column | Type | Unique | Required |
---|---|---|---|
purchasing_information_id PK |
String | Yes | Yes |
price | String | No | Yes |
timestamp_warranty_end | Integer (Unix Timestamp) | No | Yes |
timestamp_purchase | Integer (Unix Timestamp) | No | Yes |
cost_centre | Integer (len=8) | No | Yes |
seller | String | No | No |
device_id FK |
String | Yes | Yes |
In order to retrieve data regarding the devices in a user-friendly way, a simple frontend was developed that makes requests to the API and displays information fetched from the backend. The requirements for this interface are described below in the form of user stories. In addition, quality of service and design requirements are described.
-
As a user, I would like to be able to log in with my account so that I can access the main user interface / device data.
-
As a user, I would like to be able to add a new device using a form so that they are saved in the database.
-
As a user, I would like to be advised if information regarding a new unit is incorrect/incomplete when using the form (to add a new device) so that I can adjust/add missing information to it.
-
As a user, I would like to close a form if I decide not to add a new device after all, so that I'm back on the page with all devices being listed.
-
As a user, I would like to have access to a list of all the devices in the database so that I can find information about them.
-
As a user, I would like to be able to select a device in the list to view more detailed information on it.
-
As a user, I would like to be able to edit information on the detailed information page for a device regarding the current owner and location of the device.
-
As a user, I would like to be able to see all the information available on a device on the detailed information page.
-
As a user I do not want to have to log in again when I reload the page or go to the page at a later time so that I have direct access to all functionalities.
-
As an administrator, I want to be able to view a list of who previously owned a device on the detail page of a device.
-
As an administrator, I would like to be able to edit information on the detailed information page for a device in order to adjust it in the database.
- The design should be simple but aesthetically pleasing
- Users should stay logged in after they refresh the page or come back to the page later. This is to be made possible by a cookie.
- The user interface should be responsive so that it can be used comfortably on both a PC and a mobile device.
- When selecting a device/room code, help users to select a valid value
- The possibility to register in the front-end is not intended. However, there
/api/register
allows users with admin privileges to create new user accounts.
After the backend and frontend have been started and the frontend listens to the ip/port of the backend, users can authenticate in the frontend. The LocalStorage API was used to ensure that users remain logged in even during a page refresh and are only redirected to the login screen once the token has expired.
As soon as you have logged in, the main page appears with information about the logged-in user (name, privileges, organisation unit) and a list of all devices in the database. Administrators are allowed to delete devices from the database using the delete button.
In addition, administrators are allowed to download the database as a JSON file or import entries as a JSON file using the frontend.
Logged-in users can add devices by clicking on "Neues Gerät hinzufügen". When entering data, the system tries to help the user as much as possible by providing drop-down menus with choices for the individual data as well as suggestions.
There is also the possibility to upload pictures, which are then stored in the database for a device.
Finally, when submitting the data to add a new device, detailed error messages are displayed in case of invalid input for one of the fields. If you want to leave the form before submitting it, you will be informed that the fields you have entered until then are not to be stored after closing the form.
For devices that have already been saved in the database, administrators can change all data in the frontend.
Images can also be uploaded subsequently by administrators. Images that have been replaced are deleted in the backend and are not versioned.
A user without admin privileges is only allowed to change the current owner / location of a device. This permission is ensured by both the backend and frontend.
Administrators are allowed to view the versioning regarding location/owner at the end of the detail page.
Once you have finished using the Device Manager service, you can log out at any time using the logout button.
- Issues: Issues are used in GitLab for each feature of the software to be implemented. Particularly in the case of bigger features, acceptance criteria are formulated so that it can be checked in the course of development which part still has to be implemented. At the end it needs to be checked whether all acceptance criteria have been met before closing the issue.
-
Branches: For every issue that describes a feature to be implemented, a branch should be created based on the main branch.
-
Commits: Commit messages should always be in the imperative present tense and should describe the changes briefly and accurately.
- FastAPI documentation: https://fastapi.tiangolo.com/
- Simple OAuth2 with Password and Bearer: https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/
- FastAPI Tutorial: https://fastapi.tiangolo.com/tutorial/sql-databases/
- React concepts: https://www.w3schools.com/react/
- pytest documentation: https://docs.pytest.org/en/7.2.x/
Further sources are additionally mentioned in the source code.
This project is licensed under the terms of the MIT license (see here: LICENSE).
All external packages must be installed using pip/npm and are not part of this source code / repository.
Column | License | Link |
---|---|---|
FastAPI | MIT License | LICENSE |
SQLAlchemy | MIT License | LICENSE |
uvicorn | BSD 3-Clause "New" or "Revised" License | LICENSE |
bcrypt | Apache License 2.0 | LICENSE |
python-jose | MIT License | LICENSE |
passlib | BSD 2-Clause License | LICENSE |
python-multipart | Apache License 2.0 | LICENSE |
pytest | MIT License | LICENSE |
requests | Apache License 2.0 | LICENSE |
Column | License | Link |
---|---|---|
React.js | MIT License | LICENSE |
Phosphor Icons | MIT License | LICENSE |
@radix-ui/react-tooltip | MIT License | LICENSE |
@react-md/autocomplete | MIT License | LICENSE |
React Toastify | MIT License | LICENSE |
react-confirm-alert | MIT License | LICENSE |