Ejemplo n.º 1
0
 def apiv1_current_user_access_token(webinterface, request, session):
     """
     This gets the current logged in user's access token. This is typically called by the frontend
     application so that I can make calls to Yombo API.
     """
     if session.auth_type != AUTH_TYPE_WEBSESSION:
         raise YomboWarning(
             f"Must authenticate with a websession (cookie), not {session.auth_type}",
             title="Invalid session type")
     access_token = session.get_access_token(request)
     return webinterface.render_api(
         request,
         data=JSONApi(
             data={
                 "type": "user_session_token",
                 "id": request.auth.auth_id,
                 "attributes": {
                     "id": request.auth.auth_id,
                     "access_token": access_token[0],
                     "access_token_expires": access_token[1],
                     "session": request.session_long_id,
                 }
             }),
         data_type="user_session_token",
     )
Ejemplo n.º 2
0
    def render_api(self,
                   request: Type["twisted.web.http.Request"],
                   data: Union[JSONApi, dict],
                   data_type: Optional[str],
                   response_code: Optional[int] = None) -> str:
        """
        Renders content to an API based client.

        :param request: A request instance
        :param data: Prefers a JSONApi object, but accepts a dict.
        :param data_type: The string for the JSON API type.
        :param response_code: HTTP response code to set. Default: 200
        :return:
        """
        if isinstance(data, dict):
            data = JSONApi(data)

        output = data.to_dict()
        if data_type is None:
            data_type = data.data_type(output)

        return self.render_api_raw(request,
                                   data=output,
                                   data_type=data_type,
                                   response_code=response_code)
Ejemplo n.º 3
0
 def apiv1_system_info(webinterface, request, session):
     """ Various details about the gateway. """
     session.is_allowed(AUTH_PLATFORM_SYSTEM_OPTION, "backup")
     gateway = webinterface._Gateways.local
     attributes = {
         **gateway.to_dict(include_meta=False),
         **{
             "gateway_id": str(gateway.gateway_id),
             "operating_mode": str(webinterface._Loader.operating_mode)
         }
     }
     attributes["running_since"] = int(
         webinterface._Atoms["gateway.running_since"])
     attributes["uptime"] = int(webinterface._States["gateway.uptime"])
     attributes["version"] = VERSION
     attributes["id"] = gateway.gateway_id
     return webinterface.render_api(
         request,
         data=JSONApi(
             data={
                 "id": gateway.gateway_id,
                 "type": "system_info",
                 "attributes": attributes,
             }),
         data_type="system_info",
     )
Ejemplo n.º 4
0
 def apiv1_permissions_get(webinterface, request, session):
     session.is_allowed(AUTH_PLATFORM_PERMISSION, "view")
     return webinterface.render_api(
         request,
         data=JSONApi(webinterface._Permissions.get_all()),
         data_type="permissions",
     )
Ejemplo n.º 5
0
    def _states_set_(self, arguments, **kwargs):
        """
        Publish a new state, if it's from ourselves.

        :param arguments:
        :return:
        """
        if self.ok_to_publish_updates is False:
            return

        gateway_id = arguments["gateway_id"]
        if gateway_id not in (self._gateway_id, "global", "cluster"):
            return
        self.publish_yombo_gw("states", JSONApi(arguments["item"]).to_dict("to_database"))
        print(f'mqtt _states_set_: {JSONApi(arguments["item"]).to_dict("to_external")}')
        self.publish_yombo("states", JSONApi(arguments["item"]).to_dict("to_external"), jsonapi=True)
Ejemplo n.º 6
0
        def apiv1_generic_route_library_details_get(webinterface, request, session, resource_name, item_id):
            """
            Handles the majority of the api resource view requests.

            :param webinterface:
            :param request:
            :param session:
            :param resource_name:
            :return:
            """
            route_data = get_route_data(webinterface.generic_router_list, "libraries", resource_name, "view")
            session.is_allowed(route_data["auth_platform"], "view", item_id=item_id)
            klass = getattr(webinterface, route_data["resource_name"])

            data_type = route_data["resource_label"]
            if data_type == "modules":
                data_type = "gateway_modules"

            new_kwargs = {}
            arguments = signature(klass.get)
            if "instance" in arguments.parameters:
                new_kwargs["instance"] = True
            return webinterface.render_api(request,
                                           data=JSONApi(klass.get(item_id, **new_kwargs), data_type=data_type),
                                           data_type=data_type,
                                           )
