Skip to content

Commit 7f29ce5

Browse files
authored
Merge pull request #3 from crane-cloud/db-existing-endpoints
Db existing endpoints
2 parents 4d53eff + 12ab46c commit 7f29ce5

File tree

6 files changed

+186
-28
lines changed

6 files changed

+186
-28
lines changed

app/core/database.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
from sqlalchemy import create_engine
2-
import os
3-
from fastapi import Depends, HTTPException
4-
from sqlalchemy.orm import sessionmaker, Session
5-
from typing import List, Annotated
6-
from sqlalchemy.ext.declarative import declarative_base
2+
from sqlalchemy.orm import sessionmaker
73
from sqlalchemy_utils import create_database, database_exists
8-
from app.models import Base, Database
4+
from app.models import Base
5+
import os
96
import settings
107

8+
119
DATABASE_URL = os.getenv('DATABASE_URI')
1210

1311
if not database_exists(DATABASE_URL):
1412
create_database(DATABASE_URL)
1513

14+
1615
engine = create_engine(DATABASE_URL, pool_pre_ping=True)
1716

1817
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

app/core/database_flavor.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
from types import SimpleNamespace
33
from app.core.database_service import MysqlDbService, PostgresqlDbService
4+
import settings
45

56
db_flavors = {
67
'postgres': {

app/models.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,5 @@ class Database(Base):
2525
deleted = Column(Boolean, default=False)
2626
disabled = Column(Boolean, default=False)
2727
admin_disabled = Column(Boolean, default=False)
28-
# TODO: make database_flavour_name nullable=false
29-
# TODO: Implement the soft delete
30-
31-
# def password_is_valid(self, password):
32-
# """ checks the password against it's hash to validate the user's password """
33-
# return bcrypt.checkpw(password, self.password)
34-
35-
# Base.metadata.create_all(engine)
28+
default_storage = Column(Integer, nullable=True)
29+
allocated_size = Column(Integer, nullable=True)

app/routes/admin.py

+83-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from fastapi import APIRouter, Depends, HTTPException
22
from sqlalchemy.orm import Session
3-
from app.schema import (DatabaseSchema)
3+
from app.schema import (DatabaseSchema, PasswordUpdate)
44
from app.models import Database
55
from app.core.config import get_db
66
from typing import List
@@ -10,17 +10,17 @@
1010
router = APIRouter()
1111

1212
@router.get("/admin/databases/")
13-
def get_all_databases(db: Session = Depends(get_db)):
13+
def admin_get_all_databases(db: Session = Depends(get_db)):
1414
databases = db.query(Database).all()
1515
return databases
1616

1717
@router.get("/admin/mysql_databases/")
18-
def get_all_mysql_databases(db: Session = Depends(get_db)):
18+
def admin_get_all_mysql_databases(db: Session = Depends(get_db)):
1919
mysql_databases = db.query(Database).filter(Database.database_flavour_name == "mysql").all()
2020
return mysql_databases
2121

2222
@router.get("/admin/postgresql_databases/")
23-
def get_all_postgresql_databases(db: Session = Depends(get_db)):
23+
def admin_get_all_postgresql_databases(db: Session = Depends(get_db)):
2424
postgresql_databases = db.query(Database).filter(Database.database_flavour_name == "postgres").all()
2525
return postgresql_databases
2626

@@ -38,6 +38,40 @@ def get_single_databases(database_id:str, db: Session = Depends(get_db)):
3838
raise HTTPException(status_code=404, detail="Databases not found")
3939
return user_databases
4040

41+
@router.get("/admin/databases/{database_id}/password")
42+
def admin_get_database_password(database_id:str, db: Session = Depends(get_db)):
43+
db_exists = db.query(Database).filter(Database.id == database_id).first()
44+
if not db_exists:
45+
raise HTTPException(status_code=404, detail="Database not found")
46+
return db_exists.password
47+
48+
@router.post("/admin/databases/{database_id}/enable")
49+
def admin_enable_user_database(database_id:str, db: Session = Depends(get_db)):
50+
database = db.query(Database).filter(Database.id == database_id).first()
51+
if database is None:
52+
raise HTTPException(status_code=404, detail="Databases not found")
53+
54+
if (database.admin_disabled == False):
55+
raise HTTPException(status_code=404, detail="Databases is already enabled.")
56+
57+
database.admin_disabled = False
58+
db.commit()
59+
return {"message": "Database enabled successfully"}
60+
61+
62+
@router.post("/admin/databases/{database_id}/disable")
63+
def admin_disable_user_database(database_id:str, db: Session = Depends(get_db)):
64+
database = db.query(Database).filter(Database.id == database_id).first()
65+
if database is None:
66+
raise HTTPException(status_code=404, detail="Databases not found")
67+
68+
if database.admin_disabled:
69+
raise HTTPException(status_code=404, detail="Databases is already disabled.")
70+
71+
database.admin_disabled = True
72+
db.commit()
73+
return {"message": "Database disabled successfully"}
74+
4175
@router.delete("/admin/databases/{database_id}")
4276
def delete_user_database(database_id:str, db: Session = Depends(get_db)):
4377
database = db.query(Database).filter(Database.id == database_id).first()
@@ -47,7 +81,7 @@ def delete_user_database(database_id:str, db: Session = Depends(get_db)):
4781
db.commit()
4882
return {"message": "Database deleted successfully"}
4983

50-
@router.post("/admin/databases/reset/{database_id}")
84+
@router.post("/admin/databases/{database_id}/reset")
5185
def reset_user_database(database_id:str, db: Session = Depends(get_db)):
5286
database = db.query(Database).filter(Database.id == database_id).first()
5387
if database is None:
@@ -83,4 +117,47 @@ def reset_user_database(database_id:str, db: Session = Depends(get_db)):
83117
message=f"Unable to reset database"
84118
), 500
85119

86-
return ({"status":'success', "message":"Database Reset Successfully"}), 200
120+
return ({"status":'success', "message":"Database Reset Successfully"}), 200
121+
122+
@router.post("/admin/databases/{database_id}/reset_password")
123+
def admin_password_reset_database(database_id:str, field_update:PasswordUpdate, db: Session = Depends(get_db)):
124+
database = db.query(Database).filter(Database.id == database_id).first()
125+
if not database:
126+
raise HTTPException(status_code=404, detail="Databases not found")
127+
128+
db_flavour = get_db_flavour(database.database_flavour_name)
129+
130+
if not db_flavour:
131+
return dict(
132+
status="fail",
133+
message=f"Database with flavour name {database.database_flavour_name} is not mysql or postgres."
134+
), 409
135+
136+
database_service = db_flavour['class']
137+
138+
database_connection = database_service.check_db_connection()
139+
140+
if not database_connection:
141+
142+
return dict(
143+
status="fail",
144+
message=f"Failed to connect to the database service"
145+
), 500
146+
147+
password_reset_database = database_service.reset_password(
148+
149+
user=database.user,
150+
password= field_update.password
151+
)
152+
153+
if not password_reset_database:
154+
return dict(
155+
status="fail",
156+
message=f"Unable to reset database password"
157+
), 500
158+
159+
database.password = field_update.password
160+
161+
db.commit()
162+
163+
return ({"status":'success', "message":"Database Password Reset Successfully"}), 200

app/routes/userdb.py

+90-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from fastapi import APIRouter, Depends, HTTPException
22
from sqlalchemy.orm import Session
3-
from app.schema import (DatabaseSchema, DatabaseFlavor)
3+
from app.schema import (DatabaseSchema, DatabaseFlavor, PasswordUpdate)
44
import os
55
import json
66
from app.core.config import get_db
@@ -81,10 +81,10 @@ async def create_database(database: DatabaseFlavor, db: Session = Depends(get_db
8181
data=database
8282
), 201
8383

84-
@router.get("/admin/postgresql_databases/")
85-
def get_all_postgresql_databases(db: Session = Depends(get_db)):
86-
postgresql_databases = db.query(Database).filter(Database.database_flavour_name == "postgres").all()
87-
return postgresql_databases
84+
# @router.get("/admin/postgresql_databases/")
85+
# def get_all_postgresql_databases(db: Session = Depends(get_db)):
86+
# postgresql_databases = db.query(Database).filter(Database.database_flavour_name == "postgres").all()
87+
# return postgresql_databases
8888

8989
@router.get("/user/databases")
9090
def get_user_databases(user_id:str, db: Session = Depends(get_db)):
@@ -114,16 +114,56 @@ def get_one_databases(database_id:str, db: Session = Depends(get_db)):
114114
raise HTTPException(status_code=404, detail="Databases not found")
115115
return user_databases
116116

117+
@router.get("/user/databases/{database_id}/password")
118+
def get_database_password(database_id:str, db: Session = Depends(get_db)):
119+
db_exists = db.query(Database).filter(Database.id == database_id).first()
120+
if not db_exists:
121+
raise HTTPException(status_code=404, detail="Database not found")
122+
return db_exists.password
123+
117124
@router.delete("/user/databases/{database_id}")
118-
def admin_delete_user_database(database_id:str, db: Session = Depends(get_db)):
125+
def delete_user_database(database_id:str, db: Session = Depends(get_db)):
119126
database = db.query(Database).filter(Database.id == database_id).first()
120127
if database is None:
121128
raise HTTPException(status_code=404, detail="Databases not found")
122129
database.deleted = True
123130
db.commit()
124131
return {"message": "Database deleted successfully"}
125132

126-
@router.post("/user/databases/reset/{database_id}")
133+
@router.post("/user/databases/{database_id}/enable")
134+
def enable_user_database(database_id:str, db: Session = Depends(get_db)):
135+
database = db.query(Database).filter(Database.id == database_id).first()
136+
if database is None:
137+
raise HTTPException(status_code=404, detail="Databases not found")
138+
139+
if (database.disabled == False):
140+
raise HTTPException(status_code=404, detail="Databases is already enabled.")
141+
142+
if database.admin_disabled:
143+
return {'You are not authorised to enable Database with id {database_id}, please contact an admin'}, 403
144+
145+
database.disabled = False
146+
db.commit()
147+
return {"message": "Database enabled successfully"}
148+
149+
150+
@router.post("/user/databases/{database_id}/disable")
151+
def disable_user_database(database_id:str, db: Session = Depends(get_db)):
152+
database = db.query(Database).filter(Database.id == database_id).first()
153+
if database is None:
154+
raise HTTPException(status_code=404, detail="Databases not found")
155+
156+
if database.disabled:
157+
raise HTTPException(status_code=404, detail="Databases is already disabled.")
158+
159+
if database.admin_disabled:
160+
return {'Database with id {database_id} is disabled, please contact an admin'}, 403
161+
162+
database.disabled = True
163+
db.commit()
164+
return {"message": "Database disabled successfully"}
165+
166+
@router.post("/user/databases/{database_id}/reset/")
127167
def reset_database(database_id:str, db: Session = Depends(get_db)):
128168
database = db.query(Database).filter(Database.id == database_id).first()
129169
if database is None:
@@ -162,6 +202,49 @@ def reset_database(database_id:str, db: Session = Depends(get_db)):
162202

163203
return ({"status":'success', "message":"Database Reset Successfully"}), 200
164204

205+
@router.post("/user/databases/{database_id}/reset_password")
206+
def password_reset_database(database_id:str, field_update:PasswordUpdate, db: Session = Depends(get_db)):
207+
database = db.query(Database).filter(Database.id == database_id).first()
208+
if not database:
209+
raise HTTPException(status_code=404, detail="Databases not found")
210+
211+
db_flavour = get_db_flavour(database.database_flavour_name)
212+
213+
if not db_flavour:
214+
return dict(
215+
status="fail",
216+
message=f"Database with flavour name {database.database_flavour_name} is not mysql or postgres."
217+
), 409
218+
219+
database_service = db_flavour['class']
220+
221+
database_connection = database_service.check_db_connection()
222+
223+
if not database_connection:
224+
225+
return dict(
226+
status="fail",
227+
message=f"Failed to connect to the database service"
228+
), 500
229+
230+
password_reset_database = database_service.reset_password(
231+
232+
user=database.user,
233+
password= field_update.password
234+
)
235+
236+
if not password_reset_database:
237+
return dict(
238+
status="fail",
239+
message=f"Unable to reset database password"
240+
), 500
241+
242+
database.password = field_update.password
243+
244+
db.commit()
245+
246+
return ({"status":'success', "message":"Database Password Reset Successfully"}), 200
247+
165248
@router.post("/user/databases")
166249
async def create_database(database: DatabaseFlavor, db: Session = Depends(get_db)):
167250

app/schema.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ class DatabaseSchema(BaseModel):
1919

2020
class DatabaseFlavor(BaseModel):
2121

22-
database_flavour_name: Optional[str]
22+
database_flavour_name: Optional[str]
23+
24+
class PasswordUpdate(BaseModel):
25+
26+
password: str

0 commit comments

Comments
 (0)