Can get a single device enrollment status
This commit is contained in:
		| @@ -101,6 +101,11 @@ impl DevicesList { | ||||
|         self.0.clone().into_values().collect() | ||||
|     } | ||||
|  | ||||
|     /// Get the information about a single device | ||||
|     pub fn get_single(&self, id: &DeviceId) -> Option<Device> { | ||||
|         self.0.get(id).cloned() | ||||
|     } | ||||
|  | ||||
|     /// Validate a device | ||||
|     pub fn validate(&mut self, id: &DeviceId) -> anyhow::Result<()> { | ||||
|         let dev = self | ||||
|   | ||||
| @@ -137,3 +137,16 @@ impl Handler<GetDeviceLists> for EnergyActor { | ||||
|         self.devices.full_list() | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Get the information about a single device | ||||
| #[derive(Message)] | ||||
| #[rtype(result = "Option<Device>")] | ||||
| pub struct GetSingleDevice(pub DeviceId); | ||||
|  | ||||
| impl Handler<GetSingleDevice> for EnergyActor { | ||||
|     type Result = Option<Device>; | ||||
|  | ||||
|     fn handle(&mut self, msg: GetSingleDevice, _ctx: &mut Context<Self>) -> Self::Result { | ||||
|         self.devices.get_single(&msg.0) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -71,3 +71,34 @@ pub async fn enroll(req: web::Json<EnrollRequest>, actor: WebEnergyActor) -> Htt | ||||
|  | ||||
|     Ok(HttpResponse::Accepted().json("Device successfully enrolled")) | ||||
| } | ||||
|  | ||||
| #[derive(serde::Deserialize)] | ||||
| pub struct EnrollmentStatusQuery { | ||||
|     id: DeviceId, | ||||
| } | ||||
|  | ||||
| #[derive(serde::Serialize)] | ||||
| #[serde(tag = "status")] | ||||
| enum EnrollmentDeviceStatus { | ||||
|     Unknown, | ||||
|     Pending, | ||||
|     Validated, | ||||
| } | ||||
|  | ||||
| /// Check device enrollment status | ||||
| pub async fn enrollment_status( | ||||
|     query: web::Query<EnrollmentStatusQuery>, | ||||
|     actor: WebEnergyActor, | ||||
| ) -> HttpResult { | ||||
|     let dev = actor | ||||
|         .send(energy_actor::GetSingleDevice(query.id.clone())) | ||||
|         .await?; | ||||
|  | ||||
|     let status = match dev { | ||||
|         None => EnrollmentDeviceStatus::Unknown, | ||||
|         Some(d) if d.validated => EnrollmentDeviceStatus::Validated, | ||||
|         _ => EnrollmentDeviceStatus::Pending, | ||||
|     }; | ||||
|  | ||||
|     Ok(HttpResponse::Ok().json(status)) | ||||
| } | ||||
|   | ||||
| @@ -156,7 +156,10 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()> | ||||
|                 "/devices_api/mgmt/enroll", | ||||
|                 web::post().to(mgmt_controller::enroll), | ||||
|             ) | ||||
|         // TODO : check device status | ||||
|             .route( | ||||
|                 "/devices_api/mgmt/enrollment_status", | ||||
|                 web::get().to(mgmt_controller::enrollment_status), | ||||
|             ) | ||||
|     }) | ||||
|     .bind_openssl(&AppConfig::get().listen_address, builder)? | ||||
|     .run() | ||||
|   | ||||
| @@ -17,6 +17,20 @@ def get_root_ca() -> str: | ||||
|     return res.text | ||||
|  | ||||
|  | ||||
| def device_enrollment_status() -> str: | ||||
|     """ | ||||
|     Get current device enrollment status | ||||
|     """ | ||||
|     res = requests.get( | ||||
|         f"{args.secure_origin}/devices_api/mgmt/enrollment_status?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.json()["status"] | ||||
|  | ||||
|  | ||||
| def device_info(): | ||||
|     """ | ||||
|     Get device information to return with enrollment and sync requests | ||||
|   | ||||
| @@ -19,8 +19,8 @@ args = parser.parse_args() | ||||
|  | ||||
| args.secure_origin_path = os.path.join(args.storage, "SECURE_ORIGIN") | ||||
| args.root_ca_path = os.path.join(args.storage, "root_ca.crt") | ||||
| args.dev_id_path = os.path.join(args.storage, "DEV_ID") | ||||
| args.dev_priv_key_path = os.path.join(args.storage, "dev.key") | ||||
| args.dev_csr_path = os.path.join(args.storage, "dev.csr") | ||||
| args.dev_enroll_marker = os.path.join(args.storage, "ENROLL_SUBMITTED") | ||||
| args.dev_crt_path = os.path.join(args.storage, "dev.crt") | ||||
| args.relay_gpios_list = list(map(lambda x: int(x), args.relay_gpios.split(","))) | ||||
|   | ||||
| @@ -27,6 +27,15 @@ if not os.path.isfile(args.root_ca_path): | ||||
|     with open(args.root_ca_path, "w") as f: | ||||
|         f.write(origin) | ||||
|  | ||||
| print("Check device ID") | ||||
| if not os.path.isfile(args.dev_id_path): | ||||
|     print("Generate device id...") | ||||
|     with open(args.dev_id_path, "w") as f: | ||||
|         f.write(f"PyDev {utils.rand_str(10)}") | ||||
|  | ||||
| with open(args.dev_id_path, "r") as f: | ||||
|     args.dev_id = f.read() | ||||
|  | ||||
| print("Check private key") | ||||
| if not os.path.isfile(args.dev_priv_key_path): | ||||
|     print("Generate private key...") | ||||
| @@ -39,19 +48,27 @@ if not os.path.isfile(args.dev_csr_path): | ||||
|     print("Generate CSR...") | ||||
|     with open(args.dev_priv_key_path, "r") as f: | ||||
|         priv_key = "".join(f.readlines()) | ||||
|     csr = pki.gen_csr(priv_key=priv_key, cn=f"PyDev {utils.rand_str(10)}") | ||||
|     csr = pki.gen_csr(priv_key=priv_key, cn=args.dev_id) | ||||
|     with open(args.dev_csr_path, "w") as f: | ||||
|         f.write(csr) | ||||
|  | ||||
| print("Check device enrollment...") | ||||
| if not os.path.isfile(args.dev_enroll_marker): | ||||
| status = api.device_enrollment_status() | ||||
|  | ||||
| if status == "Unknown": | ||||
|     print("Device is unknown on the system, need to submit a CSR...") | ||||
|     with open(args.dev_csr_path, "r") as f: | ||||
|         csr = "".join(f.read()) | ||||
|  | ||||
|     print("Enrolling device...") | ||||
|     crt = api.enroll_device(csr) | ||||
|     print("Done. Please accept the device on central system web UI") | ||||
|     exit(0) | ||||
|  | ||||
|     with open(args.dev_enroll_marker, "w") as f: | ||||
|         f.write("submitted") | ||||
| if status == "Pending": | ||||
|     print( | ||||
|         "Device is enrolled, but not validated yet. Please accept the device on central system web UI" | ||||
|     ) | ||||
|     exit(0) | ||||
|  | ||||
| # TODO : "intelligent" enrollment management (re-enroll if cancelled) | ||||
| print("Device is successfully enrolled!") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user