feat(backend): add FastAPI backend — procurement, inventory domain, Casdoor auth, PM arrival endpoints
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
"""Seed Casdoor (dev) — org `inventory`, app `inventory-app`, users.
|
||||
|
||||
Idempotent, best-effort helper for local development. Run AFTER the stack
|
||||
is up (casdoor on http://localhost:8080, admin/123):
|
||||
|
||||
python tools/seed_casdoor.py
|
||||
|
||||
It talks to Casdoor's REST API. If the Casdoor API version differs, the
|
||||
script logs the failure and keeps going (the important part for local dev
|
||||
is the app + client id/secret, which match frontend/public/casdoor-config.js).
|
||||
"""
|
||||
import os
|
||||
import urllib.request
|
||||
import json
|
||||
|
||||
BASE = os.environ.get("CASDOOR_BASE", "http://localhost:8080")
|
||||
ADMIN = os.environ.get("CASDOOR_ADMIN", "admin")
|
||||
ADMIN_PW = os.environ.get("CASDOOR_ADMIN_PW", "123")
|
||||
|
||||
ORG = "inventory"
|
||||
APP = "inventory-app"
|
||||
CLIENT_ID = "inventory-app-client"
|
||||
CLIENT_SECRET = "inventory-app-secret-2026"
|
||||
REDIRECT_URI = "http://localhost:3000/login"
|
||||
|
||||
USERS = [
|
||||
# (name, first_name, last_name, email, password, role_tag)
|
||||
("razaei", "آقای", "رضایی", "razaei@sample.ir", "123456", "admin"),
|
||||
("mousavi", "آقای", "موسوی", "mousavi@sample.ir", "123456", "pm"),
|
||||
("mohaghegh", "آقای", "محقق", "mohaghegh@sample.ir", "123456", "pm"),
|
||||
]
|
||||
|
||||
|
||||
def _req(method: str, path: str, body=None, auth: str | None = None):
|
||||
url = BASE + path
|
||||
data = json.dumps(body).encode() if body is not None else None
|
||||
req = urllib.request.Request(url, data=data, method=method)
|
||||
req.add_header("Content-Type", "application/json")
|
||||
if auth:
|
||||
import base64
|
||||
req.add_header("Authorization", "Basic " + base64.b64encode(auth.encode()).decode())
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=20) as resp:
|
||||
return resp.status, json.loads(resp.read() or b"{}")
|
||||
except Exception as exc:
|
||||
return 0, {"error": str(exc)}
|
||||
|
||||
|
||||
def _login():
|
||||
"""Casdoor login -> JWT (its /api/login is form-encoded)."""
|
||||
import urllib.parse
|
||||
data = urllib.parse.urlencode({
|
||||
"type": "login-normal", "organization": "built-in",
|
||||
"username": ADMIN, "password": ADMIN_PW,
|
||||
}).encode()
|
||||
req = urllib.request.Request(BASE + "/api/login", data=data, method="POST")
|
||||
req.add_header("Content-Type", "application/x-www-form-urlencoded")
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=20) as resp:
|
||||
body = json.loads(resp.read() or b"{}")
|
||||
return body.get("data", "") or body.get("accessToken", "")
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def main():
|
||||
token = _login()
|
||||
auth = f"{ADMIN}:{ADMIN_PW}" if not token else f"Bearer {token}".replace("Bearer ", "Bearer ") # placeholder
|
||||
auth = f"Bearer {token}" if token else None
|
||||
|
||||
# 1) organization
|
||||
status, body = _req("POST", "/api/add-organization", {
|
||||
"owner": "admin", "name": ORG, "displayName": "سازمان تدارکات",
|
||||
}, auth)
|
||||
print("add-organization:", status, body.get("msg", body.get("error", "")))
|
||||
|
||||
# 2) application (client id/secret fixed — matches casdoor-config.js)
|
||||
status, body = _req("POST", "/api/add-application", {
|
||||
"owner": "admin",
|
||||
"name": APP,
|
||||
"displayName": "سامانه تدارکات و انبار",
|
||||
"organization": ORG,
|
||||
"clientId": CLIENT_ID,
|
||||
"clientSecret": CLIENT_SECRET,
|
||||
"redirectUris": [REDIRECT_URI],
|
||||
"grantTypes": ["authorization_code"],
|
||||
"enablePassword": True,
|
||||
"enableSignUp": False,
|
||||
"tokenFormat": "JWT",
|
||||
"expireInHours": 24,
|
||||
}, auth)
|
||||
print("add-application:", status, body.get("msg", body.get("error", "")))
|
||||
|
||||
# 3) users
|
||||
for name, first, last, email, pw, _role in USERS:
|
||||
status, body = _req("POST", "/api/add-user", {
|
||||
"owner": ORG, "name": name, "displayName": f"{first} {last}",
|
||||
"firstName": first, "lastName": last, "email": email, "password": pw,
|
||||
"phone": "", "type": "normal-user",
|
||||
}, auth)
|
||||
print(f"add-user {name}:", status, body.get("msg", body.get("error", "")))
|
||||
|
||||
print("\nDone. Casdoor console: http://localhost:8080 (admin/123)")
|
||||
print("Login in the app: http://localhost:3000/login")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user