Skip to content

Commit

Permalink
Refactor libiam (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
smrtrfszm committed Jul 10, 2024
1 parent a6c7e61 commit 0d1b096
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 148 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libiam/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ tokio = { version = "1.25.0", features = ["rt"] }
futures = "0.3.26"
async-trait = "0.1.64"
jsonwebtoken = "9.1.0"
anyhow = "1.0.86"
22 changes: 22 additions & 0 deletions libiam/src/api/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use super::Api;
use anyhow::Result;
use reqwest::Method;
use serde::{Deserialize, Serialize};

pub mod login {
use super::*;

#[derive(Debug, Serialize)]
pub struct Request<'a> {
pub token: &'a str,
}

#[derive(Debug, Deserialize)]
pub struct Response {
pub token: String,
}
}

pub async fn login(api: &Api, req: &login::Request<'_>) -> Result<login::Response> {
api.request(Method::POST, "/v1/apps/login", Some(req)).await
}
86 changes: 86 additions & 0 deletions libiam/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
pub mod app;
pub mod user;

use reqwest::{header::AUTHORIZATION, Client, Method, Url};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use thiserror::Error;
use tokio::runtime::Handle;

#[derive(Debug)]
pub struct Api {
client: Client,
base: Url,
handle: Handle,
token: Option<String>,
}

impl Api {
pub fn new(base: &str, token: Option<String>) -> anyhow::Result<Self> {
Ok(Self {
client: Client::new(),
base: Url::parse(base)?,
handle: Handle::current(),
token,
})
}

pub fn with_token(&self, token: String) -> Self {
Self {
client: self.client.clone(),
base: self.base.clone(),
handle: self.handle.clone(),
token: Some(token),
}
}

#[inline]
async fn request<Req, Res>(
&self,
method: Method,
path: &str,
req: Option<&Req>,
) -> anyhow::Result<Res>
where
Req: Serialize,
Res: DeserializeOwned + Send + 'static,
{
let mut r = self.client.request(method, self.base.join(path).unwrap());

if let Some(token) = &self.token {
r = r.header(AUTHORIZATION, &format!("Bearer {}", token));
}

if let Some(req) = req {
r = r.json(req)
}

self.handle
.spawn(async move {
let res: ErrorOr<Res> = r.send().await?.json().await?;

match res {
ErrorOr::Error(error) => {
tracing::error!("iam error: {error:?}");
Err(error.into())
}
ErrorOr::Data(res) => anyhow::Ok(res),
}
})
.await
.unwrap()
}
}

#[derive(Debug, Deserialize, Error)]
#[error("{error}")]
pub struct Error {
pub code: String,
pub error: String,
}

#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum ErrorOr<T> {
Error(Error),
Data(T),
}
56 changes: 56 additions & 0 deletions libiam/src/api/user.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use super::Api;
use anyhow::Result;
use reqwest::Method;
use serde::{Deserialize, Serialize};

pub mod register {
use super::*;

#[derive(Debug, Serialize)]
pub struct Request<'a> {
pub name: &'a str,
pub email: &'a str,
pub password: &'a str,
}

#[derive(Debug, Deserialize)]
pub struct Response {
pub id: String,
}
}

pub async fn register(api: &Api, req: &register::Request<'_>) -> Result<register::Response> {
api.request(Method::POST, "/v1/users/register", Some(req))
.await
}

pub mod login {
use super::*;

#[derive(Debug, Serialize)]
pub struct Request<'a> {
pub email: &'a str,
pub password: &'a str,
}

#[derive(Debug, Deserialize)]
pub struct Response {
pub token: String,
}
}

pub async fn login(api: &Api, req: &login::Request<'_>) -> Result<login::Response> {
api.request(Method::POST, "/v1/users/login", Some(req))
.await
}

pub mod get_user {
use iam_common::user::UserInfo;

pub type Response = UserInfo;
}

pub async fn get_user(api: &Api, id: &str) -> Result<get_user::Response> {
api.request(Method::GET, &format!("/v1/users/{id}"), None::<&()>)
.await
}
59 changes: 11 additions & 48 deletions libiam/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
use std::sync::Arc;

use iam_common::user::UserInfo;
use reqwest::Client;
use serde::Deserialize;
use serde_json::json;

use crate::{
error::{unwrap_res, ErrorMessage, Result},
utils::{create_client, Either},
api::{self, Api},
Iam,
};
use iam_common::user::UserInfo;
use std::sync::Arc;

#[derive(Debug)]
pub struct AppInner {
secret: String,
token: String,
iam: Iam,
client: Client,
api: Api,
}

#[derive(Debug, Clone)]
Expand All @@ -25,41 +18,20 @@ pub struct App {
}

impl App {
pub async fn login(iam: &Iam, secret: &str) -> Result<Self> {
#[derive(Debug, Deserialize)]
struct Response {
token: String,
}

tracing::debug!(secret, "app logging into iam");

let res = Client::new()
.post(iam.get_url("/v1/apps/login"))
.json(&json!({
"token": secret,
}))
.send()
pub async fn login(iam: &Iam, secret: &str) -> anyhow::Result<Self> {
let token = api::app::login(&iam.inner.api, &api::app::login::Request { token: secret })
.await?
.json::<Either<Response, ErrorMessage>>()
.await?;

let res = unwrap_res(res)?;
.token;

Ok(Self {
inner: Arc::new(AppInner {
secret: secret.to_owned(),
client: create_client(&res.token),
token: res.token,
iam: iam.clone(),
token: token.clone(),
api: iam.inner.api.with_token(token),
}),
})
}

#[inline]
fn client(&self) -> &Client {
&self.inner.client
}

pub fn token(&self) -> &str {
&self.inner.token
}
Expand All @@ -69,17 +41,8 @@ impl App {
id
}

pub async fn get_user_info(&self, id: &str) -> Result<UserInfo> {
let res = self
.client()
.get(self.inner.iam.get_url(&format!("/v1/users/{}/", id)))
.send()
.await?
.json::<Either<UserInfo, ErrorMessage>>()
.await?;

let res = unwrap_res(res)?;

pub async fn get_user_info(&self, id: &str) -> anyhow::Result<UserInfo> {
let res = api::user::get_user(&self.inner.api, id).await?;
Ok(res)
}
}
30 changes: 0 additions & 30 deletions libiam/src/error.rs

This file was deleted.

12 changes: 6 additions & 6 deletions libiam/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
pub mod api;
mod app;
mod error;
pub mod testing;
mod user;
mod utils;

use api::Api;
use std::sync::Arc;

pub use app::App;
Expand All @@ -12,7 +12,7 @@ pub use user::User;

#[derive(Debug)]
pub struct IamInner {
base_url: String,
api: Api,
}

#[derive(Debug, Clone)]
Expand All @@ -24,12 +24,12 @@ impl Iam {
pub fn new(base_url: &str) -> Self {
Self {
inner: Arc::new(IamInner {
base_url: base_url.to_owned(),
api: Api::new(base_url, None).unwrap(),
}),
}
}

pub(crate) fn get_url(&self, path: &str) -> String {
format!("{}{}", self.inner.base_url, path)
pub fn api(&self) -> &Api {
&self.inner.api
}
}
Loading

0 comments on commit 0d1b096

Please sign in to comment.