Module indieauth

Source
Expand description

Provides an implementation of the IndieAuth standard.

The implementations in this crate allows for one to request a Token, verify it and other common operations. All known operations can be found under the request representation as well as the responses.

§Requesting A Token

In order to request a token or a profile, one needs to construct an authorization URL that’ll allow the user to provide you with an authorization code. You can build the such by doing the following:

use indieweb::standards::indieauth;
use indieweb::http::reqwest::Client as HttpClient;
use indieauth::Client;
use url::Url;

// Get networking client.
let http_client = HttpClient::default();

// Define who I want to be.
let me: Url = "https://jacky.wtf".parse().unwrap();

// Create a simple client for making requests.
let client: indieauth::Client = (
    indieauth::ClientId::new("https://jacky.wtf".into()),
    indieauth::EndpointDiscovery::Classic {
        authorization: "https://jacky.wtf/auth/auth".parse().unwrap(),
        token: "https://jacky.wtf/auth/token".parse().unwrap(),
        ticket: None
    }).into();

// Build the authorization URL to get an authorization code.
let response = client.dispatch(&http_client,
    indieauth::Request::BuildAuthorizationUrl {
        me: Some(me.clone()),
        scope: None,
        redirect_uri: None
    });

// Prune out the fields from the request.
let response_opt: Option<(_, _, _, _)> = response.await.as_ref()
        .ok()
        .and_then(|r| {
            if let indieauth::Response::AuthenticationUrl { url, verifier, challenge,
            csrf_token, issuer: _ } = r {
                Some((url.clone(), challenge.clone(), verifier.clone(), csrf_token.clone()))
                  .filter(|_| {
                    url.query_pairs().any(|(key, value)| {
                        key == "me" && value == me.as_str()
                    })
                  })
            } else {
                None
            }
         })
         .clone();

 assert!(
    response_opt
        .as_ref()
        .map(|(url, _, _, _)| url)
        .map(|url| {
            url.query_pairs().any(|(key, value)| {
                key == "me" && value == me.as_str()
            })
        }).unwrap_or(false),
    "confirms the authorization URL to send the user to on behalf of them");
// Direct the user to the location of `response_opt.unwrap().0`.

§Redeeming an Authorization Code

The IndieAuth server will do the work of confirming the identity and scopes that the site ends up permitting. You’ll be redirected back to with an authoriz ation code or error information. This step is meant to help capture that kind of information.

§Note

  • The logic for checking CSRF tokens is up to your implementation. It’s strongly recommended to do to prevent forged requests.
use indieweb::{
    standards::indieauth::{
        Client, EndpointDiscovery, ClientId, AuthUrl, TokenUrl, 
        Request, DesiredResourceAuthorization, AuthorizationCode
    },
    http::reqwest::Client as HttpClient
};

let http_client = HttpClient::default();

let client: Client = (
   ClientId::new("https://jacky.wtf".into()),
   EndpointDiscovery::Classic {
     authorization: "https://jacky.wtf/auth/auth".parse().unwrap(),
     token: "https://jacky.wtf/auth/token".parse().unwrap(),
     ticket: None
   }
).into();

let code = AuthorizationCode::new("abcdefghijklmnopqrstuvxwyz123456".to_string());

client.dispatch(&http_client, Request::CompleteAuthorization {
  code,
  resource: DesiredResourceAuthorization::Profile,
  code_verifier: String::default(),
  redirect_uri: None
});

The expected response from that dispatch call could be either the providing of a profile or of a token.

§Verifying A Token

The act of verification is done by doing the following:

use indieweb::{
    standards::indieauth::{AccessToken, Client,
        EndpointDiscovery, EndpointMetadata,
        ClientId, AuthUrl, TokenUrl, Request, DesiredResourceAuthorization},
    http::reqwest::Client as HttpClient
};

let http_client = HttpClient::default();

let client: Client = (
   ClientId::new("https://jacky.wtf".into()),
   EndpointDiscovery::Classic {
    authorization: "https://jacky.wtf/auth/auth".parse().unwrap(),
    token: "https://jacky.wtf/auth/token".parse().unwrap(),
    ticket: None
   }
).into();
let token = AccessToken::new("magic-token".to_string());

client.dispatch(&http_client, Request::VerifyAccessToken(token));

What’s missing from this implementation is logic for things like AutoAuth or TicketAuth. This also is locked at the 26 Nov 2020 version.

Structs§

AccessToken
Access token returned by the token endpoint and used to access protected resources.
AuthUrl
URL of the authorization server’s authorization endpoint.
AuthorizationCode
Authorization code returned from the authorization endpoint.
Client
A helper object for representing an interaction with a fixed client for fetching tokens.
ClientId
Client identifier issued to the client during the registration process described by Section 2.2.
EndpointMetadata
Represents a successful attempt at collecting metadata info.
Metadata
Represents all of the server metadata known.
OAuth2Interface
Provides a structured interface to use for OAuth2.
Parameters
Represents a collection of the most common values in IndieAuth contexts.
PkceCodeChallenge
Code Challenge used for PKCE protection via the code_challenge parameter.
PkceCodeVerifier
Code Verifier used for PKCE protection via the code_verifier parameter. The value must have a minimum length of 43 characters and a maximum length of 128 characters. Each character must be ASCII alphanumeric or one of the characters “-” / “.” / “_” / “~”.
Profile
Represents the canonically relevant fields of a profile response.
RedirectUrl
URL of the client’s redirection endpoint.
RefreshToken
Refresh token used to obtain a new access token (if supported by the authorization server).
ResponseType
Authorization endpoint response (grant) type defined in Section 3.1.1.
Scope
Access token scope, as defined by the authorization server.
Scopes
A representation of a list of scopes.
Token
Represents the canonically relevant fields of an access token.
TokenUrl
URL of the authorization server’s token endpoint.
VerifiedToken
Represents the canonically relevant fields of an verified token.

Enums§

DesiredResourceAuthorization
Describes the different kinds of authorization attempts supported by this client.
EndpointDiscovery
Represents the different kinds of discovery results one can find when looking for IndieAuth.
Error
Represents all of the known errors that can happen with IndieAuth.
Request
Different kinds of requests made with IndieAuth.
Response
Different kinds of responses made with IndieAuth.

Functions§

discover
Finds discovery information about a profile URL for IndieAuth.
ensure_discovery
is_loopback
Checks if the provided URL isn’t a loopback address.

Type Aliases§

ErrorResponse
Provides a structured response for OAuth2 failures.
OAuth2Client
Represents the OAuth 2 client that IndieAuth is based on.