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