mirror of
https://github.com/hubHarmony/servii-backend.git
synced 2024-11-17 21:40:31 +00:00
[+] Added basic firebase authentication checks, and added firestore basic functions.
Signed-off-by: Charles Le Maux <charles.le-maux@epitech.eu>
This commit is contained in:
parent
acd72ffa8a
commit
9ccef01999
25
api.py
25
api.py
@ -4,6 +4,7 @@ import inspect
|
||||
from flask import Flask, Response, jsonify, request
|
||||
from flask_cors import CORS
|
||||
|
||||
import firebase_manager
|
||||
import generic_executor
|
||||
|
||||
app = Flask(__name__)
|
||||
@ -44,6 +45,19 @@ def parse_and_validate_request(parameters: [str]) -> list[str]:
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
raise Exception("Empty request body.")
|
||||
if 'jwt' not in data:
|
||||
raise Exception("Missing 'token' in request body. The API doesn't support anonymous access anymore.")
|
||||
else:
|
||||
valid, user_id = firebase_manager.verify_jwt_token(data['jwt'])
|
||||
if not valid:
|
||||
raise Exception("Invalid JWT token.")
|
||||
else:
|
||||
user = firebase_manager.get_user_from_id(user_id)
|
||||
if not user:
|
||||
raise Exception("User not found.")
|
||||
if not user.email_verified:
|
||||
raise Exception("Your google account isn't verified yet.")
|
||||
pass
|
||||
for name in parameters:
|
||||
if name not in data:
|
||||
raise Exception(f"Missing parameter {name}")
|
||||
@ -73,13 +87,14 @@ def dynamic_route_handler(path):
|
||||
route_fn = route_handlers[path]
|
||||
parameters = []
|
||||
sig = inspect.signature(route_fn)
|
||||
|
||||
for param in sig.parameters.values():
|
||||
parameters.append(param.name)
|
||||
|
||||
mapped_parameters = parse_and_validate_request(parameters)
|
||||
status: http.HTTPStatus = route_fn(*mapped_parameters)
|
||||
return generic_response_maker(status)
|
||||
try :
|
||||
mapped_parameters = parse_and_validate_request(parameters)
|
||||
status: http.HTTPStatus = route_fn(*mapped_parameters)
|
||||
return generic_response_maker(status)
|
||||
except Exception as e:
|
||||
return generic_response_maker(http.HTTPStatus.BAD_REQUEST, str(e))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -42,6 +42,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
button.addEventListener('click', async event => {
|
||||
const form = event.target.closest('form');
|
||||
const action = button.dataset.action;
|
||||
const jwt = "0";
|
||||
const email = document.getElementById('accountEmail').value;
|
||||
const port = document.getElementById('accountPort').value;
|
||||
const name = document.getElementById('serverName').value;
|
||||
@ -52,28 +53,28 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
var data = {}
|
||||
switch(action) {
|
||||
case 'AccountCreate':
|
||||
data = {email, port}
|
||||
data = {email, port, jwt}
|
||||
break;
|
||||
case 'AccountDelete':
|
||||
data = {email, port}
|
||||
data = {email, port, jwt}
|
||||
break;
|
||||
case 'ServerCreate':
|
||||
data = {port, name, version}
|
||||
data = {port, name, version, jwt}
|
||||
break;
|
||||
case 'ServerDelete':
|
||||
data = {port, name}
|
||||
data = {port, name, jwt}
|
||||
break;
|
||||
case 'ServerRun':
|
||||
data = {port, name}
|
||||
data = {port, name, jwt}
|
||||
break;
|
||||
case 'ServerStop':
|
||||
data = {port, name}
|
||||
data = {port, name, jwt}
|
||||
break;
|
||||
case 'UpdateProperty':
|
||||
data = {port, name, prop, value}
|
||||
data = {port, name, prop, value, jwt}
|
||||
break;
|
||||
case 'Command':
|
||||
data = {port, name, command}
|
||||
data = {port, name, command, jwt}
|
||||
break;
|
||||
}
|
||||
sendRequest(action, data)
|
||||
|
@ -1,10 +1,13 @@
|
||||
from datetime import datetime
|
||||
|
||||
import jwt
|
||||
import firebase_admin
|
||||
from firebase_admin import credentials, auth
|
||||
from firebase_admin import credentials, auth, firestore
|
||||
from google.api_core.exceptions import NotFound, PermissionDenied, Aborted, ResourceExhausted, OutOfRange, DataLoss
|
||||
|
||||
cred = credentials.Certificate('servii.json')
|
||||
firebase_admin.initialize_app(cred)
|
||||
|
||||
firestore_database = firestore.client()
|
||||
|
||||
'''
|
||||
TODO
|
||||
@ -15,6 +18,7 @@ Tell the database they have now stopped running.
|
||||
Also ensure the program can add an additional argument to avoid this checking for scalability.
|
||||
'''
|
||||
|
||||
|
||||
def get_user_from_id(user_id):
|
||||
return auth.get_user(user_id)
|
||||
|
||||
@ -28,3 +32,44 @@ def verify_jwt_token(token):
|
||||
return False, None
|
||||
except jwt.InvalidTokenError:
|
||||
return False, None
|
||||
|
||||
|
||||
def create_firestore(user_id: str, data: dict) -> bool:
|
||||
doc_ref = firestore_database.collection('users').document(user_id)
|
||||
try:
|
||||
doc_ref.create(data)
|
||||
return True
|
||||
except (NotFound, PermissionDenied, Aborted, ResourceExhausted,
|
||||
OutOfRange, DataLoss, TypeError, Exception, ValueError) as e:
|
||||
log_exception_to_firestore(e, user_id, data)
|
||||
return False
|
||||
|
||||
|
||||
def update_firestore(user_id: str, data: dict) -> bool:
|
||||
doc_ref = firestore_database.collection('users').document(user_id)
|
||||
try:
|
||||
doc_ref.update(data)
|
||||
return True
|
||||
except (NotFound, PermissionDenied, Aborted, ResourceExhausted,
|
||||
OutOfRange, DataLoss, TypeError, Exception, ValueError) as e:
|
||||
log_exception_to_firestore(e, user_id, data)
|
||||
return False
|
||||
|
||||
|
||||
def log_exception_to_firestore(exception: Exception = None, user_id: str = None, data: dict = None):
|
||||
new_id: str = datetime.now().strftime('%Y-%m-%d %H:%M:%S %Z%z')
|
||||
log_entry = {
|
||||
'exception_name': str(type(exception).__name__),
|
||||
'exception': str(exception) if exception else 'No exception',
|
||||
'user_id': str(user_id) if user_id else 'No user_id',
|
||||
'data': str(data) if data else 'No data provided',
|
||||
}
|
||||
try:
|
||||
firestore_database.collection('firebase.logs').document(new_id).create(log_entry)
|
||||
print("Log entry added successfully.")
|
||||
except Exception as e:
|
||||
print(f"Failed to add log entry: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
@ -1,5 +1,6 @@
|
||||
from server_mc_manager import MinecraftServerManager
|
||||
from http import HTTPStatus
|
||||
|
||||
import file_manager
|
||||
|
||||
mc_manager: MinecraftServerManager = MinecraftServerManager()
|
||||
@ -90,3 +91,6 @@ def run_command(port: str, command: str) -> HTTPStatus:
|
||||
print(f"Error executing command: {e}")
|
||||
return HTTPStatus.INTERNAL_SERVER_ERROR
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
@ -1,4 +1,4 @@
|
||||
firebase_admin==6.5.0
|
||||
Flask==3.0.3
|
||||
Flask_Cors==4.0.1
|
||||
plotly==5.22.0
|
||||
psutil==5.9.8
|
||||
PyJWT==2.8.0
|
||||
|
Loading…
Reference in New Issue
Block a user