def trigger_action(): device_name_bi = request.args.get("device_name_bi", None) name_bi = request.args.get("name_bi", None) additional_data = request.args.get("additional_data", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (device_name_bi, DEVICE_NAME_BI_MISSING_ERROR_MSG), (additional_data, ADDITIONAL_DATA_MISSING_ERROR_MSG), (name_bi, ACTION_NAME_BI_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check dv = Device.get_by_name_bi(device_name_bi) if dv is None or not User.can_use_device(user, dv.id): return http_json_response(False, 400, **{"error": UNAUTHORIZED_USER_ERROR_MSG}) topic = format_topic(user.mqtt_creds.username, dv.mqtt_creds.username) ac = Device.get_action_by_bi(dv.id, name_bi) if ac is None: return http_json_response(False, 400, **{"error": ACTION_BI_INVALID_ERROR_MSG}) payload = create_payload(user.mqtt_creds.username, { "action": ac.name.decode("utf-8"), "additional_data": additional_data }) client.publish(topic, payload) return http_json_response()
def keygen(): data_owner = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None)) attr_list = request.form.get("attr_list", None) api_username = request.form.get("api_username", None) device_id = request.form.get("device_id", None) arg_check = check_missing_request_argument( (attr_list, ATTR_LIST_MISSING_ERROR_MSG), (api_username, API_USERNAME_MISSING_ERROR_MSG), (device_id, DEVICE_ID_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check receiver = AttrAuthUser.get_by_user_name(api_username) if receiver is None: return http_json_response(False, 400, **{"error": INCORRECT_API_USERNAME_ERROR_MSG}) attr_list = parse_attr_list(attr_list) if not attr_list: return http_json_response(False, 400, **{"error": INVALID_ATTR_LIST_ERROR_MSG}) serialized_private_key = create_private_key(data_owner.master_keypair.data_master, data_owner.master_keypair.data_public, attr_list) # delegate to receiver of generated key old_key = next((k for k in receiver.private_keys if k.challenger == data_owner and k.device_id == int(device_id)), None) if old_key: db.session.delete(old_key) receiver.private_keys.append(PrivateKey(data=serialized_private_key, challenger=data_owner, device_id=device_id, attributes=create_attributes(attr_list))) db.session.commit() return http_json_response()
def set_device_action(): device_id = request.form.get("device_id", None) correctness_hash = request.form.get("correctness_hash", None) name = request.form.get("name", None) name_bi = request.form.get("name_bi", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (device_id, DEVICE_ID_MISSING_ERROR_MSG), (correctness_hash, CORRECTNESS_HASH_MISSING_ERROR_MSG), (name, ACTION_NAME_MISSING_ERROR_MSG), (name_bi, ACTION_NAME_BI_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check if not user.is_registered_with_broker: return http_json_response( False, 400, **{"error": NOT_REGISTERED_WITH_BROKER_ERROR_MSG}) if not User.can_use_device(user, device_id): return http_json_response(False, 400, **{"error": UNAUTHORIZED_USER_ERROR_MSG}) dv = Device.get_by_id(device_id) with db.session.no_autoflush: dv.add_action(name.encode(), name_bi, correctness_hash) db.session.add(dv) db.session.commit() return http_json_response()
def retrieve_public_key(): device_id = request.form.get("device_id", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (device_id, DEVICE_ID_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check if not User.can_use_device(user, device_id): return http_json_response(False, 400, **{"error": UNAUTHORIZED_USER_ERROR_MSG}) user_device = db.session.query(UserDevice) \ .filter(and_(UserDevice.device_id == device_id, UserDevice.user_id == user.id)).first() public_key = user_device.device_public_session_key if public_key: user_device.device_public_session_key = None user_device.added = None db.session.add(user_device) db.session.commit() return http_json_response(**{'device_public_key': public_key}) return http_json_response(False, 400, **{"error": NO_PUBLIC_KEY_ERROR_MSG})
def get_device_data(): device_name_bi = request.args.get("device_name_bi", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (device_name_bi, DEVICE_NAME_BI_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check device = Device.get_by_name_bi(device_name_bi) if device is None: return http_json_response( False, 400, **{"error": DEVICE_NAME_BI_INVALID_ERROR_MSG}) if not User.can_use_device(user, device.id): return http_json_response(False, 400, **{"error": UNAUTHORIZED_USER_ERROR_MSG}) result = [] for row in device.data: r = row.as_dict() for k, v in r.items(): if isinstance(v, bytes): r[k] = v.decode() result.append(r) return http_json_response(**{'device_data': result})
def decrypt(): decryptor = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None)) owner_api_username = request.args.get("api_username", None) serialized_ciphertext = request.args.get("ciphertext", None) arg_check = check_missing_request_argument( (owner_api_username, OWNER_API_USERNAME_MISSING_ERROR_MSG), (serialized_ciphertext, CIPHERTEXT_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check pairing_group = create_pairing_group() cp_abe = create_cp_abe() data_owner = db.session.query(AttrAuthUser) \ .filter(AttrAuthUser.api_username == owner_api_username) \ .first() if data_owner is None: return http_json_response(False, 400, **{"error": INVALID_OWNER_API_USERNAME_ERROR_MSG}) public_key = deserialize_charm_object(data_owner.master_keypair.data_public, pairing_group) private_key = deserialize_charm_object(get_private_key_based_on_owner(decryptor, data_owner).data, pairing_group) ciphertext = deserialize_charm_object(str.encode(serialized_ciphertext), pairing_group) try: plaintext = cp_abe.decrypt(public_key, private_key, ciphertext) except: return http_json_response(False, 400, **{"error": COULD_NOT_DECRYPT_ERROR_MSG}) # return plaintext return http_json_response(**{'plaintext': plaintext.decode("utf-8")})
def add_scene_action(): scene_name_bi = request.form.get("scene_name_bi", None) action_name_bi = request.form.get("action_name_bi", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (scene_name_bi, SCENE_NAME_BI_MISSING_ERROR_MSG), (action_name_bi, ACTION_NAME_BI_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check sc = Scene.get_by_name_bi(scene_name_bi) ac = Action.get_by_name_bi(action_name_bi) if sc is None or ac is None: return http_json_response( False, 400, **{"error": INVALID_SCENE_OR_ACTION_BI_ERROR_MSG}) if not User.can_use_device(user, ac.device_id): return http_json_response(False, 400, **{"error": UNAUTHORIZED_USER_ERROR_MSG}) if sc.owner is not None and sc.owner != user: return http_json_response( False, 400, **{"error": UNAUTHORIZED_USER_SCENE_ERROR_MSG}) if sc.already_present(ac): return http_json_response( False, 400, **{"error": ACTION_ALREADY_PRESENT_ERROR_MSG}) sc.actions.append(ac) db.session.add(sc) db.session.commit() return http_json_response()
def trigger_scene(): name_bi = request.args.get("name_bi", None) additional_data = request.args.get("additional_data", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (name_bi, ACTION_NAME_BI_MISSING_ERROR_MSG), (additional_data, ADDITIONAL_DATA_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check if not user.is_registered_with_broker: return http_json_response( False, 400, **{"error": NOT_REGISTERED_WITH_BROKER_ERROR_MSG}) sc = Scene.get_by_name_bi(name_bi) if sc is None: return http_json_response(False, 400, **{"error": INVALID_SCENE_BI_ERROR_MSG}) if sc.owner is not None and sc.owner != user: return http_json_response( False, 400, **{"error": UNAUTHORIZED_USER_SCENE_ERROR_MSG}) for ac in sc.actions: payload = create_payload(user.mqtt_creds.username, { "action": ac.name.decode("utf-8"), "additional_data": additional_data }) topic = format_topic(user.mqtt_creds.username, ac.device.mqtt_creds.username) client.publish(topic, payload) return http_json_response()
def create_device(): device_type_id = request.form.get("type_id", None) correctness_hash = request.form.get("correctness_hash", None) name = request.form.get("name", None) name_bi = request.form.get("name_bi", None) password_hash = request.form.get("password", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (device_type_id, DEVICE_TYPE_ID_MISSING_ERROR_MSG), (correctness_hash, CORRECTNESS_HASH_MISSING_ERROR_MSG), (name, DEVICE_NAME_MISSING_ERROR_MSG), (password_hash, DEVICE_PASSWORD_MISSING_ERROR_MSG), (name_bi, DEVICE_NAME_BI_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check dt = None try: if is_valid_uuid(device_type_id): dt = db.session.query(DeviceType).filter( DeviceType.type_id == device_type_id).first() finally: if dt is None: return http_json_response( False, 400, **{"error": DEVICE_TYPE_ID_INCORRECT_ERROR_MSG}) if not user.is_registered_with_broker: return http_json_response( False, 400, **{"error": NOT_REGISTERED_WITH_BROKER_ERROR_MSG}) if not validate_broker_password(password_hash): return http_json_response( False, 400, **{"error": INVALID_BROKER_PASSWORD_ERROR_MSG}) ud = UserDevice() # noinspection PyArgumentList dv = Device(device_type_id=device_type_id, device_type=dt, owner=user, owner_id=user.id, correctness_hash=correctness_hash, name=name.encode(), name_bi=name_bi) ud.device = dv with db.session.no_autoflush: user.devices.append(ud) dv.create_mqtt_creds_for_device(password_hash, db.session) user.add_acls_for_device(dv.id) db.session.add(dv) db.session.commit() return http_json_response(**{'id': dv.id})
def delete_account_aa(): user = AttrAuthUser.get_using_jwt_token( request.headers.get('Authorization', "")) db.session.delete(user) db.session.commit() return http_json_response()
def register_to_broker(): password_hash = request.form.get("password", None) user = User.get_using_jwt_token(request.headers.get('Authorization', "")) arg_check = check_missing_request_argument( (password_hash, USER_MISSING_PASSWORD_HASH)) if arg_check is not True: return arg_check if not validate_broker_password(password_hash): return http_json_response( False, 400, **{"error": INVALID_BROKER_PASSWORD_ERROR_MSG}) user.create_mqtt_creds_for_user(password_hash, db.session) db.session.commit() return http_json_response(**{"broker_id": str(user.id)})
def get_device_by_name(): device_name_bi = request.args.get("name_bi", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) if device_name_bi is None: return http_json_response( False, 400, **{"error": DEVICE_NAME_BI_MISSING_ERROR_MSG}) devices = db.session.query(Device).filter( and_(Device.name_bi == device_name_bi, Device.owner == user)) result = [] for device in devices: d = device.as_dict() for k, v in d.items(): if isinstance(v, bytes): d[k] = v.decode() result.append(d) return http_json_response(**{'devices': result})
def set_username(): user = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None)) api_username = request.form.get("api_username", None) arg_check = check_missing_request_argument((api_username, API_USERNAME_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check if AttrAuthUser.get_by_user_name(api_username) is not None: return http_json_response(False, 400, **{"error": API_USERNAME_ALREADY_PRESENT_MSG}) user.api_username = api_username db.session.add(user) db.session.commit() return http_json_response()
def device_keygen(): data_owner = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None)) attr_list = request.form.get("attr_list", None) arg_check = check_missing_request_argument( (attr_list, ATTR_LIST_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check attr_list = parse_attr_list(attr_list) if not attr_list: return http_json_response(False, 400, **{"error": INVALID_ATTR_LIST_ERROR_MSG}) serialized_private_key = create_private_key(data_owner.master_keypair.data_master, data_owner.master_keypair.data_public, attr_list) # delegate to receiver of generated key return http_json_response(private_key=serialized_private_key.decode("utf-8"))
def exchange_session_keys(): user_public_key_bytes = request.form.get("public_key", None) device_id = request.form.get("device_id", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (user_public_key_bytes, PUBLIC_KEY_MISSING_ERROR_MSG), (device_id, DEVICE_ID_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check if not User.can_use_device(user, device_id): return http_json_response(False, 400, **{"error": UNAUTHORIZED_USER_ERROR_MSG}) payload_bytes = bytes( Payload(user_public_key=user_public_key_bytes, user_id=user.id)) client.publish(f'server/d:{device_id}/', f'"{payload_bytes.decode("utf-8")}"'.encode()) return http_json_response()
def authorize_user(): device_name_bi = request.form.get("device_name_bi", None) auth_user_id = request.form.get("auth_user_id", None) # ID of user to be authorized user = User.get_using_jwt_token(request.headers.get("Authorization", "")) auth_user = User.get_by_id(auth_user_id) arg_check = check_missing_request_argument( (device_name_bi, DEVICE_NAME_BI_MISSING_ERROR_MSG), (auth_user_id, AUTH_USER_ID_MISSING_ERROR_MSG), (None if auth_user is None or auth_user.id == user.id else auth_user, AUTH_USER_ID_INVALID_ERROR_MSG)) if arg_check is not True: return arg_check device = Device.get_by_name_bi(device_name_bi) if device is None or not User.can_use_device(user, device.id): return http_json_response(False, 400, **{"error": UNAUTHORIZED_USER_ERROR_MSG}) if not auth_user.is_registered_with_broker: return http_json_response( False, 400, **{"error": NOT_REGISTERED_WITH_BROKER_ERROR_MSG}) if next((ud for ud in device.users if ud.user_id == auth_user.id), None) is not None: return http_json_response( False, 400, **{"error": AUTH_USER_ALREADY_AUTHORIZED_ERROR_MSG}) ud = UserDevice() ud.device = device ud.user = auth_user db.session.add(ud) auth_user.add_acls_for_device(device.id) device.add_acls_for_user(auth_user_id) db.session.add(auth_user) db.session.add(device) db.session.commit() return http_json_response()
def retrieve_private_keys(): user = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None)) private_keys = [{ "data": key.data.decode("utf-8"), "key_update": key.key_update, "attributes": [a.value for a in key.attributes], "challenger_id": key.challenger_id, "device_id": key.device_id, } for key in user.private_keys] return http_json_response(**{'private_keys': private_keys})
def revoke_user(): device_name_bi = request.form.get("device_name_bi", None) revoke_user_id = request.form.get("revoke_user_id", None) # ID of user to be revoked user = User.get_using_jwt_token(request.headers.get("Authorization", "")) user_to_revoke = User.get_by_id(revoke_user_id) arg_check = check_missing_request_argument( (device_name_bi, DEVICE_NAME_BI_MISSING_ERROR_MSG), (revoke_user_id, REVOKE_USER_ID_MISSING_ERROR_MSG), (None if user_to_revoke is None or user_to_revoke.id == user.id else user_to_revoke, REVOKE_USER_ID_INVALID_ERROR_MSG)) if arg_check is not True: return arg_check device = Device.get_by_name_bi(device_name_bi) if device is None or not User.can_use_device(user, device.id): return http_json_response(False, 400, **{"error": UNAUTHORIZED_USER_ERROR_MSG}) device = Device.get_by_id(device.id) if next((ud for ud in device.users if ud.user_id == user_to_revoke.id), None) is None: return http_json_response( False, 400, **{"error": REVOKE_USER_NOT_AUTHORIZED_ERROR_MSG}) ud_to_remove = UserDevice.get_by_ids(int(device.id), user_to_revoke.id) device.users.remove(ud_to_remove) db.session.add(device) user_to_revoke.remove_acls_for_device(device.id) device.remove_acls_for_user(revoke_user_id) db.session.add(device) db.session.add(user_to_revoke) db.session.commit() return http_json_response()
def create_device_type(): description = request.form.get("description", None) correctness_hash = request.form.get("correctness_hash", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (description, DEVICE_TYPE_DESC_MISSING_ERROR_MSG), (correctness_hash, CORRECTNESS_HASH_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check dt = DeviceType(description=description.encode(), owner=user, correctness_hash=correctness_hash) db.session.add(dt) db.session.commit() return http_json_response(**{"type_id": str(dt.type_id)})
def key_setup(): pairing_group = create_pairing_group() cp_abe = create_cp_abe() public_key, master_key = cp_abe.setup() # "store keypair in DB" user = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None)) serialized_public_key = serialize_charm_object(public_key, pairing_group) serialized_master_key = serialize_charm_object(master_key, pairing_group) user.master_keypair = MasterKeypair(data_public=serialized_public_key, data_master=serialized_master_key) db.session.add(user) db.session.commit() # return pk, msk return http_json_response(**{'public_key': serialized_public_key.decode("utf-8")})
def encrypt(): data_owner = AttrAuthUser.get_using_jwt_token(request.headers.get("Authorization", None)) plaintext = request.args.get("message", None) policy_string = request.args.get("policy_string", None) arg_check = check_missing_request_argument( (plaintext, MESSAGE_MISSING_ERROR_MSG), (policy_string, POLICY_STRING_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check pairing_group = create_pairing_group() cp_abe = create_cp_abe() public_key = deserialize_charm_object(data_owner.master_keypair.data_public, pairing_group) ciphertext = cp_abe.encrypt(public_key, plaintext, policy_string) # return ciphertext return http_json_response(**{'ciphertext': serialize_charm_object(ciphertext, pairing_group).decode("utf-8")})
def create_scene(): name = request.form.get("name", None) description = request.form.get("description", None) name_bi = request.form.get("name_bi", None) correctness_hash = request.form.get("correctness_hash", None) arg_check = check_missing_request_argument( (name, SCENE_NAME_MISSING_ERROR_MSG), (description, SCENE_DESC_MISSING_ERROR_MSG), (name_bi, SCENE_NAME_BI_MISSING_ERROR_MSG), (correctness_hash, CORRECTNESS_HASH_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check sc = Scene(name=name.encode(), name_bi=name_bi, description=description.encode(), correctness_hash=correctness_hash) db.session.add(sc) db.session.commit() return http_json_response()
def get_data_by_num_range(): lower_bound = request.args.get("lower", "") upper_bound = request.args.get("upper", "") device_name_bi = request.args.get("device_name_bi", None) user = User.get_using_jwt_token(request.headers.get("Authorization", "")) arg_check = check_missing_request_argument( (device_name_bi, DEVICE_NAME_BI_MISSING_ERROR_MSG)) if arg_check is not True: return arg_check device = Device.get_by_name_bi(device_name_bi) if device is None: return http_json_response( False, 400, **{"error": DEVICE_NAME_BI_INVALID_ERROR_MSG}) if not User.can_use_device(user, device.id): return http_json_response(False, 400, **{"error": UNAUTHORIZED_USER_ERROR_MSG}) if not is_number(lower_bound) and not is_number(upper_bound): return http_json_response(False, 400, **{"error": DATA_RANGE_MISSING_ERROR_MSG}) with suppress(ValueError): lower_bound = int(lower_bound) with suppress(ValueError): upper_bound = int(upper_bound) data = [] if isinstance(lower_bound, int) and isinstance(upper_bound, int): if -214748364800 <= lower_bound < upper_bound <= 214748364700: data = db.session.query(DeviceData).join(Device).filter( and_(DeviceData.num_data > lower_bound, DeviceData.num_data < upper_bound, Device.name_bi == device_name_bi)).all() else: return http_json_response( False, 400, **{"error": DATA_OUT_OF_OUTPUT_RANGE_ERROR_MSG}) elif not isinstance(upper_bound, int) and isinstance(lower_bound, int): if -214748364800 <= lower_bound <= 214748364700: data = db.session.query(DeviceData).join(Device).filter( and_(DeviceData.num_data > lower_bound, Device.name_bi == device_name_bi)).all() else: return http_json_response( False, 400, **{"error": DATA_OUT_OF_OUTPUT_RANGE_ERROR_MSG}) elif not isinstance(lower_bound, int) and isinstance(upper_bound, int): if -214748364800 <= upper_bound <= 214748364700: data = db.session.query(DeviceData).join(Device).filter( and_(DeviceData.num_data < upper_bound, Device.name_bi == device_name_bi)).all() else: return http_json_response( False, 400, **{"error": DATA_OUT_OF_OUTPUT_RANGE_ERROR_MSG}) result = [] for row in data: r = row.as_dict() for k, v in r.items(): if isinstance(v, bytes): r[k] = v.decode() result.append(r) return http_json_response(**{'device_data': result})
def check_token(*args, **kwargs): token = request.headers.get("Authorization", "") if not validate_token(bind, token): return http_json_response( False, 400, **{"error": INVALID_ACCESS_TOKEN_ERROR_MSG}) return func(*args, **kwargs)
def handle_error(e): if hasattr(e, "code"): return http_json_response(False, e.code, **{"error": SOMETHING_WENT_WRONG_MSG}) return http_json_response(False, 500, **{"error": SOMETHING_WENT_WRONG_MSG})
def handle_authorize(remote, token, user_info): token = save_user(remote, user_info, token).decode() return http_json_response(**{'access_token': token})