Ejemplo n.º 7
0
 def apiv1_states_details_get(webinterface, request, session,
                              device_id):
     """ Gets a single device state. """
     webinterface._Validate.id_string(device_id)
     session.is_allowed(AUTH_PLATFORM_DEVICE_STATE, "view")
     device = webinterface._Devices.get(device_id)
     return webinterface.render_api(
         request,
         data=JSONApi(device.state_all),
         data_type="device_states",
     )
Ejemplo n.º 8
0
        def apiv1_permissions_details_get(webinterface, request, session,
                                          permission_id):
            webinterface._Validate.id_string(permission_id)
            session.is_allowed(AUTH_PLATFORM_PERMISSION, "view", permission_id)
            if permission_id in webinterface._Permissions:
                permission = webinterface._Permissions[permission_id]
            else:
                return return_not_found(request, "Role not found")

            return webinterface.render_api(
                request,
                data=JSONApi(permission),
                data_type="permissions",
            )
Ejemplo n.º 9
0
 def apiv1_states_get(webinterface, request, session):
     """ Get all devices' state. """
     session.is_allowed(AUTH_PLATFORM_DEVICE_STATE, "view")
     devices = webinterface._Devices.devices
     states = []
     for device_id, device in devices.items():
         if device.status == 2:
             continue
         states.append(device.state_all)
     return webinterface.render_api(
         request,
         data=JSONApi(states),
         data_type="device_states",
     )
Ejemplo n.º 10
0
        def apiv1_authkeys_rotate_get(webinterface, request, session, auth_id):
            webinterface._Validate.id_string(auth_id)
            session.is_allowed(AUTH_PLATFORM_AUTHKEY, "edit", auth_id)
            if len(auth_id) > 100 or isinstance(auth_id, str) is False:
                return return_error(request, "invalid auth_id format", 400)

            authkey = webinterface._AuthKeys[auth_id]
            auth_key_id_full = authkey.rotate()
            results = authkey.to_external()
            results["auth_key_id_full"] = auth_key_id_full

            return webinterface.render_api(request,
                                           data=JSONApi(authkey),
                                           data_type="auth_keys",
                                           )
Ejemplo n.º 11
0
 def apiv1_system_awake(webinterface, request, session):
     """
     A non-authed method of checking if the system is fully booted and ready to go.
     """
     return webinterface.render_api(
         request,
         data=JSONApi(
             data={
                 "id": int(
                     webinterface._Atoms["gateway.running_since"]),
                 "type": "system_awake",
                 "attributes": {
                     "id":
                     int(webinterface._Atoms["gateway.running_since"]),
                 }
             }),
         data_type="system_awake")
Ejemplo n.º 12
0
        def apiv1_generic_route_library_delete(webinterface, request, session, resource_name, item_id):
            """
            Deletes a resource record. The required attributes varies depending on what is being deleted.

            :param webinterface:
            :param request:
            :param session:
            :param resource_name:
            :param item_id:
            :return:
            """
            route_data = get_route_data(webinterface.generic_router_list, "libraries", resource_name, "remove")
            session.is_allowed(route_data["auth_platform"], "remove")
            library_reference = getattr(webinterface, route_data["resource_name"])

            results = yield maybeDeferred(library_reference.delete, item_id)
            return webinterface.render_api(request,
                                           data=JSONApi(results),
                                           data_type=route_data["resource_label"],
                                           )
