use crate::codec::host_service::{HostServiceChannel, connect_host_service, plain_channel};
use crate::codec::identity::{
from_wire_authorize_response, from_wire_get_grant_response, from_wire_introspect_response,
from_wire_list_grants_response, from_wire_revoke_grant_response, from_wire_token_response,
from_wire_user_info_response, to_wire_authorize_request, to_wire_get_grant_request,
to_wire_introspect_request, to_wire_list_grants_request, to_wire_revoke_grant_request,
to_wire_token_request, to_wire_user_info_request,
};
use crate::generated::v1;
use crate::rpc_support::GestaltError;
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizeRequest {
pub response_type: String,
pub client_id: String,
pub redirect_uri: String,
pub scope: String,
pub state: String,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizeResponse {
pub redirect_uri: String,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GetGrantRequest {
pub grant_id: String,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GetGrantResponse {
pub scopes: Vec<GrantScope>,
pub created_at: i64,
pub expires_at: i64,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GrantScope {
pub scope: String,
pub resource: Vec<String>,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct IntrospectRequest {
pub token: String,
pub token_type_hint: String,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct IntrospectResponse {
pub active: bool,
pub subject: String,
pub scope: String,
pub client_id: String,
pub audience: Vec<String>,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ListGrantsRequest {}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ListGrantsResponse {
pub grant_ids: Vec<String>,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RevokeGrantRequest {
pub grant_id: String,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RevokeGrantResponse {}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TokenRequest {
pub grant_type: String,
pub code: String,
pub redirect_uri: String,
pub client_id: String,
pub state: String,
pub scope: String,
pub subject_token: String,
pub subject_token_type: String,
pub expires_in: i64,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TokenResponse {
pub access_token: String,
pub token_type: String,
pub expires_in: i64,
pub refresh_token: String,
pub scope: String,
pub grant_id: String,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UserInfoRequest {}
#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UserInfoResponse {
pub subject_id: String,
pub email: String,
pub name: String,
}
pub struct Identity {
inner: v1::identity_client::IdentityClient<HostServiceChannel>,
timeout: Option<std::time::Duration>,
}
impl Identity {
pub fn new(channel: tonic::transport::Channel) -> Self {
Self {
inner: v1::identity_client::IdentityClient::new(plain_channel(channel)),
timeout: None,
}
}
pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub async fn connect() -> Result<Self, GestaltError> {
Self::connect_named("").await
}
pub async fn connect_named(name: &str) -> Result<Self, GestaltError> {
Ok(Self {
inner: v1::identity_client::IdentityClient::new(
connect_host_service("identity", name).await?,
),
timeout: None,
})
}
pub async fn authorize(
&mut self,
response_type: String,
client_id: String,
redirect_uri: String,
scope: String,
state: String,
) -> Result<AuthorizeResponse, GestaltError> {
let request = AuthorizeRequest {
response_type,
client_id,
redirect_uri,
scope,
state,
};
let mut tonic_request = tonic::Request::new(to_wire_authorize_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.authorize(tonic_request).await?;
Ok(from_wire_authorize_response(response.into_inner()))
}
pub async fn authorize_raw(
&mut self,
request: AuthorizeRequest,
) -> Result<AuthorizeResponse, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_authorize_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.authorize(tonic_request).await?;
Ok(from_wire_authorize_response(response.into_inner()))
}
#[allow(clippy::too_many_arguments)]
pub async fn token(
&mut self,
grant_type: String,
code: String,
redirect_uri: String,
client_id: String,
state: String,
scope: String,
subject_token: String,
subject_token_type: String,
options: IdentityTokenOptions,
) -> Result<TokenResponse, GestaltError> {
let request = TokenRequest {
grant_type,
code,
redirect_uri,
client_id,
state,
scope,
subject_token,
subject_token_type,
expires_in: options.expires_in,
};
let mut tonic_request = tonic::Request::new(to_wire_token_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.token(tonic_request).await?;
Ok(from_wire_token_response(response.into_inner()))
}
pub async fn token_raw(
&mut self,
request: TokenRequest,
) -> Result<TokenResponse, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_token_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.token(tonic_request).await?;
Ok(from_wire_token_response(response.into_inner()))
}
pub async fn introspect(
&mut self,
token: String,
token_type_hint: String,
) -> Result<IntrospectResponse, GestaltError> {
let request = IntrospectRequest {
token,
token_type_hint,
};
let mut tonic_request = tonic::Request::new(to_wire_introspect_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.introspect(tonic_request).await?;
Ok(from_wire_introspect_response(response.into_inner()))
}
pub async fn introspect_raw(
&mut self,
request: IntrospectRequest,
) -> Result<IntrospectResponse, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_introspect_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.introspect(tonic_request).await?;
Ok(from_wire_introspect_response(response.into_inner()))
}
pub async fn user_info(
&mut self,
request: UserInfoRequest,
) -> Result<UserInfoResponse, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_user_info_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.user_info(tonic_request).await?;
Ok(from_wire_user_info_response(response.into_inner()))
}
pub async fn list_grants(
&mut self,
request: ListGrantsRequest,
) -> Result<ListGrantsResponse, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_list_grants_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.list_grants(tonic_request).await?;
Ok(from_wire_list_grants_response(response.into_inner()))
}
pub async fn get_grant(&mut self, grant_id: String) -> Result<GetGrantResponse, GestaltError> {
let request = GetGrantRequest { grant_id };
let mut tonic_request = tonic::Request::new(to_wire_get_grant_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.get_grant(tonic_request).await?;
Ok(from_wire_get_grant_response(response.into_inner()))
}
pub async fn get_grant_raw(
&mut self,
request: GetGrantRequest,
) -> Result<GetGrantResponse, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_get_grant_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.get_grant(tonic_request).await?;
Ok(from_wire_get_grant_response(response.into_inner()))
}
pub async fn revoke_grant(
&mut self,
grant_id: String,
) -> Result<RevokeGrantResponse, GestaltError> {
let request = RevokeGrantRequest { grant_id };
let mut tonic_request = tonic::Request::new(to_wire_revoke_grant_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.revoke_grant(tonic_request).await?;
Ok(from_wire_revoke_grant_response(response.into_inner()))
}
pub async fn revoke_grant_raw(
&mut self,
request: RevokeGrantRequest,
) -> Result<RevokeGrantResponse, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_revoke_grant_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.revoke_grant(tonic_request).await?;
Ok(from_wire_revoke_grant_response(response.into_inner()))
}
}
#[derive(Clone, Debug, Default)]
pub struct IdentityTokenOptions {
pub expires_in: i64,
}