mirror of
https://github.com/getnora-io/nora.git
synced 2026-04-12 16:10:31 +00:00
style: cargo fmt
DevITWay
This commit is contained in:
@@ -45,11 +45,7 @@ pub struct AuditLog {
|
||||
impl AuditLog {
|
||||
pub fn new(storage_path: &str) -> Self {
|
||||
let path = PathBuf::from(storage_path).join("audit.jsonl");
|
||||
let writer = match OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(&path)
|
||||
{
|
||||
let writer = match OpenOptions::new().create(true).append(true).open(&path) {
|
||||
Ok(f) => {
|
||||
info!(path = %path.display(), "Audit log initialized");
|
||||
Mutex::new(Some(f))
|
||||
|
||||
@@ -13,8 +13,8 @@ use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::AppState;
|
||||
use crate::tokens::Role;
|
||||
use crate::AppState;
|
||||
|
||||
/// Htpasswd-based authentication
|
||||
#[derive(Clone)]
|
||||
@@ -247,12 +247,18 @@ async fn create_token(
|
||||
};
|
||||
|
||||
let role = match req.role.as_str() {
|
||||
"read" => Role::Read,
|
||||
"write" => Role::Write,
|
||||
"admin" => Role::Admin,
|
||||
_ => return (StatusCode::BAD_REQUEST, "Invalid role. Use: read, write, admin").into_response(),
|
||||
};
|
||||
match token_store.create_token(&req.username, req.ttl_days, req.description, role) {
|
||||
"read" => Role::Read,
|
||||
"write" => Role::Write,
|
||||
"admin" => Role::Admin,
|
||||
_ => {
|
||||
return (
|
||||
StatusCode::BAD_REQUEST,
|
||||
"Invalid role. Use: read, write, admin",
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
};
|
||||
match token_store.create_token(&req.username, req.ttl_days, req.description, role) {
|
||||
Ok(token) => Json(CreateTokenResponse {
|
||||
token,
|
||||
expires_in_days: req.ttl_days,
|
||||
|
||||
@@ -29,7 +29,10 @@ pub async fn run_gc(storage: &Storage, dry_run: bool) -> GcResult {
|
||||
|
||||
// 2. Collect all referenced digests from manifests
|
||||
let referenced = collect_referenced_digests(storage).await;
|
||||
info!("Found {} referenced digests from manifests", referenced.len());
|
||||
info!(
|
||||
"Found {} referenced digests from manifests",
|
||||
referenced.len()
|
||||
);
|
||||
|
||||
// 3. Find orphans
|
||||
let mut orphan_keys: Vec<String> = Vec::new();
|
||||
|
||||
@@ -8,11 +8,11 @@ mod backup;
|
||||
mod config;
|
||||
mod dashboard_metrics;
|
||||
mod error;
|
||||
mod gc;
|
||||
mod health;
|
||||
mod metrics;
|
||||
mod migrate;
|
||||
mod openapi;
|
||||
mod gc;
|
||||
mod rate_limit;
|
||||
mod registry;
|
||||
mod repo_index;
|
||||
|
||||
@@ -51,7 +51,9 @@ async fn download(
|
||||
"cargo",
|
||||
"LOCAL",
|
||||
));
|
||||
state.audit.log(AuditEntry::new("pull", "api", "", "cargo", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("pull", "api", "", "cargo", ""));
|
||||
(StatusCode::OK, data).into_response()
|
||||
}
|
||||
Err(_) => StatusCode::NOT_FOUND.into_response(),
|
||||
|
||||
@@ -312,7 +312,10 @@ async fn upload_blob(
|
||||
StatusCode::CREATED,
|
||||
[
|
||||
(header::LOCATION, location),
|
||||
(HeaderName::from_static("docker-content-digest"), digest.to_string()),
|
||||
(
|
||||
HeaderName::from_static("docker-content-digest"),
|
||||
digest.to_string(),
|
||||
),
|
||||
],
|
||||
)
|
||||
.into_response()
|
||||
@@ -489,7 +492,13 @@ async fn put_manifest(
|
||||
"docker",
|
||||
"LOCAL",
|
||||
));
|
||||
state.audit.log(AuditEntry::new("push", "api", &format!("{}:{}", name, reference), "docker", "manifest"));
|
||||
state.audit.log(AuditEntry::new(
|
||||
"push",
|
||||
"api",
|
||||
&format!("{}:{}", name, reference),
|
||||
"docker",
|
||||
"manifest",
|
||||
));
|
||||
state.repo_index.invalidate("docker");
|
||||
|
||||
let location = format!("/v2/{}/manifests/{}", name, reference);
|
||||
|
||||
@@ -43,7 +43,9 @@ async fn download(State(state): State<Arc<AppState>>, Path(path): Path<String>)
|
||||
"maven",
|
||||
"CACHE",
|
||||
));
|
||||
state.audit.log(AuditEntry::new("cache_hit", "api", "", "maven", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("cache_hit", "api", "", "maven", ""));
|
||||
return with_content_type(&path, data).into_response();
|
||||
}
|
||||
|
||||
@@ -60,7 +62,9 @@ async fn download(State(state): State<Arc<AppState>>, Path(path): Path<String>)
|
||||
"maven",
|
||||
"PROXY",
|
||||
));
|
||||
state.audit.log(AuditEntry::new("proxy_fetch", "api", "", "maven", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("proxy_fetch", "api", "", "maven", ""));
|
||||
|
||||
let storage = state.storage.clone();
|
||||
let key_clone = key.clone();
|
||||
@@ -106,7 +110,9 @@ async fn upload(
|
||||
"maven",
|
||||
"LOCAL",
|
||||
));
|
||||
state.audit.log(AuditEntry::new("push", "api", "", "maven", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("push", "api", "", "maven", ""));
|
||||
state.repo_index.invalidate("maven");
|
||||
StatusCode::CREATED
|
||||
}
|
||||
|
||||
@@ -49,7 +49,9 @@ async fn handle_request(State(state): State<Arc<AppState>>, Path(path): Path<Str
|
||||
"npm",
|
||||
"CACHE",
|
||||
));
|
||||
state.audit.log(AuditEntry::new("cache_hit", "api", "", "npm", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("cache_hit", "api", "", "npm", ""));
|
||||
}
|
||||
return with_content_type(is_tarball, data).into_response();
|
||||
}
|
||||
@@ -69,7 +71,9 @@ async fn handle_request(State(state): State<Arc<AppState>>, Path(path): Path<Str
|
||||
"npm",
|
||||
"PROXY",
|
||||
));
|
||||
state.audit.log(AuditEntry::new("proxy_fetch", "api", "", "npm", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("proxy_fetch", "api", "", "npm", ""));
|
||||
}
|
||||
|
||||
let storage = state.storage.clone();
|
||||
|
||||
@@ -116,7 +116,9 @@ async fn download_file(
|
||||
"pypi",
|
||||
"CACHE",
|
||||
));
|
||||
state.audit.log(AuditEntry::new("cache_hit", "api", "", "pypi", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("cache_hit", "api", "", "pypi", ""));
|
||||
|
||||
let content_type = if filename.ends_with(".whl") {
|
||||
"application/zip"
|
||||
@@ -158,7 +160,9 @@ async fn download_file(
|
||||
"pypi",
|
||||
"PROXY",
|
||||
));
|
||||
state.audit.log(AuditEntry::new("proxy_fetch", "api", "", "pypi", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("proxy_fetch", "api", "", "pypi", ""));
|
||||
|
||||
// Cache in local storage
|
||||
let storage = state.storage.clone();
|
||||
|
||||
@@ -36,7 +36,9 @@ async fn download(State(state): State<Arc<AppState>>, Path(path): Path<String>)
|
||||
state
|
||||
.activity
|
||||
.push(ActivityEntry::new(ActionType::Pull, path, "raw", "LOCAL"));
|
||||
state.audit.log(AuditEntry::new("pull", "api", "", "raw", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("pull", "api", "", "raw", ""));
|
||||
|
||||
// Guess content type from extension
|
||||
let content_type = guess_content_type(&key);
|
||||
@@ -74,7 +76,9 @@ async fn upload(
|
||||
state
|
||||
.activity
|
||||
.push(ActivityEntry::new(ActionType::Push, path, "raw", "LOCAL"));
|
||||
state.audit.log(AuditEntry::new("push", "api", "", "raw", ""));
|
||||
state
|
||||
.audit
|
||||
.log(AuditEntry::new("push", "api", "", "raw", ""));
|
||||
StatusCode::CREATED.into_response()
|
||||
}
|
||||
Err(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
|
||||
|
||||
@@ -40,7 +40,6 @@ impl Role {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// API Token metadata stored on disk
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TokenInfo {
|
||||
@@ -260,7 +259,9 @@ mod tests {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let store = TokenStore::new(temp_dir.path());
|
||||
|
||||
let token = store.create_token("testuser", 30, None, Role::Write).unwrap();
|
||||
let token = store
|
||||
.create_token("testuser", 30, None, Role::Write)
|
||||
.unwrap();
|
||||
let (user, role) = store.verify_token(&token).unwrap();
|
||||
|
||||
assert_eq!(user, "testuser");
|
||||
@@ -291,7 +292,9 @@ mod tests {
|
||||
let store = TokenStore::new(temp_dir.path());
|
||||
|
||||
// Create token and manually set it as expired
|
||||
let token = store.create_token("testuser", 1, None, Role::Write).unwrap();
|
||||
let token = store
|
||||
.create_token("testuser", 1, None, Role::Write)
|
||||
.unwrap();
|
||||
let token_hash = hash_token(&token);
|
||||
let file_path = temp_dir.path().join(format!("{}.json", &token_hash[..16]));
|
||||
|
||||
@@ -330,7 +333,9 @@ mod tests {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let store = TokenStore::new(temp_dir.path());
|
||||
|
||||
let token = store.create_token("testuser", 30, None, Role::Write).unwrap();
|
||||
let token = store
|
||||
.create_token("testuser", 30, None, Role::Write)
|
||||
.unwrap();
|
||||
let token_hash = hash_token(&token);
|
||||
let hash_prefix = &token_hash[..16];
|
||||
|
||||
@@ -375,7 +380,9 @@ mod tests {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let store = TokenStore::new(temp_dir.path());
|
||||
|
||||
let token = store.create_token("testuser", 30, None, Role::Write).unwrap();
|
||||
let token = store
|
||||
.create_token("testuser", 30, None, Role::Write)
|
||||
.unwrap();
|
||||
|
||||
// First verification
|
||||
store.verify_token(&token).unwrap();
|
||||
@@ -391,7 +398,12 @@ mod tests {
|
||||
let store = TokenStore::new(temp_dir.path());
|
||||
|
||||
store
|
||||
.create_token("testuser", 30, Some("CI/CD Pipeline".to_string()), Role::Admin)
|
||||
.create_token(
|
||||
"testuser",
|
||||
30,
|
||||
Some("CI/CD Pipeline".to_string()),
|
||||
Role::Admin,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let tokens = store.list_tokens("testuser");
|
||||
|
||||
Reference in New Issue
Block a user