use axum::{http::StatusCode, response::IntoResponse, routing, Json, Router}; use base64::{engine::general_purpose::STANDARD, Engine as _}; use openssl::{hash::MessageDigest, rsa::Padding, sign::Signer}; use serde_json::json; use crate::vo::{self, LicenseRequestForm}; pub struct LicenseController { routes: Router, } impl Into for LicenseController { fn into(self) -> Router { self.routes } } impl LicenseController { pub fn init() -> Self { let routes = Router::new().route("/license", routing::post(issue_license)); Self { routes } } } async fn issue_license(Json(request_form): Json) -> impl IntoResponse { let mut license = vo::License::new( request_form.licensee_name, request_form.assignee_name, request_form.assignee_email, ); for p in request_form.request_products.into_iter() { license.add_product(p, request_form.valid_days); } let serialized_license = license.serialize(); let private_key = crate::certificate::get_private_key(); let mut signer = Signer::new(MessageDigest::sha1(), private_key).unwrap(); signer.set_rsa_padding(Padding::PKCS1).unwrap(); signer.update(serialized_license.as_bytes()).unwrap(); let cert = crate::certificate::get_public_key() .public_key() .unwrap() .public_key_to_der() .unwrap(); let base64_license = STANDARD.encode(serialized_license); let base64_signature = STANDARD.encode(signer.sign_to_vec().unwrap()); let base64_cert = STANDARD.encode(cert); let license_response = format!( "{}-{}-{}-{}", license.license_id, base64_license, base64_signature, base64_cert ); (StatusCode::OK, Json(json!({"license": license_response}))) }