Initial commit

This commit is contained in:
Pal Kerecsenyi 2024-01-23 14:29:30 +00:00
commit 4c27d2f148
Signed by: palk
GPG Key ID: 6891661E25394C2C
7 changed files with 1307 additions and 0 deletions

2
.gitignore vendored Normal file

@ -0,0 +1,2 @@
/target
.env

1181
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

14
Cargo.toml Normal file

@ -0,0 +1,14 @@
[package]
name = "palauth-iam-rust"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
reqwest = { version = "0.11", features = ["json"] }
url = { version = "2.5.0", features = ["serde"] }
serde = { version = "1.0.195" }
[dev-dependencies]
tokio = { version = "1", features = ["full"] }

101
src/client.rs Normal file

@ -0,0 +1,101 @@
use std::error::Error;
use reqwest::Url;
use serde::de::DeserializeOwned;
use crate::routes::check::CheckPermissionResponse;
#[derive(Debug, Clone)]
pub struct PalAuthIAMClient {
client_id: String,
client_secret: String,
base_url: String,
}
impl PalAuthIAMClient {
pub fn new(client_id: String, client_secret: String) -> PalAuthIAMClient {
PalAuthIAMClient {
client_id,
client_secret,
base_url: "https://auth.palk.me/iam".to_string(),
}
}
pub fn set_base_url(&mut self, base_url: String) {
self.base_url = base_url;
}
fn build_path(&self, path: &str) -> Result<Url, Box<dyn Error>> {
let mut url = Url::parse(self.base_url.as_str())?;
let mut path_segments: Vec<&str> = url.path_segments().ok_or("cannot be base")?.collect();
path_segments.extend(&[self.client_id.as_str(), path]);
url.set_path(&path_segments.join("/"));
Ok(url)
}
async fn get_request<R: DeserializeOwned>(&self, url: Url) -> Result<R, Box<dyn Error>> {
let client = reqwest::Client::new();
let resp = client
.get(url)
.bearer_auth(self.client_secret.clone())
.send()
.await?
.json::<R>()
.await?;
Ok(resp)
}
pub async fn check_permission(
&self,
user_id: &str,
permission_name: &str,
) -> Result<CheckPermissionResponse, Box<dyn Error>> {
let mut url = self.build_path("/check")?;
url.query_pairs_mut()
.append_pair("userId", user_id)
.append_pair("permission", permission_name);
let response = self.get_request::<CheckPermissionResponse>(url).await?;
Ok(response)
}
}
#[cfg(test)]
mod tests {
use std::env;
use super::*;
#[test]
fn create_client() {
let mut client = PalAuthIAMClient::new("abc".to_string(), "xyz".to_string());
assert_eq!(client.client_id, "abc");
assert_eq!(client.client_secret, "xyz");
assert_eq!(client.base_url, "https://auth.palk.me/iam");
client.set_base_url("https://example.com".to_string());
assert_eq!(client.base_url, "https://example.com");
}
#[tokio::test]
async fn check_permission() {
let client_id = env::var("PAL_CLIENT_ID").expect("no PAL_CLIENT_ID provided");
let client_secret = env::var("PAL_CLIENT_SECRET").expect("no PAL_CLIENT_SECRET provided");
let client = PalAuthIAMClient::new(client_id, client_secret);
let user_id = env::var("PAL_USER_ID").expect("no PAL_USER_ID provided");
let resp1 = client
.check_permission(user_id.as_str(), "cookies.create")
.await
.expect("request failed!");
assert_eq!(resp1.allowed, true);
let resp2 = client
.check_permission(user_id.as_str(), "cookies.eat")
.await
.expect("request failed!");
assert_eq!(resp2.allowed, false);
}
}

2
src/lib.rs Normal file

@ -0,0 +1,2 @@
pub mod client;
pub mod routes;

6
src/routes/check.rs Normal file

@ -0,0 +1,6 @@
use serde::Deserialize;
#[derive(Debug, Deserialize, Clone)]
pub struct CheckPermissionResponse {
pub allowed: bool
}

1
src/routes/mod.rs Normal file

@ -0,0 +1 @@
pub mod check;