118 lines
4.0 KiB
Python
118 lines
4.0 KiB
Python
|
|
from bottle import Bottle, request, response, static_file
|
||
|
|
import json
|
||
|
|
import os
|
||
|
|
import db
|
||
|
|
|
||
|
|
app = Bottle()
|
||
|
|
db.init_db()
|
||
|
|
|
||
|
|
# ── auth config ──────────────────────────────────────────
|
||
|
|
# Token simpel, mudah diingat. Ganti sesuai kebutuhan.
|
||
|
|
API_TOKEN = "secret123"
|
||
|
|
|
||
|
|
|
||
|
|
# ── helpers ──────────────────────────────────────────────
|
||
|
|
def json_response(data, status=200):
|
||
|
|
response.content_type = "application/json"
|
||
|
|
response.status = status
|
||
|
|
return json.dumps(data)
|
||
|
|
|
||
|
|
|
||
|
|
def check_auth():
|
||
|
|
"""
|
||
|
|
Cek Bearer token.
|
||
|
|
Return None jika OK, atau string JSON error jika gagal.
|
||
|
|
"""
|
||
|
|
auth = request.get_header("Authorization", "")
|
||
|
|
if not auth.startswith("Bearer "):
|
||
|
|
return json.dumps({"error": "missing or invalid Authorization header"})
|
||
|
|
token = auth.split(" ", 1)[1].strip()
|
||
|
|
if token != API_TOKEN:
|
||
|
|
return json.dumps({"error": "invalid token"})
|
||
|
|
return None # ✅ token valid
|
||
|
|
|
||
|
|
|
||
|
|
# ── static playground page (tanpa auth) ──────────────────
|
||
|
|
@app.get("/")
|
||
|
|
def index():
|
||
|
|
return static_file("playground.html", root=os.path.join(os.path.dirname(__file__), "templates"))
|
||
|
|
|
||
|
|
|
||
|
|
# ── API: /api/enroll (butuh auth) ────────────────────────
|
||
|
|
@app.get("/api/enroll")
|
||
|
|
def api_enroll():
|
||
|
|
"""
|
||
|
|
GET /api/enroll → list all
|
||
|
|
GET /api/enroll?id=3 → detail id=3
|
||
|
|
"""
|
||
|
|
err = check_auth()
|
||
|
|
if err:
|
||
|
|
return json_response(json.loads(err), 401)
|
||
|
|
|
||
|
|
enroll_id = request.query.id
|
||
|
|
if enroll_id:
|
||
|
|
row = db.get_enroll(int(enroll_id))
|
||
|
|
if not row:
|
||
|
|
return json_response({"error": "not found"}, 404)
|
||
|
|
return json_response({"data": row})
|
||
|
|
rows = db.list_enrolls()
|
||
|
|
return json_response({"data": rows})
|
||
|
|
|
||
|
|
|
||
|
|
@app.post("/api/enroll")
|
||
|
|
def api_enroll_post():
|
||
|
|
"""
|
||
|
|
POST /api/enroll (form fields + Bearer token)
|
||
|
|
id → if present → edit, otherwise → add
|
||
|
|
type
|
||
|
|
service
|
||
|
|
user
|
||
|
|
action → "remove" to delete (needs id)
|
||
|
|
"""
|
||
|
|
err = check_auth()
|
||
|
|
if err:
|
||
|
|
return json_response(json.loads(err), 401)
|
||
|
|
|
||
|
|
action = request.forms.get("action", "").strip()
|
||
|
|
enroll_id = request.forms.get("id", "").strip()
|
||
|
|
type_ = request.forms.get("type", "").strip()
|
||
|
|
service = request.forms.get("service", "").strip()
|
||
|
|
user = request.forms.get("user", "").strip()
|
||
|
|
|
||
|
|
# ── remove ──
|
||
|
|
if action == "remove":
|
||
|
|
if not enroll_id:
|
||
|
|
return json_response({"error": "id is required for remove"}, 400)
|
||
|
|
db.remove_enroll(int(enroll_id))
|
||
|
|
return json_response({"message": "removed", "id": int(enroll_id)})
|
||
|
|
|
||
|
|
# ── validate type ──
|
||
|
|
if type_ not in db.VALID_TYPES:
|
||
|
|
return json_response(
|
||
|
|
{"error": f"type must be one of: {', '.join(db.VALID_TYPES)}"}, 400
|
||
|
|
)
|
||
|
|
|
||
|
|
# ── validate service ──
|
||
|
|
if service not in db.VALID_SERVICES:
|
||
|
|
return json_response(
|
||
|
|
{"error": f"service must be one of: {', '.join(db.VALID_SERVICES)}"}, 400
|
||
|
|
)
|
||
|
|
|
||
|
|
# ── edit ──
|
||
|
|
if enroll_id:
|
||
|
|
if not type_ or not service or not user:
|
||
|
|
return json_response({"error": "type, service, user are required"}, 400)
|
||
|
|
db.edit_enroll(int(enroll_id), type_, service, user)
|
||
|
|
return json_response({"message": "updated", "id": int(enroll_id)})
|
||
|
|
|
||
|
|
# ── add ──
|
||
|
|
if not type_ or not service or not user:
|
||
|
|
return json_response({"error": "type, service, user are required"}, 400)
|
||
|
|
new_id = db.add_enroll(type_, service, user)
|
||
|
|
return json_response({"message": "created", "id": new_id}, 201)
|
||
|
|
|
||
|
|
|
||
|
|
# ── run ──────────────────────────────────────────────────
|
||
|
|
if __name__ == "__main__":
|
||
|
|
app.run(host="0.0.0.0", port=8080, debug=True, reloader=True)
|