Skip to content

Commit

Permalink
Updates to latest axum
Browse files Browse the repository at this point in the history
  • Loading branch information
wyatt-herkamp committed Jan 12, 2025
1 parent a667bfa commit 135a35c
Show file tree
Hide file tree
Showing 29 changed files with 2,711 additions and 1,687 deletions.
547 changes: 305 additions & 242 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ toml = "0.8"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
tracing-appender = "0.2"
utoipa = { version = "5.0.0", features = ["chrono", "uuid", "url", "debug"] }
utoipa = { version = "5", features = ["chrono", "uuid", "url", "debug"] }
rand = "0.8"

nr-core = { path = "crates/core" }
Expand Down
20 changes: 15 additions & 5 deletions nitro_repo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ license.workspace = true
pretty_assertions = "1.1"
[dependencies]
# Web
axum = { version = "0.7", features = ["macros", "tokio"] }
axum-extra = { version = "0.9", features = [
axum = { version = "0.8", features = ["macros", "tokio"] }
axum-extra = { version = "0.10", features = [
"multipart",
"cookie",
"typed-header",
Expand All @@ -25,7 +25,7 @@ http.workspace = true
mime.workspace = true
http-body-util.workspace = true
utoipa = { workspace = true, features = ["axum_extras"] }
utoipa-scalar = { version = "0.2.0", features = ["axum"], optional = true }
utoipa-scalar = { version = "0.2", features = ["axum"], optional = true }
async-trait = "0.1"
# TLS
tokio-rustls = "0.26"
Expand Down Expand Up @@ -94,8 +94,18 @@ tracing-appender.workspace = true
# OpenTelemetry - Tracing framework
tracing-opentelemetry = "0.28"
opentelemetry = { version = "0.27", features = [] }
opentelemetry_sdk = { version = "0.27", features = ["rt-tokio"] }
opentelemetry-otlp = { version = "0.27", default-features = true }
opentelemetry_sdk = { version = "0.27", features = [
"rt-tokio",
"trace",
"metrics",
"logs",
] }
opentelemetry-otlp = { version = "0.27", default-features = true, features = [
"grpc-tonic",
"http-proto",
"http-json",
] }
opentelemetry-appender-tracing = { version = "0.27" }
lettre = { version = "0.11.9", features = [
"builder",
"tokio1",
Expand Down
4 changes: 2 additions & 2 deletions nitro_repo/src/app/api/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ pub struct RepositoryAPI;
pub fn repository_routes() -> axum::Router<NitroRepo> {
axum::Router::new()
.route("/list", get(list_repositories))
.route("/:id", get(get_repository))
.route("/page/:id", get(page::get_repository_page))
.route("/{id}", get(get_repository))
.route("/page/{id}", get(page::get_repository_page))
.route("/types", get(types::repository_types))
.merge(browse::browse_routes())
.merge(management::management_routes())
Expand Down
6 changes: 3 additions & 3 deletions nitro_repo/src/app/api/repository/browse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ use crate::{
};
pub fn browse_routes() -> axum::Router<NitroRepo> {
axum::Router::new()
.route("/browse/:repository_id", get(browse))
.route("/browse/:repository_id/", get(browse))
.route("/browse/:repository_id/*path", get(browse))
.route("/browse/{repository_id}", get(browse))
.route("/browse/{repository_id}/", get(browse))
.route("/browse/{repository_id}/{*path}", get(browse))
}
#[derive(Debug, Deserialize, Clone, ToSchema)]
#[serde(default)]
Expand Down
8 changes: 4 additions & 4 deletions nitro_repo/src/app/api/repository/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ use crate::{
};
pub fn config_routes() -> axum::Router<NitroRepo> {
axum::Router::new()
.route("/config/:key/schema", axum::routing::get(config_schema))
.route("/config/{key}/schema", axum::routing::get(config_schema))
.route(
"/config/:key/validate",
"/config/{key}/validate",
axum::routing::post(config_validate),
)
.route("/config/:key/default", axum::routing::get(config_default))
.route("/config/{key}/default", axum::routing::get(config_default))
.route(
"/config/:key/description",
"/config/{key}/description",
axum::routing::get(config_description),
)
}
Expand Down
12 changes: 7 additions & 5 deletions nitro_repo/src/app/api/repository/management.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use ahash::HashMap;
use axum::{
body::Body,
debug_handler,
extract::{Path, Query, State},
response::{IntoResponse, Response},
routing::{delete, get, post, put},
Expand Down Expand Up @@ -32,11 +33,11 @@ use crate::{
};
pub fn management_routes() -> Router<NitroRepo> {
Router::new()
.route("/:id/configs", get(get_configs_for_repository))
.route("/new/:repository_type", post(new_repository))
.route("/:id/config/:key", put(update_config))
.route("/:id/config/:key", get(get_config))
.route("/:id", delete(delete_repository))
.route("/{id}/configs", get(get_configs_for_repository))
.route("/new/{repository_type}", post(new_repository))
.route("/{id}/config/{key}", put(update_config))
.route("/{id}/config/{key}", get(get_config))
.route("/{id}", delete(delete_repository))
}
#[derive(Deserialize, ToSchema, Debug)]
pub struct NewRepositoryRequest {
Expand Down Expand Up @@ -166,6 +167,7 @@ pub struct GetConfigParams {
(status = 200, description = "Config for the repository"),
)
)]
#[debug_handler]
#[instrument]
pub async fn get_config(
State(site): State<NitroRepo>,
Expand Down
4 changes: 2 additions & 2 deletions nitro_repo/src/app/api/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ pub struct StorageAPI;
pub fn storage_routes() -> axum::Router<crate::app::api::storage::NitroRepo> {
axum::Router::new()
.route("/list", axum::routing::get(list_storages))
.route("/new/:storage_type", axum::routing::post(new_storage))
.route("/:id", axum::routing::get(get_storage))
.route("/new/{storage_type}", axum::routing::post(new_storage))
.route("/{id}", axum::routing::get(get_storage))
.route(
"/local-storage-path-helper",
axum::routing::post(local_storage_path_helper),
Expand Down
4 changes: 2 additions & 2 deletions nitro_repo/src/app/api/user/password_reset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ use crate::{
pub fn password_reset_routes() -> axum::Router<NitroRepo> {
axum::Router::new()
.route("/request", post(request_password_reset))
.route("/check/:token", get(does_exist))
.route("/:token", post(perform_password_change))
.route("/check/{token}", get(does_exist))
.route("/{token}", post(perform_password_change))
}
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct RequestPasswordReset {
Expand Down
4 changes: 2 additions & 2 deletions nitro_repo/src/app/api/user/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ pub fn token_routes() -> axum::Router<NitroRepo> {
axum::Router::new()
.route("/create", post(create))
.route("/list", get(list))
.route("/get/:id", get(get_token))
.route("/delete/:id", delete(delete_token))
.route("/get/{id}", get(get_token))
.route("/delete/{id}", delete(delete_token))
}

#[derive(Debug, Serialize, Deserialize, ToSchema)]
Expand Down
8 changes: 4 additions & 4 deletions nitro_repo/src/app/api/user_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,19 @@ pub struct UserManagementAPI;
pub fn user_management_routes() -> axum::Router<NitroRepo> {
axum::Router::new()
.route("/list", axum::routing::get(list_users))
.route("/get/:user_id", axum::routing::get(get_user))
.route("/get/{user_id}", axum::routing::get(get_user))
.route(
"/get/:user_id/permissions",
"/get/{user_id}/permissions",
axum::routing::get(get_user_permissions),
)
.route("/create", axum::routing::post(create_user))
.route("/is-taken", axum::routing::post(is_taken))
.route(
"/update/:user_id/permissions",
"/update/{user_id}/permissions",
axum::routing::put(update_permissions),
)
.route(
"/update/:user_id/password",
"/update/{user_id}/password",
axum::routing::put(update_password),
)
}
Expand Down
43 changes: 38 additions & 5 deletions nitro_repo/src/app/authentication/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use std::fmt::{Debug, Display};
use std::ops::Deref;

use axum::async_trait;
use axum::body::Body;
use axum::extract::{FromRef, FromRequestParts};
use axum::extract::{FromRef, FromRequestParts, OptionalFromRequestParts};
use axum::response::IntoResponse;
use axum_extra::extract::cookie::Cookie;
use derive_more::From;
Expand Down Expand Up @@ -93,7 +92,6 @@ impl HasPermissions for OnlySessionAllowedAuthentication {
self.user.get_permissions()
}
}
#[async_trait]
impl<S> FromRequestParts<S> for OnlySessionAllowedAuthentication
where
NitroRepo: FromRef<S>,
Expand Down Expand Up @@ -164,7 +162,6 @@ impl HasPermissions for Authentication {
}
}
}
#[async_trait]
impl<S> FromRequestParts<S> for Authentication
where
NitroRepo: FromRef<S>,
Expand Down Expand Up @@ -204,7 +201,43 @@ where
Ok(auth)
}
}

impl<S> OptionalFromRequestParts<S> for Authentication
where
NitroRepo: FromRef<S>,
S: Send + Sync,
{
type Rejection = AuthenticationError;
async fn from_request_parts(
parts: &mut Parts,
state: &S,
) -> Result<Option<Self>, Self::Rejection> {
let raw_extension = parts.extensions.get::<AuthenticationRaw>().cloned();
let repo = NitroRepo::from_ref(state);
let Some(raw_auth) = raw_extension else {
return Ok(None);
};
let auth = match raw_auth {
AuthenticationRaw::NoIdentification => {
return Ok(None);
}
AuthenticationRaw::AuthToken(token) => {
let (user, auth_token) = get_user_and_auth_token(&token, &repo.database).await?;
Authentication::AuthToken(auth_token, user)
}
AuthenticationRaw::Session(session) => {
let user = UserSafeData::get_by_id(session.user_id, &repo.database)
.await?
.ok_or(AuthenticationError::Unauthorized)?;
Authentication::Session(session, user)
}
other => {
warn!("Unknown Authentication Method: {}", other);
return Ok(None);
}
};
Ok(Some(auth))
}
}
#[derive(Debug, Serialize, Clone, From, ToSchema)]
pub struct MeWithSession {
session: Session,
Expand Down
62 changes: 47 additions & 15 deletions nitro_repo/src/app/authentication/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use std::{
};

use crate::{
app::config::{get_current_directory, Mode},
app::{
config::{get_current_directory, Mode},
NitroRepo,
},
error::IntoErrorResponse,
};
use axum::response::{IntoResponse, Response};
Expand All @@ -18,7 +21,12 @@ use rand::{distributions::Alphanumeric, rngs::StdRng, Rng, SeedableRng};
use redb::{CommitError, Database, Error, ReadableTable, ReadableTableMetadata, TableDefinition};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tracing::{debug, error, info, instrument};
use tokio::task::JoinHandle;
use tracing::{
debug, error,
field::{display, Empty},
info, instrument, span, Level,
};
use utoipa::ToSchema;
#[derive(Debug, Error)]
pub enum SessionError {
Expand Down Expand Up @@ -250,30 +258,54 @@ impl SessionManager {
sessions.commit()?;
Ok(sessions_removed)
}
pub fn start_cleaner(this: Arc<Self>) {
let how_often = this
.config
.cleanup_interval
.to_std()
.expect("Duration is too large");
debug!("Starting Session Cleaner with interval: {:?}", how_often);
tokio::spawn(async move {
let this = this;
while this.running.load(Ordering::Relaxed) {
pub async fn cleaner_task(this: NitroRepo, how_often: std::time::Duration) {
let session_manager = this.session_manager.clone();

while session_manager.running.load(Ordering::Relaxed) {
let sleep_for = {
let span = span!(
Level::INFO,
"Session Cleaner",
sessions.removed = Empty,
session.cleaner.error = Empty
);
let _enter = span.enter();

info!("Cleaning sessions");
let sleep_for = match this.clean_inner() {
match session_manager.clean_inner() {
Ok(value) => {
info!("Cleaned {} sessions", value);
span.record("sessions.removed", value);
how_often
}
Err(err) => {
error!("Failed to clean sessions: {:?}", err);
span.record("session.cleaner.error", display(err));
how_often / 2
}
};
tokio::time::sleep(sleep_for).await
}
};
if let Ok(number_of_sessions) = session_manager.number_of_sessions() {
this.metrics
.active_sessions
.add(number_of_sessions as i64, &[]);
}
tokio::time::sleep(sleep_for).await
}
}
pub fn start_cleaner(this: NitroRepo) -> Option<JoinHandle<()>> {
let how_often = this
.session_manager
.config
.cleanup_interval
.to_std()
.expect("Duration is too large");
debug!("Starting Session Cleaner with interval: {:?}", how_often);
let result = tokio::spawn(async move {
let this = this;
SessionManager::cleaner_task(this, how_often).await;
});
Some(result)
}
#[instrument]
pub fn create_session(
Expand Down
6 changes: 3 additions & 3 deletions nitro_repo/src/app/badge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ pub struct BadgeRoutes;
pub fn badge_routes() -> axum::Router<NitroRepo> {
axum::Router::new()
.route(
"/:storage/:repository",
"/{storage}/{repository}",
axum::routing::get(repository_badge),
)
.route(
"/:storage/:repository/project/:project",
"/{storage}/{repository}/project/{project}",
axum::routing::get(project_badge),
)
.route(
"/:storage/:repository/supports",
"/{storage}/{repository}/supports",
axum::routing::get(supports_badges),
)
}
Expand Down
2 changes: 1 addition & 1 deletion nitro_repo/src/app/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod max_upload;
mod security;
use super::authentication::session::SessionManagerConfig;
use super::email::EmailSetting;
use super::logging::LoggingConfig;
use super::logging::config::LoggingConfig;
use crate::repository::StagingConfig;
pub use max_upload::*;
pub use security::*;
Expand Down
Loading

0 comments on commit 135a35c

Please sign in to comment.