File

mod_rest/example/prosody_oauth.py @ 6325:6ea80b73d8f2

mod_http_oauth2: Only require redirect URIs when using grant types that need it In the Device flow, no redirect URI is used because the client instead receives responses by polling. It is therefore unnecessary to enforce a requirement that these include redirect URI(s).
author Kim Alvefur <zash@zash.se>
date Thu, 03 Jul 2025 15:42:42 +0200
parent 5488:9a4556a13cc7
line wrap: on
line source

from requests_oauthlib import OAuth2Session
import requests


class ProsodyRestSession(OAuth2Session):
    def __init__(
        self, base_url, client_name, client_uri, redirect_uri, *args, **kwargs
    ):
        self.base_url = base_url
        discovery_url = base_url + "/.well-known/oauth-authorization-server"

        meta = requests.get(discovery_url).json()
        reg = requests.post(
            meta["registration_endpoint"],
            json={
                "client_name": client_name,
                "client_uri": client_uri,
                "redirect_uris": [redirect_uri],
                "application_type": redirect_uri[:8] == "https://"
                and "web"
                or "native",
            },
        ).json()

        super().__init__(client_id=reg["client_id"], *args, **kwargs)

        self.meta = meta
        self.client_secret = reg["client_secret"]
        self.client_id = reg["client_id"]

    def authorization_url(self, *args, **kwargs):
        return super().authorization_url(
            self.meta["authorization_endpoint"], *args, **kwargs
        )

    def fetch_token(self, *args, **kwargs):
        return super().fetch_token(
            token_url=self.meta["token_endpoint"],
            client_secret=self.client_secret,
            *args,
            **kwargs
        )

    def xmpp(self, json=None, *args, **kwargs):
        return self.post(self.base_url + "/rest", json=json, *args, **kwargs)


if __name__ == "__main__":
    # Example usage

    # from prosody_oauth import ProsodyRestSession
    from getpass import getpass

    p = ProsodyRestSession(
        input("Base URL: "),
        "Prosody mod_rest OAuth 2 example",
        "https://modules.prosody.im/mod_rest",
        "urn:ietf:wg:oauth:2.0:oob",
    )

    print("Open the following URL in a browser and login:")
    print(p.authorization_url()[0])

    p.fetch_token(code=getpass("Paste Authorization code: "))

    print(p.xmpp(json={"disco": True, "to": "jabber.org"}).json())