servii-backend/firebase_manager.py

182 lines
6.1 KiB
Python
Raw Normal View History

from datetime import datetime
import firebase_admin
import jwt
from firebase_admin import auth, credentials, firestore
from google.api_core.exceptions import Aborted, DataLoss, NotFound, OutOfRange, PermissionDenied, ResourceExhausted
import file_manager
cred = credentials.Certificate('secrets/servii.json')
app = firebase_admin.initialize_app(cred)
firestore_database = firestore.client()
'''
TODO
Write a function that launches upon app's startup, it does check in the firestore for any already running servers.
Fetches the PID's.
Stops all the current processes,
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)
def verify_jwt_token(token):
try:
decoded_token = jwt.decode(token, options={"verify_signature": False})
user_id = decoded_token.get('sub')
return True, user_id
except jwt.ExpiredSignatureError:
return False, None
except jwt.InvalidTokenError:
return False, None
def fetch_port() -> int or None:
servers_ref = firestore_database.collection("users")
query = servers_ref.order_by("port", direction="DESCENDING").limit(1)
highest_port_doc = next(query.stream(), None)
if highest_port_doc:
return highest_port_doc.get('port')
return None
def user_field_exists(user_id: str, field: str) -> bool:
try:
doc = firestore_database.collection('users').document(user_id).get()
if doc.exists:
return True
return False
except NotFound:
return False
def server_name_taken(user_id: str, server_name: str) -> bool:
servers = firestore_database.collection('users').document(user_id).collection('servers')
query = servers.where(field_path='name', op_string='==', value=server_name)
for _ in query.stream():
return True
return False
def get_user_field(user_id, field_name):
user_doc_ref = firestore_database.collection('users').document(user_id)
user_doc = user_doc_ref.get()
if user_doc.exists:
field_value = user_doc.to_dict().get(field_name)
return field_value
else:
return None
def get_server_port(user_id: str) -> int or None:
try:
servers_ref = firestore_database.collection('users').document(user_id)
server_doc = servers_ref.get()
port = server_doc.get('port')
return port if port else None
except Exception:
return 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 set_firestore(user_id: str, data: dict) -> bool:
doc_ref = firestore_database.collection('users').document(user_id)
try:
doc_ref.set(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 create_server(user_id: str, server_name: str, version: str, port: str, framework: str = "paper"):
port: int = int(port)
servers_ref = firestore_database.collection('users').document(user_id).collection('servers')
server_doc_ref = servers_ref.document(server_name)
server_doc_ref.set(
{'name': server_name,
'port': port,
'running': "false",
'version': version,
'framework': framework,
"difficulty": "easy",
"gamemode": "survival",
"forceGamemode": "false",
"hardcore": "false",
"generateStructures": "true",
"motd": "A Minecraft Server",
"pvp": "true",
"onlineMode": "true",
"maxPlayers": 20,
"enableCommandBlock": "false"})
def delete_server(user_id: str, server_name: str):
user_ref = firestore_database.collection('users').document(user_id)
servers_ref = user_ref.collection('servers')
server_doc_ref = servers_ref.document(server_name)
server_doc_ref.delete()
def delete_user(user_id: str):
user_ref = firestore_database.collection('users').document(user_id)
user_ref.delete()
def update_server_running_state(user_id: str, server_name: str, state: bool):
server_ref = firestore_database.collection('users').document(user_id).collection('servers').document(server_name)
if server_ref.get().get('running') != state:
server_ref.update({'running': state})
def update_server_property(user_id: str, server_name: str, prop: str, value: str):
server_ref = firestore_database.collection('users').document(user_id).collection('servers').document(server_name)
prop = file_manager.kebab_to_camel_case(prop)
server_ref.update({prop: value})
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