Ejemplo n.º 13
0
 def apiv1_system_backup_info(webinterface, request, session):
     """ Returns details about backing up the gateway. """
     session.is_allowed(AUTH_PLATFORM_SYSTEM_OPTION, "backup")
     return webinterface.render_api(
         request,
         data=JSONApi(
             data={
                 "id": webinterface._gateway_id,
                 "type": "system_awake",
                 "attributes": {
                     "id":
                     webinterface._gateway_id,
                     "db_size":
                     os.path.getsize(
                         f"{webinterface._working_dir}/etc/yombo.sqlite3"
                     ),
                 }
             }),
         data_type="system_awake",
     )
Ejemplo n.º 14
0
        def apiv1_generic_route_library_post(webinterface, request, session, resource_name):
            """
            Create a new resource record. The required attributes varies depending on what is being created.

            :param webinterface:
            :param request:
            :param session:
            :param resource_name:
            :return:
            """
            route_data = get_route_data(webinterface.generic_router_list, "libraries", resource_name, "create")
            session.is_allowed(route_data["auth_platform"], "create")
            library_reference = getattr(webinterface, route_data["resource_name"])

            data, arguments = generic_arguments(request, session)
            data.update(arguments)
            results = yield maybeDeferred(library_reference.new, **data)
            return webinterface.render_api(request,
                                           data=JSONApi(results),
                                           data_type=route_data["resource_label"],
                                           )
Ejemplo n.º 15
0
        def apiv1_system_tools_ping(webinterface, request, session):
            """
            Responds to a simple ping. This allows frontend client to judge how far away the gateway is.
            """
            try:
                request_id = request.args.get("id")[0]
            except Exception as e:
                request_id = random_string(length=12)

            return webinterface.render_api(
                request,
                data=JSONApi(
                    data={
                        "id": request_id,
                        "type": "system_ping",
                        "attributes": {
                            "id": request_id,
                            "time": float(time()),
                        },
                    }),
                data_type="system_ping",
            )
Ejemplo n.º 16
0
        def apiv1_generic_route_library_get(webinterface, request, session, resource_name):
            """
            Handles the majority of the api resource view requests.

            :param webinterface:
            :param request:
            :param session:
            :param resource_name:
            :return:
            """
            data = request_args(request)
            filters = None
            if "filter" in data:
                filters = data["filter"]

            if resource_name == "gateway_modules":
                resource_name = "modules"

            route_data = get_route_data(webinterface.generic_router_list, "libraries", resource_name, "view")
            session.is_allowed(route_data["auth_platform"], "view")
            klass = getattr(webinterface, route_data["resource_name"])
            data_type = route_data["resource_label"]
            if data_type == "modules":
                data_type = "gateway_modules"
            try:
                # print(f"generic get: {klass.get_all(filters=filters, gateway_id=webinterface._gateway_id)}")
                return webinterface.render_api(request,
                                               data=JSONApi(klass.get_all(filters=filters, gateway_id=webinterface._gateway_id),
                                                            data_type=data_type),
                                               data_type=data_type,
                                               )
            except Exception as e:
                logger.error("--------==(Error: {e})==--------", e=e)
                logger.error("--------------------------------------------------------")
                logger.error("{error}", error=sys.exc_info())
                logger.error("---------------==(Traceback)==--------------------------")
                logger.error("{trace}", trace=traceback.print_exc(file=sys.stdout))
                logger.error("--------------------------------------------------------")
Ejemplo n.º 17
0
        def apiv1_generic_route_library_patch(webinterface, request, session, resource_name, item_id):
            """
            Updates (patches/puts) a resource record. The required attributes varies depending on what is being
            updated.

            :param webinterface:
            :param request:
            :param session:
            :param resource_name:
            :param item_id:
            :return:
            """
            route_data = get_route_data(webinterface.generic_router_list, "libraries", resource_name, "modify")
            session.is_allowed(route_data["auth_platform"], "modify")
            library_reference = getattr(webinterface, route_data["resource_name"])

            patch_put_hotfix(request)
            data, arguments = generic_arguments(request, session)

            results = yield maybeDeferred(library_reference.update, item_id, data, **arguments)
            return webinterface.render_api(request,
                                           data=JSONApi(results),
                                           data_type=route_data["resource_label"],
                                           )
