Skip to content

Commit 81e7ada

Browse files
committed
Fix bugs,add sign-out and delete record features
1 parent 14121fe commit 81e7ada

7 files changed

Lines changed: 474 additions & 375 deletions

File tree

Pipfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ requests = "*"
1111
[dev-packages]
1212

1313
[requires]
14-
python_version = "3.11"
14+
python_version = "3.13"

Pipfile.lock

Lines changed: 256 additions & 252 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

controllers/auth.py

Lines changed: 78 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
import requests
44
from typing import Annotated
55

6-
auth = FastAPI()
76

87

9-
@auth.middleware("http")
10-
async def validate_token(request: Request, call_next, headers:Annotated[str | None, Header()] = None):
11-
print("reaching here---validateToken",headers)
12-
auth_header = request.headers.get("Authorization")
8+
async def validate_token(req: Request):
9+
print("reaching here---validateToken")
10+
auth_header = req.headers.get("Authorization")
1311

1412
if not auth_header:
1513
raise HTTPException(status_code=401, detail="Authorization header is missing")
@@ -19,54 +17,47 @@ async def validate_token(request: Request, call_next, headers:Annotated[str | No
1917
if len(auth_header_parts) != 2 or auth_header_parts[0].lower() != "basic":
2018
raise HTTPException(status_code=400, detail="Invalid Authorization header format")
2119

22-
request.basicAuthToken = auth_header_parts[1]
20+
req.basicAuthToken = auth_header_parts[1]
2321

24-
return await call_next(request)
2522

26-
@auth.middleware("http")
27-
async def validate_session(request: Request, call_next):
28-
basic_auth_token = request.basicAuthToken
29-
session = request.json().get("session", {})
23+
async def validate_session(req: Request):
24+
basic_auth_token = req.basicAuthToken
25+
body= req.state.body
26+
session = body.get("session", {})
3027
token = session.get("token")
3128
required = session.get("required", False) if session else False
32-
method_body = request.json().get("methodBody", {})
29+
method_body =body.get("methodBody", {})
3330
database = method_body.get("database")
34-
fm_server = request.json().get("fmServer")
35-
36-
should_call_next = False # Flag to track if next() should be called
31+
fm_server = body.get("fmServer")
32+
method=body.get("method")
3733

3834
if not session or not token:
3935
try:
4036
fm_session_token = await fm_login(fm_server, database, basic_auth_token)
4137

4238
if fm_session_token:
4339
is_session_valid = await fm_validate_session(fm_server, fm_session_token)
44-
4540
if is_session_valid:
46-
request.fmSessionToken = fm_session_token
47-
should_call_next = True
41+
req.state.body["fmSessionToken"] = fm_session_token
42+
4843
else:
4944
return JSONResponse(status_code=401, content={"error": "Session token validation failed"})
5045
except Exception as error:
5146
return JSONResponse(status_code=401, content={"error": str(error)})
5247
else:
5348
try:
5449
is_session_valid = await fm_validate_session(fm_server, token)
55-
5650
if is_session_valid:
57-
request.fmSessionToken = token
58-
should_call_next = True
51+
req.state.body["fmSessionToken"] = token
5952
else:
60-
if token and (not required or required is False):
53+
if token:
6154
try:
6255
fm_session_token = await fm_login(fm_server, database, basic_auth_token)
63-
6456
if fm_session_token:
65-
is_session_valid = await fm_validate_session(fm_server, fm_session_token)
66-
57+
is_session_valid = await fm_validate_session(fm_server, fm_session_token)
6758
if is_session_valid:
68-
request.fmSessionToken = fm_session_token
69-
should_call_next = True
59+
req.state.body["fmSessionToken"] = fm_session_token
60+
7061
else:
7162
return JSONResponse(status_code=401, content={"error": "Re-validation of session token failed"})
7263
else:
@@ -78,11 +69,31 @@ async def validate_session(request: Request, call_next):
7869
except Exception as error:
7970
return JSONResponse(status_code=401, content={"error": "Session validation failed"})
8071

81-
if should_call_next:
82-
await call_next(request)
8372

8473

74+
async def signin(req: Request):
75+
try:
76+
await validate_token(req)
77+
basic_auth_token = req.basicAuthToken
78+
body =req.state.body
79+
fm_server = body.get("fmServer")
80+
method_body = body.get("methodBody", {})
81+
database = method_body.get("database")
82+
83+
if not fm_server or not database:
84+
raise HTTPException(status_code=400, detail="Missing fmServer or database in request body")
85+
86+
session_token = await fm_login(fm_server, database, basic_auth_token)
8587

88+
return {
89+
"message": "Signin Successful",
90+
"database": database,
91+
"session": session_token
92+
}
93+
except HTTPException as e:
94+
raise e
95+
except Exception as e:
96+
raise HTTPException(status_code=500, detail=f"Signin failed: {str(e)}")
8697

8798
async def fm_login(fm_server, database, basic_auth_token):
8899
print("reaching here---fmlogin")
@@ -95,7 +106,6 @@ async def fm_login(fm_server, database, basic_auth_token):
95106

96107
try:
97108
login_response = requests.post(url, headers=headers, json={}, verify=False)
98-
print(login_response)
99109
login_response.raise_for_status()
100110
return login_response.json()["response"]["token"]
101111
except requests.HTTPError as error:
@@ -111,7 +121,7 @@ async def fm_login(fm_server, database, basic_auth_token):
111121
async def fm_validate_session(fm_server, session_token):
112122
print("reaching here---fmValidateSession")
113123
url = f"https://{fm_server}/fmi/data/vLatest/validateSession"
114-
124+
115125
headers = {
116126
"Authorization": f"Bearer {session_token}"
117127
}
@@ -120,7 +130,43 @@ async def fm_validate_session(fm_server, session_token):
120130
validate_response = requests.get(url, headers=headers, verify=False)
121131
validate_response.raise_for_status()
122132
return validate_response.json()["messages"][0]["message"] == "OK"
123-
except requests.HTTPError:
133+
except requests.HTTPError as error:
124134
return False # Return false if there was an error
125135

126136

137+
138+
async def signout(req: Request):
139+
try:
140+
body = req.state.body
141+
method_body = body.get("methodBody", {})
142+
database = method_body.get("database")
143+
fm_server = body.get("fmServer")
144+
token = body.get("fmSessionToken")
145+
146+
if not (fm_server and database):
147+
raise HTTPException(status_code=400, detail="Missing fmServer, database.")
148+
149+
url = f"https://{fm_server}/fmi/data/vLatest/databases/{database}/sessions/{token}"
150+
headers = {
151+
"Authorization": f"Bearer {token}"
152+
}
153+
154+
155+
156+
response = requests.delete(url, headers=headers, verify=False)
157+
if response.status_code == 200 and response.json().get("messages", [{}])[0].get("message") == "OK":
158+
return {"message": "Signout success"}
159+
else:
160+
return JSONResponse(status_code=401, content={"error": "Signout failed"})
161+
162+
except requests.RequestException as error:
163+
response_json = {
164+
"error": "An error occurred while signing out.",
165+
}
166+
if error.response and error.response.status_code:
167+
response_json["statusText"] = error.response.status_code
168+
try:
169+
response_json["error"] = error.response.json()
170+
except Exception:
171+
response_json["error"] = str(error)
172+
return JSONResponse(status_code=500, content=response_json)

controllers/index.py

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,36 @@
11
from fastapi import FastAPI, Request, Response
2-
from .auth import validate_session, validate_token
2+
from .auth import validate_session, validate_token,signin,signout
33
from .records import (
44
create_record,
55
get_all_records,
66
find_record,
77
update_record,
8+
delete_record
89
)
910

10-
controllers_to_skip_validation = []
11+
controllers_to_skip_validation = ["signin"]
12+
METHOD_HANDLERS = {
13+
"createRecord": create_record,
14+
"getAllRecords": get_all_records,
15+
"findRecord": find_record,
16+
"updateRecord": update_record,
17+
"deleteRecord": delete_record,
18+
"signin": signin,
19+
"signout" : signout
20+
21+
}
1122

1223

1324
async def data_api(req: Request, res: Response):
14-
method = req.get("method")
15-
16-
print("In this function", res.headers)
17-
18-
# Check if the method should skip validation
25+
method = req.state.body.get("method")
26+
if method not in METHOD_HANDLERS:
27+
return {"error": f"Invalid method ${method}"}
1928
if method not in controllers_to_skip_validation:
20-
# If the method is not in the skip list, apply the validateToken middleware first
21-
await validate_token(req, res)
22-
29+
# If the method is not in the skip list, apply the validateToken first
30+
await validate_token(req)
2331
# After token validation, apply the validateSession middleware
24-
await validate_session(req, res)
32+
await validate_session(req)
33+
34+
handler = METHOD_HANDLERS[method]
35+
return await handler(req)
2536

26-
# Once validated, call the appropriate controller method
27-
if method == "createRecord":
28-
return await create_record(req)
29-
# elif method == "getRecordById":
30-
# return await get_record_by_id(req)
31-
elif method == "getAllRecords":
32-
return await get_all_records(req)
33-
elif method == "findRecord":
34-
return await find_record(req)
35-
# elif method == "executeScript":
36-
# return await execute_script(req)
37-
elif method == "updateRecord":
38-
return await update_record(req)
39-
# elif method == "test":
40-
# return await test(req)
41-
# elif method == "syncCollection":
42-
# return await sync_collection(req)
43-
else:
44-
return {"error": "Invalid method"}

0 commit comments

Comments
 (0)