picox/src/model/api_key.rs

84 lines
1.9 KiB
Rust

use base64::Engine;
use j_db::database::Database;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use bitflags::bitflags;
use rand::RngCore;
use sha2::Digest;
bitflags! {
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ApiPermissions: u32 {
const WRITE = 0b00000001;
const DELETE = 0b00000010;
}
}
impl FromStr for ApiPermissions {
type Err = bitflags::parser::ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
bitflags::parser::from_str(s)
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ApiKey {
pub token_hash: String,
pub description: String,
pub permissions: ApiPermissions,
id: Option<u64>,
}
impl ApiKey {
pub fn create_new_key(
db: &Database,
description: String,
permissions: ApiPermissions,
) -> Result<(Vec<u8>, ApiKey), j_db::error::JDbError> {
let mut key = [0u8; 32];
rand::thread_rng().fill_bytes(&mut key);
let hash = sha2::Sha256::digest(key);
let api_key = ApiKey {
token_hash: base64::prelude::BASE64_STANDARD.encode(hash),
description,
permissions,
id: None,
};
let api_key = db.insert(api_key)?;
Ok((key.to_vec(), api_key))
}
pub fn find_api_key_by_token(
db: &Database,
token: &str,
) -> Result<Option<ApiKey>, j_db::error::JDbError> {
let token = base64::prelude::BASE64_STANDARD.decode(token).unwrap();
let hash = sha2::Sha256::digest(token);
let hash = base64::prelude::BASE64_STANDARD.encode(hash);
Ok(db
.filter(move |_, api_key: &ApiKey| api_key.token_hash == hash)?
.next())
}
}
impl j_db::model::JdbModel for ApiKey {
fn id(&self) -> Option<u64> {
self.id
}
fn set_id(&mut self, id: u64) {
self.id = Some(id);
}
fn tree() -> String {
"ApiKey".to_string()
}
}