saas-rs-sdk 0.6.3

The SaaS RS SDK
use crate::authentication::IdentityProviderHandler;
use async_trait::async_trait;
use http_api_isahc_client::IsahcClient;
use oauth2_client::extensions::{
    AccessTokenResponseSuccessfulBody, Builder, BuilderObtainUserInfoError, BuilderObtainUserInfoOutput, GrantInfo,
};
use oauth2_client::re_exports::{ClientId, ClientSecret, RedirectUri, Scope};
use oauth2_okta::{OktaProviderForWebApplication, OktaScope};
use oauth2_signin::web_app::{SigninFlow, SigninFlowHandleCallbackByQueryConfiguration, SigninFlowHandleCallbackRet};

pub use oauth2_okta;

pub const OKTA_AUTHORIZATION_SERVER_ID: &str = "OKTA_AUTHORIZATION_SERVER_ID";
pub const OKTA_DOMAIN: &str = "OKTA_DOMAIN";

#[derive(Default)]
pub struct OktaIdentityProviderHandler {}

#[async_trait]
impl IdentityProviderHandler for OktaIdentityProviderHandler {
    async fn handle_callback(
        &self,
        client_id: ClientId,
        client_secret: ClientSecret,
        redirect_uri: RedirectUri,
        query: String,
    ) -> Result<SigninFlowHandleCallbackRet, Box<dyn std::error::Error>> {
        let client = IsahcClient::new()?;
        let domain = std::env::var(OKTA_DOMAIN)?;
        let authorization_server_id = std::env::var(OKTA_DOMAIN).ok();
        let provider = OktaProviderForWebApplication::new(
            domain,
            authorization_server_id,
            client_id,
            client_secret,
            redirect_uri,
        )?;
        let scopes = vec![OktaScope::Email, OktaScope::Openid];
        let flow = SigninFlow::new(client, provider, scopes, OktaExtensionsBuilder);
        let config = SigninFlowHandleCallbackByQueryConfiguration::new();
        Ok(flow.handle_callback_by_query(query, config).await)
    }
}

#[derive(Clone, Debug)]
struct OktaExtensionsBuilder;

impl<SCOPE> Builder<SCOPE> for OktaExtensionsBuilder
where
    SCOPE: Scope,
{
    fn obtain_user_info(
        &self,
        _grant_info: GrantInfo<SCOPE>,
        _access_token: &AccessTokenResponseSuccessfulBody<SCOPE>,
    ) -> Result<BuilderObtainUserInfoOutput, BuilderObtainUserInfoError> {
        Ok(BuilderObtainUserInfoOutput::None)
    }
}