Exemplo n.º 1
0
 def post(self):
     """Sign the owner out and return to given return page."""
     # XXX if not web.tx.user.is_owner:
     # XXX     raise web.Unauthorized("must be owner")
     web.tx.user.session = None
     return_to = web.form(return_to="").return_to
     raise web.SeeOther(f"/{return_to}")
Exemplo n.º 2
0
 def post(self):
     program = web.form("program").program
     machine = tx.db.select("machines",
                            where="name = ?",
                            vals=[self.machine])[0]
     web.enqueue(build, machine["ip_address"], program)
     raise web.Accepted(f"{program} is building on the machine..")
Exemplo n.º 3
0
def initiate_auth():
    """
    Begin the authorization and return a three-tuple of client, developer and scope(s).

    Should be called from the GET handler for the Authorization Endpoint.

    """
    form = web.form("response_type",
                    "client_id",
                    "redirect_uri",
                    "state",
                    scope="")
    if form.response_type not in ("code", "id"):  # NOTE `id` for backcompat
        raise web.BadRequest('`response_type` must be "code".')
    client, developer = _discover_client(form.client_id)
    tx.user.session.update(
        client_id=form.client_id,
        client_name=client["name"],
        redirect_uri=form.redirect_uri,
        state=form.state,
    )
    if "code_challenge" in form and "code_challenge_method" in form:
        tx.user.session.update(
            code_challenge=form.code_challenge,
            code_challenge_method=form.code_challenge_method,
        )
    return client, developer, form.scope.split()
Exemplo n.º 4
0
 def post(self):
     """Perform an action."""
     form = web.form("action", channel="default")
     response = {}
     if form.action == "channels":
         web.tx.sub.add_channel(form.name)
         response = {"channels": web.tx.sub.get_channels()}
     elif form.action == "search":
         response = {"results": web.tx.sub.search(form.query)}
     elif form.action == "preview":
         response = web.tx.sub.preview(form.url)
     elif form.action == "follow":
         web.tx.sub.follow(form.url)
         response = {"items": web.tx.sub.get_following()}
         web.enqueue(websub.subscribe,
                     f"{web.tx.origin}/subscriptions/sent", form.url)
     elif form.action == "unfollow":
         pass
     elif form.action == "timeline":
         pass
     elif form.action == "mute":
         pass
     elif form.action == "unmute":
         pass
     elif form.action == "block":
         pass
     elif form.action == "unblock":
         pass
     web.header("Content-Type", "application/json")
     return response
Exemplo n.º 5
0
 def post(self):
     name = web.form("name").name
     token = tx.db.select("providers",
                          where="service = ?",
                          vals=["dynadot.com"])[0]["token"]
     # XXX web.enqueue(spawn_machine, name, token)
     raise web.Created("domain has been added..", f"/sites/domains/{name}")
Exemplo n.º 6
0
 def post(self):
     name = web.form("name").name
     token = tx.db.select("providers",
                          where="service = ?",
                          vals=["digitalocean.com"])[0]["token"]
     web.enqueue(spawn_machine, name, token)
     raise web.Accepted("machine is being created..")
Exemplo n.º 7
0
 def get(self):
     """Return a search box or search results."""
     try:
         query = web.form("q").q
     except web.BadRequest:
         return app.view.search()
     results = tx.cache.search(query)
     return app.view.results(query, results)
Exemplo n.º 8
0
 def post(self):
     """Handle "Access Token" flow response or revoke an existing access token."""
     # TODO token introspection
     # TODO token verification
     try:
         form = web.form("action", "token")
     except web.BadRequest:
         return _redeem_authorization_code("token")
     if form.action == "revoke":
         revoke_auth(form.token)
Exemplo n.º 9
0
 def post(self):
     try:
         topic_url = web.form("topic_url").topic_url
     except web.BadRequest:
         pass
     else:
         web.enqueue(websub.subscribe,
                     f"{web.tx.origin}/subscriptions/sent", topic_url)
         return app.view.sent.subscription_requested()
     mode = web.form("hub.mode")["hub.mode"]
     if mode != "subscribe":
         raise web.BadRequest(
             'hub only supports subscription; `hub.mode` must be "subscribe"'
         )
     form = web.form("hub.topic", "hub.callback")
     # TODO raise web.BadRequest("topic not found")
     web.enqueue(websub.verify_received_subscription, form["hub.topic"],
                 form["hub.callback"])
     raise web.Accepted("subscription request accepted")
