Implement RESTful API, JWT auth, SQLite storage
This update brings a huge change to the whole system's structure.
A new RESTful API has been implemented, which allows users to register, login
and store data.
The API only supports HTTP POST, and can be accessed via /api/v1/. Requests must
contain a JSON body with the necessary entries, which are:
/api/v1/register AND /api/v1/login:
{
"username": "username",
"password": "password",
"encoding": "plaintext/base64"
}
(Note: passwords can be encoded via "base64" or "plaintext".)
/api/v1/store:
{
"jwt": "encrypted_key_here",
"url": "https://google.com/"
}
The flow is:
- register via /api/v1/register;
- login via /api/v1/login, listen for JWT token in response;
- store via /api/v1/store, by sending JWT and URL to store.
The SQLite database now has 2 tables, "users" and "history".
The "users" table is used to store user data:
- username;
- password, secured via bcrypt;
- random user UUID.
The "history" table is used to store browsing history:
- user UUID, to identify the user;
- browsed url.
The secret used to sign JWTs is stored in the config.yml file.
Other new features include SQL-injection protection,
multiple validity/security checks on usernames and passwords, etc.
Signed-off-by: Lorenzo Dellacà <lorenzo.dellaca@mind-overflow.net>
2020-08-22 12:51:33 +02:00
|
|
|
package net.mindoverflow.webmarker.utils.sql;
|
|
|
|
|
|
|
|
import net.mindoverflow.webmarker.utils.Cached;
|
|
|
|
|
2020-08-22 18:32:46 +02:00
|
|
|
import java.time.LocalDateTime;
|
|
|
|
import java.time.format.DateTimeFormatter;
|
Implement RESTful API, JWT auth, SQLite storage
This update brings a huge change to the whole system's structure.
A new RESTful API has been implemented, which allows users to register, login
and store data.
The API only supports HTTP POST, and can be accessed via /api/v1/. Requests must
contain a JSON body with the necessary entries, which are:
/api/v1/register AND /api/v1/login:
{
"username": "username",
"password": "password",
"encoding": "plaintext/base64"
}
(Note: passwords can be encoded via "base64" or "plaintext".)
/api/v1/store:
{
"jwt": "encrypted_key_here",
"url": "https://google.com/"
}
The flow is:
- register via /api/v1/register;
- login via /api/v1/login, listen for JWT token in response;
- store via /api/v1/store, by sending JWT and URL to store.
The SQLite database now has 2 tables, "users" and "history".
The "users" table is used to store user data:
- username;
- password, secured via bcrypt;
- random user UUID.
The "history" table is used to store browsing history:
- user UUID, to identify the user;
- browsed url.
The secret used to sign JWTs is stored in the config.yml file.
Other new features include SQL-injection protection,
multiple validity/security checks on usernames and passwords, etc.
Signed-off-by: Lorenzo Dellacà <lorenzo.dellaca@mind-overflow.net>
2020-08-22 12:51:33 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.UUID;
|
|
|
|
|
|
|
|
public class MarkerSQLUtils {
|
|
|
|
|
|
|
|
public static boolean addUser(UUID randomId, String name, String password)
|
|
|
|
{
|
|
|
|
|
|
|
|
String query = "INSERT INTO " + MDatabaseTable.USERS.getTable().getTableSQLName() + " (" +
|
|
|
|
MDatabaseColumn.USER_UUID.getColumn().getColumnSQLName() + ", " +
|
|
|
|
MDatabaseColumn.USERNAME.getColumn().getColumnSQLName() + ", " +
|
|
|
|
MDatabaseColumn.PASSWORD.getColumn().getColumnSQLName() + ") VALUES (?, ?, ?);";
|
|
|
|
|
|
|
|
return Cached.sqlManager.executeUpdate(query, randomId.toString(), name, password);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean userExists(String name)
|
|
|
|
{
|
|
|
|
String query = "SELECT " + MDatabaseColumn.USERNAME.getColumn().getColumnSQLName() +
|
|
|
|
" FROM " + MDatabaseTable.USERS.getTable().getTableSQLName() +
|
|
|
|
" WHERE " + MDatabaseColumn.USERNAME.getColumn().getColumnSQLName() +
|
|
|
|
" = ? ;";
|
|
|
|
|
|
|
|
List<String> result = Cached.sqlManager.executeStatement(query, MDatabaseColumn.USERNAME, name);
|
|
|
|
return result.size() > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean uuidTaken(UUID randomId)
|
|
|
|
{
|
|
|
|
String query = "SELECT " + MDatabaseColumn.USER_UUID.getColumn().getColumnSQLName() +
|
|
|
|
" FROM " + MDatabaseTable.USERS.getTable().getTableSQLName() +
|
|
|
|
" WHERE " + MDatabaseColumn.USER_UUID.getColumn().getColumnSQLName() +
|
|
|
|
" = ? ;";
|
|
|
|
|
|
|
|
List<String> result = Cached.sqlManager.executeStatement(query, MDatabaseColumn.USER_UUID, randomId.toString());
|
|
|
|
if(result.size() > 0) return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static UUID getUserUUID(String username)
|
|
|
|
{
|
|
|
|
String query = "SELECT " + MDatabaseColumn.USER_UUID.getColumn().getColumnSQLName() +
|
|
|
|
" FROM " + MDatabaseTable.USERS.getTable().getTableSQLName() +
|
|
|
|
" WHERE " + MDatabaseColumn.USERNAME.getColumn().getColumnSQLName() +
|
|
|
|
" = ? ;";
|
|
|
|
|
|
|
|
List<String> result = Cached.sqlManager.executeStatement(query, MDatabaseColumn.USER_UUID, username);
|
|
|
|
if(result.size() != 1) return null; //todo: error!
|
|
|
|
|
|
|
|
return UUID.fromString(result.get(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo: use UUID?
|
|
|
|
public static String getUserBcryptedPassword(String username)
|
|
|
|
{
|
|
|
|
String query = "SELECT " + MDatabaseColumn.PASSWORD.getColumn().getColumnSQLName() +
|
|
|
|
" FROM " + MDatabaseTable.USERS.getTable().getTableSQLName() +
|
|
|
|
" WHERE " + MDatabaseColumn.USERNAME.getColumn().getColumnSQLName() +
|
|
|
|
" = ? ;";
|
|
|
|
|
|
|
|
List<String> result = Cached.sqlManager.executeStatement(query, MDatabaseColumn.PASSWORD, username);
|
|
|
|
if(result.size() != 1) return null; // todo: error!
|
|
|
|
|
|
|
|
return result.get(0);
|
|
|
|
}
|
|
|
|
|
2020-08-22 18:32:46 +02:00
|
|
|
public static boolean addHistoryRecord(UUID uuid, String url, LocalDateTime timestampUTC)
|
Implement RESTful API, JWT auth, SQLite storage
This update brings a huge change to the whole system's structure.
A new RESTful API has been implemented, which allows users to register, login
and store data.
The API only supports HTTP POST, and can be accessed via /api/v1/. Requests must
contain a JSON body with the necessary entries, which are:
/api/v1/register AND /api/v1/login:
{
"username": "username",
"password": "password",
"encoding": "plaintext/base64"
}
(Note: passwords can be encoded via "base64" or "plaintext".)
/api/v1/store:
{
"jwt": "encrypted_key_here",
"url": "https://google.com/"
}
The flow is:
- register via /api/v1/register;
- login via /api/v1/login, listen for JWT token in response;
- store via /api/v1/store, by sending JWT and URL to store.
The SQLite database now has 2 tables, "users" and "history".
The "users" table is used to store user data:
- username;
- password, secured via bcrypt;
- random user UUID.
The "history" table is used to store browsing history:
- user UUID, to identify the user;
- browsed url.
The secret used to sign JWTs is stored in the config.yml file.
Other new features include SQL-injection protection,
multiple validity/security checks on usernames and passwords, etc.
Signed-off-by: Lorenzo Dellacà <lorenzo.dellaca@mind-overflow.net>
2020-08-22 12:51:33 +02:00
|
|
|
{
|
|
|
|
String query = "INSERT INTO " + MDatabaseTable.HISTORY.getTable().getTableSQLName() + " (" +
|
|
|
|
MDatabaseColumn.USER_UUID.getColumn().getColumnSQLName() + ", " +
|
2020-08-22 18:32:46 +02:00
|
|
|
MDatabaseColumn.WEB_DOMAIN.getColumn().getColumnSQLName() + ", " +
|
|
|
|
MDatabaseColumn.TIMESTAMP_UTC.getColumn().getColumnSQLName() + ") VALUES (?, ?, ?);";
|
Implement RESTful API, JWT auth, SQLite storage
This update brings a huge change to the whole system's structure.
A new RESTful API has been implemented, which allows users to register, login
and store data.
The API only supports HTTP POST, and can be accessed via /api/v1/. Requests must
contain a JSON body with the necessary entries, which are:
/api/v1/register AND /api/v1/login:
{
"username": "username",
"password": "password",
"encoding": "plaintext/base64"
}
(Note: passwords can be encoded via "base64" or "plaintext".)
/api/v1/store:
{
"jwt": "encrypted_key_here",
"url": "https://google.com/"
}
The flow is:
- register via /api/v1/register;
- login via /api/v1/login, listen for JWT token in response;
- store via /api/v1/store, by sending JWT and URL to store.
The SQLite database now has 2 tables, "users" and "history".
The "users" table is used to store user data:
- username;
- password, secured via bcrypt;
- random user UUID.
The "history" table is used to store browsing history:
- user UUID, to identify the user;
- browsed url.
The secret used to sign JWTs is stored in the config.yml file.
Other new features include SQL-injection protection,
multiple validity/security checks on usernames and passwords, etc.
Signed-off-by: Lorenzo Dellacà <lorenzo.dellaca@mind-overflow.net>
2020-08-22 12:51:33 +02:00
|
|
|
|
2020-08-22 18:32:46 +02:00
|
|
|
DateTimeFormatter sqlDateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
String timestampSQL = sqlDateTime.format(timestampUTC);
|
|
|
|
|
|
|
|
System.out.println("SQL Timestamp: " + timestampSQL);
|
|
|
|
|
|
|
|
return Cached.sqlManager.executeUpdate(query, uuid.toString(), url, timestampSQL);
|
Implement RESTful API, JWT auth, SQLite storage
This update brings a huge change to the whole system's structure.
A new RESTful API has been implemented, which allows users to register, login
and store data.
The API only supports HTTP POST, and can be accessed via /api/v1/. Requests must
contain a JSON body with the necessary entries, which are:
/api/v1/register AND /api/v1/login:
{
"username": "username",
"password": "password",
"encoding": "plaintext/base64"
}
(Note: passwords can be encoded via "base64" or "plaintext".)
/api/v1/store:
{
"jwt": "encrypted_key_here",
"url": "https://google.com/"
}
The flow is:
- register via /api/v1/register;
- login via /api/v1/login, listen for JWT token in response;
- store via /api/v1/store, by sending JWT and URL to store.
The SQLite database now has 2 tables, "users" and "history".
The "users" table is used to store user data:
- username;
- password, secured via bcrypt;
- random user UUID.
The "history" table is used to store browsing history:
- user UUID, to identify the user;
- browsed url.
The secret used to sign JWTs is stored in the config.yml file.
Other new features include SQL-injection protection,
multiple validity/security checks on usernames and passwords, etc.
Signed-off-by: Lorenzo Dellacà <lorenzo.dellaca@mind-overflow.net>
2020-08-22 12:51:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|