Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

PHAL OAuth Plugin

This is a PHAL (hardware abstraction layer) plugin for OpenVoiceOS. It manages OAuth 2.0 authentication for skills. A skill registers an OAuth app with the plugin, and the plugin runs the OAuth flow and returns an access token.

Install

pip install ovos-PHAL-plugin-oauth

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 an OAuth app with the plugin

Send the 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

This flow needs a GUI to show the QR code, so the user can scan it with an external device. It also needs the OAuth app port open on the firewall (ufw).

Example usage from a skill or 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()

Related projects

License

Apache-2.0

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.7a2.tar.gz (11.3 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.7a2-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: ovos_phal_plugin_oauth-0.1.7a2.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ovos_phal_plugin_oauth-0.1.7a2.tar.gz
Algorithm Hash digest
SHA256 43973b9491bd894929404158be775562c1750b599ad19700f0ce0a073b9417bb
MD5 081bf9e5dc3e2d3e71f149aa51cd7b16
BLAKE2b-256 42ec6c34b405b2ad98ccc42b9c0ab48fc6ec25d55ab0fbaa5f90ce0450c87bd5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ovos_phal_plugin_oauth-0.1.7a2-py3-none-any.whl
Algorithm Hash digest
SHA256 d8e5bf452aa408dcf6dbba5958ac56e9198b73cb6a27120b77baf7f89a70e816
MD5 085fc150948cdde4759ef5621787b146
BLAKE2b-256 c89fd6aa7fa617f807ea38dddf0a943b7027964c459af3f49295ddd47bf53fc8

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 Sentry Error logging StatusPage Status page