Automatically download certificate on Python device

This commit is contained in:
Pierre HUBERT 2024-07-03 22:19:56 +02:00
parent 9cba9c5f0a
commit 6ad50657a5
4 changed files with 50 additions and 2 deletions

View File

@ -1,3 +1,4 @@
use crate::app_config::AppConfig;
use crate::devices::device::{DeviceId, DeviceInfo}; use crate::devices::device::{DeviceId, DeviceInfo};
use crate::energy::energy_actor; use crate::energy::energy_actor;
use crate::server::custom_error::HttpResult; use crate::server::custom_error::HttpResult;
@ -73,7 +74,7 @@ pub async fn enroll(req: web::Json<EnrollRequest>, actor: WebEnergyActor) -> Htt
} }
#[derive(serde::Deserialize)] #[derive(serde::Deserialize)]
pub struct EnrollmentStatusQuery { pub struct ReqWithDevID {
id: DeviceId, id: DeviceId,
} }
@ -87,7 +88,7 @@ enum EnrollmentDeviceStatus {
/// Check device enrollment status /// Check device enrollment status
pub async fn enrollment_status( pub async fn enrollment_status(
query: web::Query<EnrollmentStatusQuery>, query: web::Query<ReqWithDevID>,
actor: WebEnergyActor, actor: WebEnergyActor,
) -> HttpResult { ) -> HttpResult {
let dev = actor let dev = actor
@ -102,3 +103,24 @@ pub async fn enrollment_status(
Ok(HttpResponse::Ok().json(status)) Ok(HttpResponse::Ok().json(status))
} }
/// Get device certificate
pub async fn get_certificate(query: web::Query<ReqWithDevID>, actor: WebEnergyActor) -> HttpResult {
let dev = actor
.send(energy_actor::GetSingleDevice(query.id.clone()))
.await?;
let dev = match dev {
Some(d) if d.validated => d,
_ => {
log::error!("Device attempted to retrieve an unavailable certificate!");
return Ok(HttpResponse::UnprocessableEntity().json("Certificate not available yet!"));
}
};
let cert = std::fs::read(AppConfig::get().device_cert_path(&dev.id))?;
Ok(HttpResponse::Ok()
.content_type("application/x-pem-file")
.body(cert))
}

View File

@ -160,6 +160,10 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
"/devices_api/mgmt/enrollment_status", "/devices_api/mgmt/enrollment_status",
web::get().to(mgmt_controller::enrollment_status), web::get().to(mgmt_controller::enrollment_status),
) )
.route(
"/devices_api/mgmt/get_certificate",
web::get().to(mgmt_controller::get_certificate),
)
}) })
.bind_openssl(&AppConfig::get().listen_address, builder)? .bind_openssl(&AppConfig::get().listen_address, builder)?
.run() .run()

View File

@ -56,3 +56,16 @@ def enroll_device(csr: str):
if res.status_code < 200 or res.status_code > 299: if res.status_code < 200 or res.status_code > 299:
print(res.text) print(res.text)
raise Exception(f"Enrollment failed with status {res.status_code}") raise Exception(f"Enrollment failed with status {res.status_code}")
def device_certificate() -> str:
"""
Retrieve device certificate
"""
res = requests.get(
f"{args.secure_origin}/devices_api/mgmt/get_certificate?id={args.dev_id}",
verify=args.root_ca_path,
)
if res.status_code < 200 or res.status_code > 299:
print(res.text)
raise Exception(f"Failed to check enrollment with status {res.status_code}")
return res.text

View File

@ -72,3 +72,12 @@ if status == "Pending":
exit(0) exit(0)
print("Device is successfully enrolled!") print("Device is successfully enrolled!")
print("Check device certificate")
if not os.path.isfile(args.dev_crt_path):
print("Retrieve certificate...")
cert = api.device_certificate()
with open(args.dev_crt_path, "w") as f:
f.write(cert)
print("Done. ready to operate.")