mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
fix(users): preserve nullable rate limit updates
This commit is contained in:
@@ -882,6 +882,7 @@ impl UserReadRepository for InMemoryUserReadRepository {
|
|||||||
allowed_api_formats: Option<Vec<String>>,
|
allowed_api_formats: Option<Vec<String>>,
|
||||||
allowed_models_present: bool,
|
allowed_models_present: bool,
|
||||||
allowed_models: Option<Vec<String>>,
|
allowed_models: Option<Vec<String>>,
|
||||||
|
rate_limit_present: bool,
|
||||||
rate_limit: Option<i32>,
|
rate_limit: Option<i32>,
|
||||||
is_active: Option<bool>,
|
is_active: Option<bool>,
|
||||||
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
||||||
@@ -931,8 +932,8 @@ impl UserReadRepository for InMemoryUserReadRepository {
|
|||||||
row.allowed_providers = updated.allowed_providers.clone();
|
row.allowed_providers = updated.allowed_providers.clone();
|
||||||
row.allowed_api_formats = updated.allowed_api_formats.clone();
|
row.allowed_api_formats = updated.allowed_api_formats.clone();
|
||||||
row.allowed_models = updated.allowed_models.clone();
|
row.allowed_models = updated.allowed_models.clone();
|
||||||
if let Some(rate_limit) = rate_limit {
|
if rate_limit_present {
|
||||||
row.rate_limit = Some(rate_limit);
|
row.rate_limit = rate_limit;
|
||||||
}
|
}
|
||||||
row.is_active = updated.is_active;
|
row.is_active = updated.is_active;
|
||||||
}
|
}
|
||||||
@@ -1518,7 +1519,24 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.expect("auth user should build");
|
.expect("auth user should build");
|
||||||
let repository = InMemoryUserReadRepository::seed_auth_users(vec![user]);
|
let export_user = StoredUserExportRow::new(
|
||||||
|
"user-1".to_string(),
|
||||||
|
Some("alice@example.com".to_string()),
|
||||||
|
true,
|
||||||
|
"alice".to_string(),
|
||||||
|
Some("old-hash".to_string()),
|
||||||
|
"user".to_string(),
|
||||||
|
"local".to_string(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Some(10),
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.expect("export user should build");
|
||||||
|
let repository = InMemoryUserReadRepository::seed_auth_users(vec![user])
|
||||||
|
.with_export_users([export_user]);
|
||||||
|
|
||||||
let updated = repository
|
let updated = repository
|
||||||
.update_local_auth_user_profile(
|
.update_local_auth_user_profile(
|
||||||
@@ -1566,6 +1584,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
true,
|
true,
|
||||||
Some(vec!["gpt-4.1".to_string()]),
|
Some(vec!["gpt-4.1".to_string()]),
|
||||||
|
true,
|
||||||
Some(50),
|
Some(50),
|
||||||
Some(false),
|
Some(false),
|
||||||
)
|
)
|
||||||
@@ -1583,6 +1602,31 @@ mod tests {
|
|||||||
Some(vec!["gpt-4.1".to_string()])
|
Some(vec!["gpt-4.1".to_string()])
|
||||||
);
|
);
|
||||||
assert!(!admin_updated.is_active);
|
assert!(!admin_updated.is_active);
|
||||||
|
assert_eq!(
|
||||||
|
repository
|
||||||
|
.find_export_user_by_id("user-1")
|
||||||
|
.await
|
||||||
|
.expect("export lookup should succeed")
|
||||||
|
.expect("export row should exist")
|
||||||
|
.rate_limit,
|
||||||
|
Some(50)
|
||||||
|
);
|
||||||
|
repository
|
||||||
|
.update_local_auth_user_admin_fields(
|
||||||
|
"user-1", None, false, None, false, None, false, None, true, None, None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("rate limit clear should succeed")
|
||||||
|
.expect("rate limit clear should return user");
|
||||||
|
assert_eq!(
|
||||||
|
repository
|
||||||
|
.find_export_user_by_id("user-1")
|
||||||
|
.await
|
||||||
|
.expect("export lookup should succeed")
|
||||||
|
.expect("export row should exist")
|
||||||
|
.rate_limit,
|
||||||
|
None
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
repository
|
repository
|
||||||
.update_user_model_capability_settings(
|
.update_user_model_capability_settings(
|
||||||
|
|||||||
@@ -655,6 +655,7 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|||||||
allowed_api_formats: Option<Vec<String>>,
|
allowed_api_formats: Option<Vec<String>>,
|
||||||
allowed_models_present: bool,
|
allowed_models_present: bool,
|
||||||
allowed_models: Option<Vec<String>>,
|
allowed_models: Option<Vec<String>>,
|
||||||
|
rate_limit_present: bool,
|
||||||
rate_limit: Option<i32>,
|
rate_limit: Option<i32>,
|
||||||
is_active: Option<bool>,
|
is_active: Option<bool>,
|
||||||
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
||||||
@@ -688,7 +689,7 @@ WHERE id = ?
|
|||||||
allowed_models,
|
allowed_models,
|
||||||
"users.allowed_models",
|
"users.allowed_models",
|
||||||
)?)
|
)?)
|
||||||
.bind(rate_limit.is_some())
|
.bind(rate_limit_present)
|
||||||
.bind(rate_limit)
|
.bind(rate_limit)
|
||||||
.bind(is_active.is_some())
|
.bind(is_active.is_some())
|
||||||
.bind(is_active)
|
.bind(is_active)
|
||||||
|
|||||||
@@ -1107,6 +1107,7 @@ WHERE id = $1
|
|||||||
allowed_api_formats: Option<Vec<String>>,
|
allowed_api_formats: Option<Vec<String>>,
|
||||||
allowed_models_present: bool,
|
allowed_models_present: bool,
|
||||||
allowed_models: Option<Vec<String>>,
|
allowed_models: Option<Vec<String>>,
|
||||||
|
rate_limit_present: bool,
|
||||||
rate_limit: Option<i32>,
|
rate_limit: Option<i32>,
|
||||||
is_active: Option<bool>,
|
is_active: Option<bool>,
|
||||||
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
||||||
@@ -1130,7 +1131,7 @@ SET role = CASE
|
|||||||
ELSE allowed_models
|
ELSE allowed_models
|
||||||
END,
|
END,
|
||||||
rate_limit = CASE
|
rate_limit = CASE
|
||||||
WHEN $10::BOOLEAN AND $11 IS NOT NULL THEN $11
|
WHEN $10::BOOLEAN THEN $11
|
||||||
ELSE rate_limit
|
ELSE rate_limit
|
||||||
END,
|
END,
|
||||||
is_active = CASE
|
is_active = CASE
|
||||||
@@ -1150,7 +1151,7 @@ WHERE id = $1
|
|||||||
.bind(allowed_api_formats.map(serde_json::Value::from))
|
.bind(allowed_api_formats.map(serde_json::Value::from))
|
||||||
.bind(allowed_models_present)
|
.bind(allowed_models_present)
|
||||||
.bind(allowed_models.map(serde_json::Value::from))
|
.bind(allowed_models.map(serde_json::Value::from))
|
||||||
.bind(rate_limit.is_some())
|
.bind(rate_limit_present)
|
||||||
.bind(rate_limit)
|
.bind(rate_limit)
|
||||||
.bind(is_active.is_some())
|
.bind(is_active.is_some())
|
||||||
.bind(is_active)
|
.bind(is_active)
|
||||||
@@ -1882,6 +1883,7 @@ impl UserReadRepository for SqlxUserReadRepository {
|
|||||||
allowed_api_formats: Option<Vec<String>>,
|
allowed_api_formats: Option<Vec<String>>,
|
||||||
allowed_models_present: bool,
|
allowed_models_present: bool,
|
||||||
allowed_models: Option<Vec<String>>,
|
allowed_models: Option<Vec<String>>,
|
||||||
|
rate_limit_present: bool,
|
||||||
rate_limit: Option<i32>,
|
rate_limit: Option<i32>,
|
||||||
is_active: Option<bool>,
|
is_active: Option<bool>,
|
||||||
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
||||||
@@ -1894,6 +1896,7 @@ impl UserReadRepository for SqlxUserReadRepository {
|
|||||||
allowed_api_formats,
|
allowed_api_formats,
|
||||||
allowed_models_present,
|
allowed_models_present,
|
||||||
allowed_models,
|
allowed_models,
|
||||||
|
rate_limit_present,
|
||||||
rate_limit,
|
rate_limit,
|
||||||
is_active,
|
is_active,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -655,6 +655,7 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|||||||
allowed_api_formats: Option<Vec<String>>,
|
allowed_api_formats: Option<Vec<String>>,
|
||||||
allowed_models_present: bool,
|
allowed_models_present: bool,
|
||||||
allowed_models: Option<Vec<String>>,
|
allowed_models: Option<Vec<String>>,
|
||||||
|
rate_limit_present: bool,
|
||||||
rate_limit: Option<i32>,
|
rate_limit: Option<i32>,
|
||||||
is_active: Option<bool>,
|
is_active: Option<bool>,
|
||||||
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
) -> Result<Option<StoredUserAuthRecord>, DataLayerError> {
|
||||||
@@ -688,7 +689,7 @@ WHERE id = ?
|
|||||||
allowed_models,
|
allowed_models,
|
||||||
"users.allowed_models",
|
"users.allowed_models",
|
||||||
)?)
|
)?)
|
||||||
.bind(rate_limit.is_some())
|
.bind(rate_limit_present)
|
||||||
.bind(rate_limit)
|
.bind(rate_limit)
|
||||||
.bind(is_active.is_some())
|
.bind(is_active.is_some())
|
||||||
.bind(is_active)
|
.bind(is_active)
|
||||||
@@ -1638,6 +1639,7 @@ INSERT INTO users (
|
|||||||
Some(vec!["responses".to_string()]),
|
Some(vec!["responses".to_string()]),
|
||||||
true,
|
true,
|
||||||
Some(vec!["gpt-4.1-mini".to_string()]),
|
Some(vec!["gpt-4.1-mini".to_string()]),
|
||||||
|
true,
|
||||||
Some(5),
|
Some(5),
|
||||||
Some(false),
|
Some(false),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -596,6 +596,7 @@ pub trait UserReadRepository: Send + Sync {
|
|||||||
allowed_api_formats: Option<Vec<String>>,
|
allowed_api_formats: Option<Vec<String>>,
|
||||||
allowed_models_present: bool,
|
allowed_models_present: bool,
|
||||||
allowed_models: Option<Vec<String>>,
|
allowed_models: Option<Vec<String>>,
|
||||||
|
rate_limit_present: bool,
|
||||||
rate_limit: Option<i32>,
|
rate_limit: Option<i32>,
|
||||||
is_active: Option<bool>,
|
is_active: Option<bool>,
|
||||||
) -> Result<Option<StoredUserAuthRecord>, crate::DataLayerError>;
|
) -> Result<Option<StoredUserAuthRecord>, crate::DataLayerError>;
|
||||||
|
|||||||
Reference in New Issue
Block a user