Marco Cetica
d90d9d1f40
All checks were successful
bit / docker (push) Successful in 1m41s
In this version: - Removed vavr library; - Refactoring using LambdaTonic library; - Fixed bug related to the raw API; - Increased the expiration date from one year from now; - Fixed CD race condition; - Updated to the latest Spring boot version; |
||
---|---|---|
.gitea/workflows | ||
.github/workflows | ||
src | ||
.gitignore | ||
compose.yml | ||
Dockerfile | ||
LICENSE | ||
pom.xml | ||
README.md |
Bit
Bit is a simple, web-based, self-hostable text sharing platform written in Java and Spring. You can access it from here.
The frontend is also open-source, and it's available on this page.
General
Bit can be used both from the frontend and through the REST API. Before using it, read the following technical notices:
-
By default, each new "text"(from now on: post) added to the platform is anonymous and expires after one week. In order to associate a new post to an identity, you first need to register a new user account. The registration process requires a unique username, a unique email address and a password. User accounts can NOT be modified or recovered; therefore if you lose your password, you will need to create a new account using a new email address.
-
Each user account is associated with a user role that determines the granular access to the special endpoints. The user role is set by default to unprivileged at registration time and can be altered only by manually modifying the database.
-
Special endpoints are only accessible to the privileged user class.
-
Posts published with a valid user identity can be altered or deleted. In order to do that, you need to authenticate yourself with your credentials within the update/delete request. Anonymous posts, on the other hand, can NOT be altered or removed; if you think that a certain content goes against the terms of service, you can email the owner of the bit instance.
-
The expiration date controls whether the post can be showed or not, once the current date is greater or equal than the expiration date, the post is classified as expired and thus shall not be showed. Expired posts are NOT deleted but may be manually removed by the instance owner.
-
The bit platform is stateless, hence there is no such thing as user session. Every time you need to use your user account for a certain operation(e.g., create a new post with an identity or delete an existing, non-anonymous post) you will need to provide your user credentials.
-
Deleting an existing user, will result in a cascade delete of any existing post associated with that user.
-
User signup can be disabled by setting the environment variable
BIT_DISABLE_SIGNUP
to1
. By default, user registration is enabled(seedocker-compose.yml
).
Database
New posts are stored on a relational database(PostgreSQL) using the Spring ORM system(Hibernate). The architecture of the bit platform consists of two tables: bt_users and bt_posts. The former stores the user accounts, and it's defined as follows:
Column | Data Type | Nullable |
---|---|---|
user ID | String |
false |
created at | YYYY-MM-DD Date |
false |
String |
false |
|
password | BCrypt |
false |
role | UserRole |
false |
username | String |
false |
The latter, instead, stores the posts, and it's defined as follows:
Column | Data Type | Nullable |
---|---|---|
post ID | String |
false |
content | String |
false |
created at | YYYY-MM-DD date |
false |
expiration date | YYYY-MM-DD date |
true |
title | String |
false |
user ID | Foreign key constrain |
true |
The user password is stored using a BCrypt
based hash. Each post can be associated with one
user(eventually zero) while each user can be associate with multiple posts(eventually zero).
The relationship is of the type "one to many" from the user's perspective.
Deploy
In order to deploy the bit platform, you will need to install Docker/Podman and docker-compose. Once done that, you can easily launch the backend using the following command:
$> docker-compose up -d
By default, the following parameters are used:
SERVER_PORT
: "3000";POSTGRES_USER
: "bituser";POSTGRES_PASSWORD
: "qwerty1234";POSTGRES_DB
: "bit";SPRING_SECURITY_USER_NAME
: "admin";SPRING_SECURITY_USER_PASSWORD
: "admin".
Be sure to update these values by editing thedocker-compose.yml
file. Once the containers
are deployed, you can expose the application through a reverse proxy:
location /api {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Endpoints
The backend exposes the following REST APIs:
POST
New User(/api/users/new
):
Description: Add new user.
Parameters: username(string
), email(string
) password(string
).
DELETE
Delete User(/api/users/delete
):
Description: Delete an existing user.
Parameters: email(string
) password(string
).
POST
User List(/api/users
):
(special endpoint)
Description: Retrieve all users.
Parameters: email(string
), password(string
).
POST
Post List(/api/posts
):
(special endpoint)
Description: Retrieve all posts.
Parameters: email(string
), password(string
).
GET
Post By ID(/api/posts/{postID}
):
Description: Search a post by its ID.
Parameters: none.
GET
Post Content By ID(/api/posts/raw/{postId}
):
Description: Retrieve post content by its ID.
Parameters: none.
POST
Post By Title(/api/posts/bytitle
):
(special endpoint)
Description: Search a post by its title.
Parameters: title(string
), user(User
).
POST
New Post(/api/posts/new
):
Description: Add a new post.
Parameters: title(string
), content(string
), expirationDate(YYYY-MM-DD
),
user(User
).
PUT
Edit Post(/api/posts/{postID}
):
Description: Update an existing, non-anonymous post.
Parameters: title(string
), content(string
), user(User
).
DELETE
Delete Post(/api/posts/{postID}
):
Description: Delete an existing, non-anonymous post.
Parameters: user(User
).
Examples
Below there are some practical examples on how to use the REST API:
- Add a non-anonymous(note: the user must exist)
POST
request to /api/posts/new
with the following body:
{
"title": "Hello World",
"content": "This is a example text snippet",
"expirationDate": null,
"user": {
"email": "john@example.com",
"password": "very_bad_pw"
}
}
- Add an anonymous post with expiration date set to January 25, 2024
POST
request to /api/posts/new
with the following body:
{
"title": "Hello World",
"content": "This is a example text snippet",
"expirationDate": "2024-01-25"
}
- Delete post "
afj45c
"
DELETE
request to /api/posts/afj45c
with the following body:
{
"email": "john@example.com",
"password": "very_bad_pw"
}
- Get list of all post whose title is "
foo
"
GET
request to /api/posts/bytitle
with the following body:
{
"title": "foo",
"user": {
"email": "john@example.com",
"password": "very_bad_pw"
}
}
In this case user john@example.com
is a user of the class PRIVILEGED
.
- Get content of post "
af4598c
"
GET
request to /api/posts/raw/af4598c
with empty body.
Unit tests
The bit platform provides some unit tests for the post and the user controllers. You can
find them in src/test
. The unit tests are automatically executed during the container bootstrap
process, to manually run them issue the following command:
$> ./mvnw test
License
This software is released under the GPLv3 license. You can find a copy of the license with this repository or by visiting the following page.