mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-07-03 03:47:02 +02:00
chore: get rid of chrono in favor of time
Chrono has been unmaintened for a few month now and there is a CVE on it. make clippy happy bump milli
This commit is contained in:
parent
216965e9d9
commit
05c8d81e65
33 changed files with 369 additions and 226 deletions
|
@ -10,13 +10,13 @@ pub type Result<T> = std::result::Result<T, AuthControllerError>;
|
|||
pub enum AuthControllerError {
|
||||
#[error("`{0}` field is mandatory.")]
|
||||
MissingParameter(&'static str),
|
||||
#[error("actions field value `{0}` is invalid. It should be an array of string representing action names.")]
|
||||
#[error("`actions` field value `{0}` is invalid. It should be an array of string representing action names.")]
|
||||
InvalidApiKeyActions(Value),
|
||||
#[error("indexes field value `{0}` is invalid. It should be an array of string representing index names.")]
|
||||
#[error("`indexes` field value `{0}` is invalid. It should be an array of string representing index names.")]
|
||||
InvalidApiKeyIndexes(Value),
|
||||
#[error("expiresAt field value `{0}` is invalid. It should be in ISO-8601 format to represents a date or datetime in the future or specified as a null value. e.g. 'YYYY-MM-DD' or 'YYYY-MM-DDTHH:MM:SS'.")]
|
||||
#[error("`expiresAt` field value `{0}` is invalid. It should follow the RFC 3339 format to represents a date or datetime in the future or specified as a null value. e.g. 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'.")]
|
||||
InvalidApiKeyExpiresAt(Value),
|
||||
#[error("description field value `{0}` is invalid. It should be a string or specified as a null value.")]
|
||||
#[error("`description` field value `{0}` is invalid. It should be a string or specified as a null value.")]
|
||||
InvalidApiKeyDescription(Value),
|
||||
#[error("API key `{0}` not found.")]
|
||||
ApiKeyNotFound(String),
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
use crate::action::Action;
|
||||
use crate::error::{AuthControllerError, Result};
|
||||
use crate::store::{KeyId, KEY_ID_LENGTH};
|
||||
use chrono::{DateTime, NaiveDate, NaiveDateTime, Utc};
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{from_value, Value};
|
||||
use time::format_description::well_known::Rfc3339;
|
||||
use time::macros::{format_description, time};
|
||||
use time::{Date, OffsetDateTime, PrimitiveDateTime};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Key {
|
||||
|
@ -13,9 +15,12 @@ pub struct Key {
|
|||
pub id: KeyId,
|
||||
pub actions: Vec<Action>,
|
||||
pub indexes: Vec<String>,
|
||||
pub expires_at: Option<DateTime<Utc>>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
#[serde(with = "time::serde::rfc3339::option")]
|
||||
pub expires_at: Option<OffsetDateTime>,
|
||||
#[serde(with = "time::serde::rfc3339")]
|
||||
pub created_at: OffsetDateTime,
|
||||
#[serde(with = "time::serde::rfc3339")]
|
||||
pub updated_at: OffsetDateTime,
|
||||
}
|
||||
|
||||
impl Key {
|
||||
|
@ -52,8 +57,8 @@ impl Key {
|
|||
.map(parse_expiration_date)
|
||||
.ok_or(AuthControllerError::MissingParameter("expiresAt"))??;
|
||||
|
||||
let created_at = Utc::now();
|
||||
let updated_at = Utc::now();
|
||||
let created_at = OffsetDateTime::now_utc();
|
||||
let updated_at = created_at;
|
||||
|
||||
Ok(Self {
|
||||
description,
|
||||
|
@ -89,24 +94,26 @@ impl Key {
|
|||
self.expires_at = parse_expiration_date(exp)?;
|
||||
}
|
||||
|
||||
self.updated_at = Utc::now();
|
||||
self.updated_at = OffsetDateTime::now_utc();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn default_admin() -> Self {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
Self {
|
||||
description: Some("Default Admin API Key (Use it for all other operations. Caution! Do not use it on a public frontend)".to_string()),
|
||||
id: generate_id(),
|
||||
actions: vec![Action::All],
|
||||
indexes: vec!["*".to_string()],
|
||||
expires_at: None,
|
||||
created_at: Utc::now(),
|
||||
updated_at: Utc::now(),
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn default_search() -> Self {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
Self {
|
||||
description: Some(
|
||||
"Default Search API Key (Use it to search from the frontend)".to_string(),
|
||||
|
@ -115,8 +122,8 @@ impl Key {
|
|||
actions: vec![Action::Search],
|
||||
indexes: vec!["*".to_string()],
|
||||
expires_at: None,
|
||||
created_at: Utc::now(),
|
||||
updated_at: Utc::now(),
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,22 +141,34 @@ fn generate_id() -> [u8; KEY_ID_LENGTH] {
|
|||
bytes
|
||||
}
|
||||
|
||||
fn parse_expiration_date(value: &Value) -> Result<Option<DateTime<Utc>>> {
|
||||
fn parse_expiration_date(value: &Value) -> Result<Option<OffsetDateTime>> {
|
||||
match value {
|
||||
Value::String(string) => DateTime::parse_from_rfc3339(string)
|
||||
.map(|d| d.into())
|
||||
Value::String(string) => OffsetDateTime::parse(string, &Rfc3339)
|
||||
.or_else(|_| {
|
||||
NaiveDateTime::parse_from_str(string, "%Y-%m-%dT%H:%M:%S")
|
||||
.map(|naive| DateTime::from_utc(naive, Utc))
|
||||
PrimitiveDateTime::parse(
|
||||
string,
|
||||
format_description!(
|
||||
"[year repr:full base:calendar]-[month repr:numerical]-[day]T[hour]:[minute]:[second]"
|
||||
),
|
||||
).map(|datetime| datetime.assume_utc())
|
||||
})
|
||||
.or_else(|_| {
|
||||
NaiveDate::parse_from_str(string, "%Y-%m-%d")
|
||||
.map(|naive| DateTime::from_utc(naive.and_hms(0, 0, 0), Utc))
|
||||
PrimitiveDateTime::parse(
|
||||
string,
|
||||
format_description!(
|
||||
"[year repr:full base:calendar]-[month repr:numerical]-[day] [hour]:[minute]:[second]"
|
||||
),
|
||||
).map(|datetime| datetime.assume_utc())
|
||||
})
|
||||
.or_else(|_| {
|
||||
Date::parse(string, format_description!(
|
||||
"[year repr:full base:calendar]-[month repr:numerical]-[day]"
|
||||
)).map(|date| PrimitiveDateTime::new(date, time!(00:00)).assume_utc())
|
||||
})
|
||||
.map_err(|_| AuthControllerError::InvalidApiKeyExpiresAt(value.clone()))
|
||||
// check if the key is already expired.
|
||||
.and_then(|d| {
|
||||
if d > Utc::now() {
|
||||
if d > OffsetDateTime::now_utc() {
|
||||
Ok(d)
|
||||
} else {
|
||||
Err(AuthControllerError::InvalidApiKeyExpiresAt(value.clone()))
|
||||
|
|
|
@ -9,10 +9,10 @@ use std::path::Path;
|
|||
use std::str::from_utf8;
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::Utc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use sha2::{Digest, Sha256};
|
||||
use time::OffsetDateTime;
|
||||
|
||||
pub use action::{actions, Action};
|
||||
use error::{AuthControllerError, Result};
|
||||
|
@ -148,7 +148,7 @@ impl AuthController {
|
|||
None => self.store.prefix_first_expiration_date(key, action)?,
|
||||
}) {
|
||||
// check expiration date.
|
||||
Some(Some(exp)) => Ok(Utc::now() < exp),
|
||||
Some(Some(exp)) => Ok(OffsetDateTime::now_utc() < exp),
|
||||
// no expiration date.
|
||||
Some(None) => Ok(true),
|
||||
// action or index forbidden.
|
||||
|
|
|
@ -8,9 +8,9 @@ use std::path::Path;
|
|||
use std::str;
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use heed::types::{ByteSlice, DecodeIgnore, SerdeJson};
|
||||
use heed::{Database, Env, EnvOpenOptions, RwTxn};
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use super::error::Result;
|
||||
use super::{Action, Key};
|
||||
|
@ -27,7 +27,7 @@ pub type KeyId = [u8; KEY_ID_LENGTH];
|
|||
pub struct HeedAuthStore {
|
||||
env: Arc<Env>,
|
||||
keys: Database<ByteSlice, SerdeJson<Key>>,
|
||||
action_keyid_index_expiration: Database<KeyIdActionCodec, SerdeJson<Option<DateTime<Utc>>>>,
|
||||
action_keyid_index_expiration: Database<KeyIdActionCodec, SerdeJson<Option<OffsetDateTime>>>,
|
||||
should_close_on_drop: bool,
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ impl HeedAuthStore {
|
|||
key: &[u8],
|
||||
action: Action,
|
||||
index: Option<&[u8]>,
|
||||
) -> Result<Option<Option<DateTime<Utc>>>> {
|
||||
) -> Result<Option<Option<OffsetDateTime>>> {
|
||||
let rtxn = self.env.read_txn()?;
|
||||
match self.get_key_id(key) {
|
||||
Some(id) => {
|
||||
|
@ -161,7 +161,7 @@ impl HeedAuthStore {
|
|||
&self,
|
||||
key: &[u8],
|
||||
action: Action,
|
||||
) -> Result<Option<Option<DateTime<Utc>>>> {
|
||||
) -> Result<Option<Option<OffsetDateTime>>> {
|
||||
let rtxn = self.env.read_txn()?;
|
||||
match self.get_key_id(key) {
|
||||
Some(id) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue