initial commit
This commit is contained in:
commit
14f1c54575
|
@ -0,0 +1,4 @@
|
||||||
|
.idea
|
||||||
|
|
||||||
|
/target
|
||||||
|
/Cargo.lock
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "nerdcult-sdk"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.75"
|
||||||
|
thiserror = "1.0.50"
|
||||||
|
serde = { version = "1.0.190", features = ["derive"] }
|
||||||
|
serde_json = "1.0.108"
|
||||||
|
reqwest = { version = "0.11.22", features = ["json"] }
|
|
@ -0,0 +1,25 @@
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum AuthError {
|
||||||
|
#[error("Failed to authenticate: the API complains about a malformed request")]
|
||||||
|
BadRequest,
|
||||||
|
|
||||||
|
#[error("Failed to authenticate: unprocessable API response")]
|
||||||
|
BadResponse,
|
||||||
|
|
||||||
|
#[error("Failed to authenticate: failed to send request")]
|
||||||
|
RequestSend(reqwest::Error),
|
||||||
|
|
||||||
|
#[error("Failed to authenticate: blocked for security reasons")]
|
||||||
|
Forbidden,
|
||||||
|
|
||||||
|
#[error("Failed to authenticate: wrong password")]
|
||||||
|
WrongPassword,
|
||||||
|
|
||||||
|
#[error("Failed to authenticate: account not found")]
|
||||||
|
NotFound,
|
||||||
|
|
||||||
|
#[error("Failed to authenticate: account not verified")]
|
||||||
|
NotVerified,
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
mod error;
|
||||||
|
pub mod request;
|
||||||
|
pub mod response;
|
||||||
|
|
||||||
|
use crate::{error::AuthError, request::AccountAuthenticate};
|
||||||
|
use anyhow::Result;
|
||||||
|
use reqwest::StatusCode;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Session {
|
||||||
|
base_url: String,
|
||||||
|
auth_token: Option<String>,
|
||||||
|
client: reqwest::Client,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Session {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
base_url: "https://api.nerdcult.net".to_string(),
|
||||||
|
auth_token: None,
|
||||||
|
client: reqwest::Client::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Session {
|
||||||
|
pub fn with_base_url(base_url: String) -> Self {
|
||||||
|
Self {
|
||||||
|
base_url,
|
||||||
|
auth_token: None,
|
||||||
|
client: reqwest::Client::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn authenticate(
|
||||||
|
&mut self,
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
) -> Result<(), AuthError> {
|
||||||
|
let url = format!("{}/account/authenticate", &self.base_url);
|
||||||
|
|
||||||
|
let body = AccountAuthenticate { username, password };
|
||||||
|
|
||||||
|
let request = self.client.post(&url).json(&body);
|
||||||
|
let response = request
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|e| AuthError::RequestSend(e))?;
|
||||||
|
|
||||||
|
match response.status() {
|
||||||
|
StatusCode::OK => {
|
||||||
|
self.auth_token = Some(
|
||||||
|
response
|
||||||
|
.json::<response::AccountAuthenticateResponse>()
|
||||||
|
.await
|
||||||
|
.map_err(|_| AuthError::BadResponse)?
|
||||||
|
.token,
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
StatusCode::BAD_REQUEST => Err(AuthError::BadRequest),
|
||||||
|
StatusCode::UNAUTHORIZED => Err(AuthError::WrongPassword),
|
||||||
|
StatusCode::FORBIDDEN => Err(AuthError::Forbidden),
|
||||||
|
StatusCode::NOT_FOUND => Err(AuthError::NotFound),
|
||||||
|
StatusCode::FAILED_DEPENDENCY => Err(AuthError::NotVerified),
|
||||||
|
_ => Err(AuthError::BadResponse),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_authenticated(&self) -> bool {
|
||||||
|
self.auth_token.is_some()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Clone)]
|
||||||
|
pub struct AccountAuthenticate {
|
||||||
|
pub username: String,
|
||||||
|
pub password: String,
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
|
pub struct AccountAuthenticateResponse {
|
||||||
|
pub token: String,
|
||||||
|
}
|
Loading…
Reference in New Issue