Ejemplo n.º 18
0
        def apiv1_system_status_uptime(webinterface, request, session):
            """ Returns the system uptime. """
            try:
                timeonly = str(request.args.get("timeonly")[0])
                if timeonly == "1":
                    return str(webinterface._Atoms["gateway.running_since"])
            except Exception as e:
                pass

            return webinterface.render_api(
                request,
                data=JSONApi(
                    data={
                        "id": str(
                            webinterface._Atoms["gateway.running_since"]),
                        "type": "system_uptime",
                        "attributes": {
                            "id": str(
                                webinterface._Atoms["gateway.running_since"]),
                            "time": float(time()),
                        },
                    }),
                data_type="system_uptime",
            )
Ejemplo n.º 19
0
        def apiv1_devices_command_get_post(webinterface, request, session,
                                           device_id, command_id):
            webinterface._Validate.id_string(device_id)
            webinterface._Validate.id_string(command_id)
            session.is_allowed(AUTH_PLATFORM_DEVICE, "control", device_id)

            try:
                wait_time = float(request.args.get("_wait")[0])
            except:
                wait_time = 2

            print(f"rrequest.content.read(): {request.content.read()}")
            print(f"request.processed_body: {request.processed_body}")
            print(
                f"request.processed_body_encoding: {request.processed_body_encoding}"
            )
            print(f"request.args: {request.args}")
            if request.processed_body is not None:
                arguments = request.processed_body
            else:
                arguments = request_args(request)

            pin_code = arguments.get("pin_code", None)
            delay = arguments.get("delay", None)
            max_delay = arguments.get("max_delay", None)
            not_before = arguments.get("not_before", None)
            not_after = arguments.get("not_after", None)
            inputs = arguments.get("inputs", None)

            if device_id in webinterface._Devices:
                device = webinterface._Devices[device_id]
            else:
                return return_not_found(request, "Device id not found")

            if command_id in webinterface._Commands:
                command = webinterface._Commands[command_id]
            else:
                return return_not_found(request, "Command id not found")
            print(f"device control, input: {inputs}")
            try:
                device_command_id = yield device.command(
                    command=command,
                    authentication=session,
                    pin=pin_code,
                    delay=delay,
                    max_delay=max_delay,
                    not_before=not_before,
                    not_after=not_after,
                    inputs=inputs,
                    request_context=f"api/v1:{request.getClientIP()}"
                    # idempotence=request.idempotence,
                )
            except KeyError as e:
                print(
                    f"error with apiv1_device_command_get_post keyerror: {e}")
                return return_not_found(
                    request, f"Error with command, it is not found: {e}")
            except YomboWarning as e:
                print(f"error with apiv1_device_command_get_post warning: {e}")
                return return_error(request, f"Error with command: {e}")

            DC = webinterface._DeviceCommands.device_commands[
                device_command_id]
            if wait_time > 0:
                exit_while = False
                start_time = time()
                while (start_time > (time() - wait_time)
                       and exit_while is False):
                    yield sleep(.075)
                    if DC.status_id >= 100:
                        exit_while = True

            if len(device.state_history) > 0:
                status_current = device.state_history[0].to_dict(
                    include_meta=False)
            else:
                status_current = None

            if len(device.state_history) > 1:
                status_previous = device.state_history[1].to_dict(
                    include_meta=False)
            else:
                status_previous = None

            return webinterface.render_api(
                request,
                data=JSONApi(
                    data={
                        "type": device_command_id,
                        "id": device_command_id,
                        "attributes": {
                            "id": device_command_id,
                            "device_id": device.device_id,
                            "command_id": DC.command_id,
                            "device_command_id": device_command_id,
                            "device_command": DC.to_dict(include_meta=False),
                            "status_current": status_current,
                            "status_previous": status_previous,
                        }
                    }),
                data_type="device_commands",
            )