def copy_psk(token, src_device_id, src_attr, dest_device_id, dest_attr): """ Copies a pre shared key from a device attribute to another :param token: The authorization token (JWT). :param src_device_id: The source device (from). :param src_attr: The source attribute (from). :param dest_device_id: The destination device (to). :param dest_attr: The destination attribute (to). :return None. :raises HTTPRequestError: If no authorization token was provided (no tenant was informed) todo list the others exceptions """ tenant = init_tenant_context2(token, db) src_device_orm = assert_device_exists(src_device_id, db.session) if not src_device_orm: raise HTTPRequestError(404, "No such device: {}".format(src_device_id)) src_device = serialize_full_device(src_device_orm, tenant, True) found_attr = False src_attr_ref = None for template_id in src_device["templates"]: for attr in src_device["attrs"][template_id]: if attr["label"] == src_attr: if attr["value_type"] == "psk": found_attr = True src_attr_ref = attr break else: raise HTTPRequestError(400, "Attribute {} is not a 'psk' type_value".format(src_attr)) if not found_attr: raise HTTPRequestError(404, "Not found attributes {}".format(src_attr)) dest_device_orm = assert_device_exists(dest_device_id, db.session) if not dest_device_orm: raise HTTPRequestError(404, "No such device: {}".format(dest_device_id)) dest_device = serialize_full_device(dest_device_orm, tenant, True) found_attr = False dest_attr_ref = None for template_id in dest_device["templates"]: for attr in dest_device["attrs"][template_id]: if attr["label"] == dest_attr: if attr["value_type"] == "psk": found_attr = True dest_attr_ref = attr break else: raise HTTPRequestError(400, "Attribute {} is not a 'psk' type_value".format(dest_attr)) if not found_attr: raise HTTPRequestError(404, "Not found attributes {}".format(dest_attr)) # copy the pre shared key src_psk_entry = DeviceAttrsPsk.query.filter_by(device_id=src_device["id"], attr_id=src_attr_ref["id"]).first() if not src_psk_entry: raise HTTPRequestError(400, "There is not a psk generated to {}".format(src_attr)) dest_psk_entry = DeviceAttrsPsk.query.filter_by(device_id=dest_device["id"], attr_id=dest_attr_ref["id"]).first() if not dest_psk_entry: db.session.add(DeviceAttrsPsk(device_id=dest_device["id"], attr_id=dest_attr_ref["id"], psk=src_psk_entry.psk)) else: dest_psk_entry.psk = src_psk_entry.psk dest_device_orm.updated = datetime.now() db.session.commit() dest_attr_ref['static_value'] = src_attr_ref['static_value'] # send an update message on kafka kafka_handler = KafkaHandler() kafka_handler.update(dest_device, meta={"service": tenant}) return None
def gen_psk(token, device_id, key_length, target_attributes=None): """ Generates pre shared keys to a specifics device :param token: The authorization token (JWT). :param device_id: The target device. :param key_length: The key length to be generated. :param target_attributes: A list with the target attributes, None means all suitable attributes. :return The keys generated. :rtype JSON :raises HTTPRequestError: If no authorization token was provided (no tenant was informed) :raises HTTPRequestError: If this device could not be found in database. """ tenant = init_tenant_context2(token, db) device_orm = assert_device_exists(device_id, db.session) if not device_orm: raise HTTPRequestError(404, "No such device: {}".format(device_id)) device = serialize_full_device(device_orm, tenant, True) # checks if the key length has been specified # todo remove this magic number if key_length > 1024 or key_length <= 0: raise HTTPRequestError(400, "key_length must be greater than 0 and lesser than {}".format(1024)) is_all_psk_attr_valid = False target_attrs_data = [] # find the target attributes # first case: if there are specified attributes if target_attributes: for template_id in device["templates"]: for attr in device["attrs"][template_id]: if attr["value_type"] == "psk" and attr["label"] in target_attributes: target_attrs_data.append(attr) is_all_psk_attr_valid = True if not is_all_psk_attr_valid: raise HTTPRequestError(400, "Not found some attributes, " "please check them") if len(target_attributes) != len(target_attrs_data): if not is_all_psk_attr_valid: raise HTTPRequestError(400, "Some attribute is not a 'psk' type_value") else: raise HTTPRequestError(400, "Not found some attributes, " "please check them") else: # second case: if there are not specified attributes for template_id in device["templates"]: for attr in device["attrs"][template_id]: if attr["value_type"] == "psk": target_attrs_data.append(attr) is_all_psk_attr_valid = True if not is_all_psk_attr_valid: # there is no psk key, do not worry it is not a problem raise HTTPRequestError(204, "") # generate the pre shared key on selected attributes result = [] for attr in target_attrs_data: psk = secrets.token_hex(key_length) psk_hex = psk attr["static_value"] = psk_hex encrypted_psk = encrypt(psk) psk_entry = DeviceAttrsPsk.query.filter_by(device_id=device["id"], attr_id=attr["id"]).first() if not psk_entry: db.session.add(DeviceAttrsPsk(device_id=device["id"], attr_id=attr["id"], psk=encrypted_psk)) else: psk_entry.psk = encrypted_psk result.append( {'attribute': attr["label"], 'psk': psk_hex} ) device_orm.updated = datetime.now() db.session.commit() # send an update message on kafka kafka_handler = KafkaHandler() kafka_handler.update(device, meta={"service": tenant}) return result