unilim-cas 1.0.1

A purrfect CAS authentication wrapper for Unilim.
Documentation
use super::{OAuth2, PendingAuth};
use crate::Error;
use crate::native;
use url::Url;
use wasm_bindgen::prelude::*;

/// a cas session, the entry point to authentication.
#[wasm_bindgen]
pub struct CAS {
    inner: native::CAS,
}

impl From<native::CAS> for CAS {
    fn from(inner: native::CAS) -> Self {
        Self { inner }
    }
}

#[wasm_bindgen]
impl CAS {
    #[wasm_bindgen(constructor)]
    pub fn new(cookie: String, connection: String, key: String) -> CAS {
        native::CAS::new(cookie, connection, key).into()
    }

    /// `lemonldap` session cookie used to perform requests.
    #[wasm_bindgen(getter)]
    pub fn cookie(&self) -> String {
        self.inner.cookie.clone()
    }

    /// the `llngconnection` persistence cookie.
    #[wasm_bindgen(getter)]
    pub fn connection(&self) -> String {
        self.inner.connection.clone()
    }

    /// totp key generated by the persistence cookie.
    #[wasm_bindgen(getter)]
    pub fn key(&self) -> String {
        self.inner.key.clone()
    }

    /// start a new authentication and return a [`PendingAuth`] to solve 2fa.
    pub async fn initialize(username: String, password: String) -> Result<PendingAuth, Error> {
        native::CAS::initialize(&username, &password)
            .await
            .map(PendingAuth::from)
    }

    /// re-authenticate without solving 2fa, using a persistence cookie and key.
    pub async fn restore(
        username: String,
        password: String,
        llngconnection: String,
        key: String,
    ) -> Result<CAS, Error> {
        native::CAS::restore(&username, &password, &llngconnection, &key)
            .await
            .map(CAS::from)
    }

    /// use an existing `lemonldap` cookie for temporary access.
    pub fn temporary(cookie: String) -> CAS {
        native::CAS::temporary(cookie).into()
    }

    /// authorize through `/oauth2`, returning the callback url as a string.
    pub async fn authorize(
        &self,
        client: &OAuth2,
        challenge: Option<bool>,
        state: Option<String>,
    ) -> Result<String, Error> {
        self.inner
            .authorize(
                &client.inner,
                challenge.unwrap_or(false),
                state.as_deref().unwrap_or_default(),
            )
            .await
            .map(String::from)
    }

    /// authenticate to a `service`, returning the ticket url as a string.
    pub async fn service(&self, service: native::Services) -> Result<String, Error> {
        self.inner.service(service).await.map(String::from)
    }

    /// exchange the `code` of an authorized callback url for tokens.
    pub async fn tokenize(
        &self,
        callback: String,
        client: &OAuth2,
        challenge: Option<bool>,
    ) -> Result<native::Tokens, Error> {
        let callback = Url::parse(&callback)?;
        self.inner
            .tokenize(&callback, &client.inner, challenge.unwrap_or(false))
            .await
    }

    /// retrieve user information from the access token.
    pub async fn userinfo(&self, tokens: native::Tokens) -> Result<native::User, Error> {
        self.inner.userinfo(&tokens).await
    }
}