Skip to main content

A plugin for OpenVoiceOS hardware abstraction layer

Project description

PHAL OAuth Plugin

WIP

Bus API

Listens for

# skills register app on load or on oauth.ping
self.bus.on("oauth.register", self.handle_oauth_register)

# this triggers the ovos shell oauth flow
self.bus.on("oauth.start", self.handle_start_oauth)

# when ovos shell sends client_id/secret add it to db and continue oauth flow
self.bus.on("ovos.shell.oauth.register.credentials", self.handle_client_secret)

# this returns the oauth url for any external UI that wants to use it
self.bus.on("oauth.get", self.handle_get_auth_url)

Emits

# on plugin load trigger register events from oauth skills that were loaded already
self.bus.emit(Message("oauth.ping"))

# on oauth.get send oauth.url
self.bus.emit(message.reply("oauth.url", {"url": url}))

# on oauth.start flow trigger ovos shell UI
self.bus.emit(message.forward(
        "ovos.shell.oauth.start.authentication",
        {"url": url, "needs_credentials": self.oauth_skills[skill_id]["needs_creds"]})
    )

Registering OAuth app with the plugin

send OAuth info in oauth.register

skill_id = message.data.get("skill_id")
app_id = message.data.get("app_id")
munged_id = f"{skill_id}_{app_id}"  # key for oauth db

# these fields are app specific and provided by skills
auth_endpoint = message.data.get("auth_endpoint")
token_endpoint = message.data.get("token_endpoint")
refresh_endpoint = message.data.get("refresh_endpoint")
cb_endpoint = f"http://0.0.0.0:{self.port}/auth/callback/{munged_id}"
scope = message.data.get("scope")

# some skills may require users to input these, other may provide it
# this will depend on the app TOS
client_id = message.data.get("client_id")
client_secret = message.data.get("client_secret")

QR Code - Remote OAuth Integration Flow

  • Note: This flow requires the a GUI to display the QR Code that can be scanned by the user using any external device. This also requires the port for the oauth app to be unblocked on the ufw.

Example Usage From A Skill / Plugin

self.skill_id = "my_skill_id"
self.app_id = "my_app_id"
self.client_id = None
self.munged_id = f"{self.skill_id}_{self.app_id}"
self.bus.on("oauth.app.host.info.response", self.handle_host_response)
self.bus.on("oauth.generate.qr.response", self.handle_qr_generated)
self.bus.on("oauth.token.response.{self.munged_id}", self.handle_token_response)

def handle_host_response(self, message):
    # Some apps with OAuth Spec 2.0 require client_id to match the redirect_uri address and port, set the client id before registering the skill, send a request to "oauth.get.app.host.info" to get the host and port
    host = message.data.get("host", None)
    port = message.data.get("port", None)
    self.client_id = f"http://{host}:{port}"

def register_skill(self):
    client_secret = "my_client_secret"
    auth_endpoint = "https://example.com/auth"
    token_endpoint = "https://example.com/auth/token"
    self.bus.emit(Message("oauth.register", {
        "skill_id": self.skill_id, #Required
        "app_id": self.app_id, #Required
        "client_id": self.client_id, #Optional - Some apps may require this
        "client_secret": client_secret, #Optional - Some apps may require this
        "auth_endpoint": auth_endpoint, #Required
        "token_endpoint": token_endpoint, #Required
        "refresh_endpoint": "", #Optional - Some apps may require this
        "scope": "", #Optional - Some apps may require this
        "shell_integration": True #Optional - mark as false if app/skill handles displaying generated QR code. mark as true if shell should handle it.
    }))

def start_qr_generation(self):
    self.bus.emit(Message("oauth.generate.qr.request", {
        "app_id": self.app_id, # Required
        "skill_id": self.skill_id # Required
    }))

def handle_qr_generated(self, message):
    qr = message.data.get("qr", None)
    # Use GUI to display the generated QR Code
    # somewhere in your QML UI
    self.gui["qr_image_path"] = qr

def handle_token_response(self, message):
    response = message.data
    access_token = response.get("access_token", None)
    # Do something with access_token once oauth flow is complete

# Always register the skill first before requesting the QR Code to be generated
self.register_skill()
self.start_qr_flow()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ovos_phal_plugin_oauth-0.1.6a2.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ovos_phal_plugin_oauth-0.1.6a2-py3-none-any.whl (11.8 kB view details)

Uploaded Python 3

File details

Details for the file ovos_phal_plugin_oauth-0.1.6a2.tar.gz.

File metadata

  • Download URL: ovos_phal_plugin_oauth-0.1.6a2.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ovos_phal_plugin_oauth-0.1.6a2.tar.gz
Algorithm Hash digest
SHA256 c5af288c96a753243ad593d8795fa7058632399b4663f379113dfd5e73220080
MD5 3b6f14ca2a17c56872391d3c8c9ea122
BLAKE2b-256 d5c75015fed100b4438c585ca5a87e287a4b903106575bf147aa57178da58ed2

See more details on using hashes here.

File details

Details for the file ovos_phal_plugin_oauth-0.1.6a2-py3-none-any.whl.

File metadata

File hashes

Hashes for ovos_phal_plugin_oauth-0.1.6a2-py3-none-any.whl
Algorithm Hash digest
SHA256 5324e591a19b892702ac2130f1bd16ae4402ea357d44a9dceb2efcde867beeb9
MD5 a4b8f75deca5ab4e2da1d15e0e16753b
BLAKE2b-256 8272fb9b116abeeadafd7bde7c6015c4b6f9f12020c738a756656ad6d7f0bf2a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page