billing frontend for mariadb. setup as otb_billing for outsidethebox.top accounting. also involved with outsidethedb
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

57 lines
2.1 KiB

import os
import json
import time
import uuid
import hmac
import base64
import hashlib
from urllib.parse import quote
from flask import Blueprint, session, redirect, url_for, flash
portal_service_launch_bp = Blueprint("portal_service_launch", __name__)
def _b64url_encode(data: bytes) -> str:
return base64.urlsafe_b64encode(data).rstrip(b"=").decode("utf-8")
def _sign_payload(payload: dict, secret: str) -> str:
payload_json = json.dumps(payload, separators=(",", ":"), sort_keys=True).encode("utf-8")
payload_b64 = _b64url_encode(payload_json)
sig = hmac.new(secret.encode("utf-8"), payload_b64.encode("utf-8"), hashlib.sha256).digest()
sig_b64 = _b64url_encode(sig)
return f"{payload_b64}.{sig_b64}"
@portal_service_launch_bp.route("/portal/services/follow-me-launch")
def portal_follow_me_launch():
portal_client_id = session.get("portal_client_id")
portal_email = session.get("portal_email")
if not portal_client_id or not portal_email:
flash("Please sign in to launch Follow-me.", "warning")
return redirect(url_for("portal_login"))
secret = os.getenv("FMV2_HANDOFF_SECRET", "").strip()
base_url = os.getenv("FMV2_BASE_URL", "https://follow-me.outsidethebox.top").strip().rstrip("/")
ttl_seconds = int(os.getenv("FMV2_HANDOFF_TTL_SECONDS", "300"))
if not secret:
flash("Follow-me launch is not configured. Missing FMV2_HANDOFF_SECRET.", "danger")
return redirect(url_for("portal_services.portal_services_home"))
now = int(time.time())
payload = {
"iss": "otb-billing",
"aud": "fmv2",
"jti": str(uuid.uuid4()),
"iat": now,
"exp": now + ttl_seconds,
"portal_client_id": int(portal_client_id),
"portal_email": portal_email,
"portal_contact_name": session.get("portal_contact_name", ""),
"portal_company_name": session.get("portal_company_name", ""),
"return_to": "/dashboard",
}
token = _sign_payload(payload, secret)
target = f"{base_url}/auth/portal-handoff?token={quote(token)}"
return redirect(target)