Exemplo n.º 10
0
 def verify_passphrase(self):
     """Verify passphrase, sign the owner in and return to given return page."""
     form = web.form("passphrase", return_to="/")
     passphrase = web.tx.identities.get_passphrase()
     if web.verify_passphrase(
             passphrase["passphrase_salt"],
             passphrase["passphrase_hash"],
             form.passphrase.replace(" ", ""),
     ):
         web.tx.user.session = web.tx.identities.get_identity(
             web.tx.origin)["card"]
         raise web.SeeOther(form.return_to)
     raise web.Unauthorized("bad passphrase")
Exemplo n.º 11
0
def redeem_authorization_code(flow: str,
                              me: web.uri,
                              name: str = None,
                              email: str = None,
                              photo: web.uri = None) -> dict:
    """
    Redeem an authorization code with given `flow` and return a profile and/or a token.

    `flow` can be one of ['profile'][0] or ['token'][1].

    [0]: https://indieauth.spec.indieweb.org/#profile-url-response
    [1]: https://indieauth.spec.indieweb.org/#access-token-response

    """
    form = web.form("code",
                    "client_id",
                    "redirect_uri",
                    grant_type="authorization_code")
    # TODO verify authenticity
    # TODO grant_type=refresh_token
    if form.grant_type not in ("authorization_code", "refresh_token"):
        raise web.Forbidden(f"`grant_type` {form.grant_type} not supported")
    auth = tx.auth_server.get_auth_from_code(form.code)
    if form.client_id != auth["client_id"]:
        raise web.BadRequest("`client_id` does not match original request")
    if form.redirect_uri != auth["redirect_uri"]:
        raise web.BadRequest("`redirect_uri` does not match original request")
    if "code_verifier" in form:
        if not auth["code_challenge"]:
            raise web.BadRequest("`code_verifier` without a `code_challenge`")
        if auth["code_challenge"] != generate_challenge(form.code_verifier):
            raise web.Forbidden("code mismatch")
    elif auth["code_challenge"]:
        raise web.BadRequest("`code_challenge` without `code_verifier`")
    response = auth["response"]
    if flow == "token":
        if not response["scope"]:
            raise web.BadRequest("Access Token request requires a scope")
        response.update(
            token_type="Bearer",
            access_token=f"secret-token:{web.nbrandom(24)}",
        )
    response["me"] = me
    if "profile" in response["scope"]:
        response["profile"] = {"url": me, "name": name, "photo": photo}
        if "email" in response["scope"] and email:
            response["profile"]["email"] = email
    tx.auth_server.update_auth(response, auth["code"])
    web.header("Content-Type", "application/json")
    return response
Exemplo n.º 12
0
def wrap(handler, main_app):
    """Ensure an owner exists and then add their details to the transaction."""
    web.tx.response.claimed = True
    try:
        web.tx.host.owner = web.tx.identities.get_identity(
            web.tx.origin)["card"]
    except IndexError:
        web.header("Content-Type", "text/html")
        # if web.tx.request.method == "GET":
        #     web.tx.response.claimed = False
        #     raise web.NotFound(app.view.claim())
        # elif web.tx.request.method == "POST":
        # name = web.form("name").name
        web.tx.identities.add_identity(web.tx.origin, "Anonymous")
        passphrase = " ".join(web.tx.identities.add_passphrase())
        web.tx.host.owner = web.tx.user.session = web.tx.identities.get_identity(
            web.tx.origin)["card"]
        web.tx.user.is_owner = True
        if kiosk := web.form(kiosk=None).kiosk:
            with open(f"{kiosk}/passphrase", "w") as fp:
                fp.write(passphrase)
            raise web.SeeOther("/")
        raise web.Created(app.view.claimed(web.tx.origin, passphrase),
                          web.tx.origin)
Exemplo n.º 13
0
 def get(self):
     """Confirm subscription request."""
     try:
         action = web.form("action").action
     except web.BadRequest:
         pass
     else:
         if action == "unsubscribe":
             web.enqueue(websub.unsubscribe, self.subscription_id)
             return "unsubscribed"
         raise web.BadRequest("action must be `unsubscribe`")
     try:
         form = web.form("hub.mode", "hub.topic", "hub.challenge",
                         "hub.lease_seconds")
     except web.BadRequest:
         pass
     else:
         web.tx.websub.verify_sent_subscription(
             form["hub.topic"],
             f"{web.tx.origin}/subscriptions/sent/{self.subscription_id}",
         )
         # TODO verify the subscription
         return form["hub.challenge"]
     return "sent sub"
Exemplo n.º 14
0
 def get(self):
     """Perform an action or return an activity summary."""
     try:
         form = web.form("action", channel="default")
     except web.BadRequest:
         return app.view.activity(web.tx.sub.get_following(),
                                  web.tx.sub.get_channels())
     response = {}
     if form.action == "channels":
         response = {"channels": web.tx.sub.get_channels()}
     if form.action == "follow":
         response = {"items": web.tx.sub.get_following()}
     elif form.action == "timeline":
         response = {"items": []}
     web.header("Content-Type", "application/json")
     return response
Exemplo n.º 15
0
 def post(self):
     tx.db.update("config", theme=web.form("action").action == "activate")
     return "accepted"
Exemplo n.º 16
0
    def post(self):
        # form = web.form("subdomain", "name")
        form = web.form("provider", "token")
        config = get_config()

        # domain = config["domain"]
        # fqdn = domain
        # if form.subdomain:
        #     fqdn = f"{form.subdomain}.{domain}"
        # update_config(fqdn=fqdn)

        if form.provider == "digitalocean.com":
            c = host.digitalocean.Client(form.token)
            try:
                c.get_keys()
            except host.digitalocean.TokenError:
                return {"status": "error", "message": "bad token"}
        elif form.provider == "linode.com":
            ...
        elif form.provider == "hetzner.com":
            ...
        else:
            return {
                "status": "error",
                "message": f"unsupported provider: {form.provider}",
            }
        config = update_config(host={
            "provider": form.provider,
            "token": form.token,
        })

        # try:
        #     ip_address = config["ip_address"]
        # except KeyError:
        ip_address = host.spawn_machine("canopy", config["host"]["token"])
        config = update_config(ipAddress=ip_address, status={})

        # registrar = config["registrar"]
        # if registrar["provider"] == "dynadot.com":
        #     dynadot = host.providers.Dynadot(registrar["token"])
        #     dynadot.create_record(domain, ip_address, form.subdomain)
        # elif registrar["provider"] == "name.com":
        #     namecom = host.providers.NameCom(registrar["username"],
        #                                      registrar["token"])
        #     namecom.create_record(domain, ip_address, form.subdomain)

        host.setup_machine(ip_address)
        config = update_config(system_setup=True)
        host.setup_nginx(ip_address)
        config = update_config(nginx_installed=True)
        return
        host.generate_dhparam(ip_address)
        host.setup_tor(ip_address)
        host.setup_python(ip_address)
        host.setup_supervisor(ip_address)

        # while True:
        #     try:
        #         if web.dns.resolve(fqdn, "A")[0].address == ip_address:
        #             break
        #     except (
        #         web.dns.NoAnswer,
        #         web.dns.NXDOMAIN,
        #         web.dns.Timeout,
        #         web.dns.NoNameservers,
        #     ):
        #         pass
        #     else:
        #         print("waiting for DNS changes to propagate..")
        #         time.sleep(15)

        onion, passphrase = setup_canopy(ip_address)  # , form.name, fqdn)
        update_config(onion=onion, passphrase=passphrase)
        return {"onion": onion, "passphrase": passphrase}
Exemplo n.º 17
0
 def post(self):
     """Handle consent screen action."""
     form = web.form("action", scopes=[])
     if form.action == "cancel":
         raise web.SeeOther(tx.user.session["redirect_uri"])
     consent(form.scopes)
Exemplo n.º 18
0
 def post(self):
     """"""
     form = web.form("source", "target")
     web.enqueue(receive, form.source, form.target)
     raise web.Accepted("webmention received")
Exemplo n.º 19
0
 def post(self):
     form = web.form("service", "token")
     web.tx.db.insert("providers", service=form.service, token=form.token)
     return "token has been set"
Exemplo n.º 20
0
 def get(self):
     """Return a preview of given `url`."""
     form = web.form("url")
     return app.view.preview(form.url, web.tx.sub.preview(form.url),
                             web.tx.sub.get_channels())
Exemplo n.º 21
0
 def get(self):
     """Return search results for given `q`."""
     form = web.form("q")
     return app.view.search(form.q, web.tx.sub.search(form.q))