Skip to content

Commit

Permalink
Maven was able to publish!
Browse files Browse the repository at this point in the history
  • Loading branch information
wyatt-herkamp committed Aug 14, 2024
1 parent 2d5a3e8 commit a1f6a1d
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 88 deletions.
5 changes: 5 additions & 0 deletions crates/core/src/storage/storage_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ use tracing::instrument;
struct StoragePathComponent(String);
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct StoragePath(Vec<StoragePathComponent>);
impl Default for StoragePath {
fn default() -> Self {
StoragePath(vec![])
}
}
impl StoragePath {
pub fn has_extension(&self, extension: &str) -> bool {
self.0
Expand Down
29 changes: 16 additions & 13 deletions crates/storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,50 +29,53 @@ pub trait Storage: Send + Sync {
///
/// # Result
/// Return the number of bytes written and if a new file was created
async fn save_file(
fn save_file(
&self,
repository: Uuid,
file: FileContent,
location: &StoragePath,
) -> Result<(usize, bool), StorageError>;
) -> impl Future<Output = Result<(usize, bool), StorageError>> + Send;
/// Repository Meta files are files that are not listed and the repository controls the content. The content is stored as JSON
async fn put_repository_meta(
fn put_repository_meta(
&self,
repository: Uuid,
location: &StoragePath,
value: Value,
) -> Result<(), StorageError>;
) -> impl Future<Output = Result<(), StorageError>> + Send;
/// Repository Meta files are files that are not listed and the repository controls the content. The content is stored as JSON
async fn get_repository_meta(
fn get_repository_meta(
&self,
repository: Uuid,
location: &StoragePath,
) -> Result<Option<Value>, StorageError>;
) -> impl Future<Output = Result<Option<Value>, StorageError>> + Send;
/// Deletes a file at a given location
async fn delete_file(
fn delete_file(
&self,
repository: Uuid,
location: &StoragePath,
) -> Result<(), StorageError>;
) -> impl Future<Output = Result<(), StorageError>> + Send;

/// Returns Information about the file
async fn get_file_information(
fn get_file_information(
&self,
repository: Uuid,
location: &StoragePath,
) -> Result<Option<StorageFileMeta>, StorageError>;
) -> impl Future<Output = Result<Option<StorageFileMeta>, StorageError>> + Send;

/// Gets the File Information and Content
///
/// range is ignored for directories
/// range is the byte range to read from the file
async fn open_file(
fn open_file(
&self,
repository: Uuid,
location: &StoragePath,
) -> Result<Option<StorageFile>, StorageError>;
) -> impl Future<Output = Result<Option<StorageFile>, StorageError>> + Send;

async fn validate_config_change(&self, config: StorageTypeConfig) -> Result<(), StorageError>;
fn validate_config_change(
&self,
config: StorageTypeConfig,
) -> impl Future<Output = Result<(), StorageError>> + Send;
}
pub trait StorageFactory {
fn storage_name(&self) -> &'static str;
Expand Down
6 changes: 3 additions & 3 deletions nitro_repo/migrations/20240813200230_create_projects.up.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- Add up migration script here
create table TABLE IF NOT EXISTS projects
create TABLE IF NOT EXISTS projects
(
id UUID default gen_random_uuid() not null
constraint projects_pk
Expand All @@ -19,7 +19,7 @@ create table TABLE IF NOT EXISTS projects
updated_at TIMESTAMP WITH TIME ZONE default CURRENT_TIMESTAMP not null,
created_at TIMESTAMP WITH TIME ZONE default CURRENT_TIMESTAMP not null
);
create table TABLE IF NOT EXISTS project_members
create TABLE IF NOT EXISTS project_members
(
id serial
constraint project_members_pk
Expand All @@ -37,7 +37,7 @@ create table TABLE IF NOT EXISTS project_members
added_at TIMESTAMP WITH TIME ZONE default CURRENT_TIMESTAMP not null
);

create table TABLE IF NOT EXISTS project_versions
create TABLE IF NOT EXISTS project_versions
(
id serial
constraint project_versions_pk
Expand Down
7 changes: 3 additions & 4 deletions nitro_repo/src/app/authentication/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use serde::Serialize;
use session::Session;
use sqlx::PgPool;
use thiserror::Error;
use tracing::{error, warn};
use tracing::{error, info, warn};
use utoipa::ToSchema;

use crate::utils::headers::AuthorizationHeader;
Expand Down Expand Up @@ -175,9 +175,7 @@ where
return Err(AuthenticationError::Unauthorized);
};
let auth = match raw_auth {
AuthenticationRaw::NoIdentification => {
return Err(AuthenticationError::Unauthorized);
}
AuthenticationRaw::NoIdentification => RepositoryAuthentication::NoIdentification,
AuthenticationRaw::AuthToken(..) => {
todo!("Auth Token Authentication")
}
Expand All @@ -193,6 +191,7 @@ where
return Err(AuthenticationError::Unauthorized);
}
AuthenticationRaw::Basic { username, password } => {
info!("Basic Auth: {}", username);
let user = verify_login(username, password, &repo.database).await?;
// TODO: Check if it is an API Token and not a username/password
RepositoryAuthentication::Basic(user, None)
Expand Down
4 changes: 2 additions & 2 deletions nitro_repo/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ impl RepositoryStorageName {
pub async fn query_db(&self, database: &PgPool) -> Result<Option<Uuid>, sqlx::Error> {
let query: Option<Uuid> = sqlx::query_scalar(
r#"SELECT repositories.id FROM repositories LEFT JOIN storages
ON storages.id = repositories.storage_id
WHERE storages.name = ? AND repositories.name = ?"#,
ON storages.id = repositories.storage_id AND storages.name = $1
WHERE repositories.name = $2"#,
)
.bind(&self.storage_name)
.bind(&self.repository_name)
Expand Down
9 changes: 9 additions & 0 deletions nitro_repo/src/app/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use super::{api, config::NitroRepoConfig};

use anyhow::Context;
use axum::extract::DefaultBodyLimit;
use axum::routing::any;
use axum::{extract::Request, Router};
use futures_util::pin_mut;
use http::{HeaderName, HeaderValue};
Expand Down Expand Up @@ -54,6 +55,14 @@ pub(crate) async fn start(config: NitroRepoConfig) -> anyhow::Result<()> {
let cloned_site = site.clone();
let auth_layer = AuthenticationLayer::from(site.clone());
let app = Router::new()
.route(
"/repositories/:storage/:repository/*path",
any(crate::repository::handle_repo_request),
)
.route(
"/storages/:storage/:repository/*path",
any(crate::repository::handle_repo_request),
)
.merge(api::api_routes())
.merge(super::open_api::build_router())
.with_state(site);
Expand Down
38 changes: 26 additions & 12 deletions nitro_repo/src/repository/maven/hosted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use nr_core::{
};
use nr_storage::{DynStorage, Storage};
use parking_lot::RwLock;
use tracing::{debug, instrument};
use tracing::{debug, info, instrument};
use uuid::Uuid;

use crate::{
Expand Down Expand Up @@ -229,21 +229,34 @@ impl Repository for MavenHosted {
authentication,
}: RepositoryRequest,
) -> Result<RepoResponse, RepositoryHandlerError> {
let repository = self.repository.read();
if !repository.active {
return Ok(RepoResponse::disabled_repository());
}
info!(
"Handling PUT Request for Repository: {} Path: {}",
self.id, path
);
let repository_name = {
let repository = self.repository.read();
if !repository.active {
return Ok(RepoResponse::disabled_repository());
}
repository.name.clone()
};
let Some(user) = authentication.get_user() else {
return Ok(RepoResponse::Unauthorized);
};
let security_config = self.security.read();
let push_rules = self.push_rules.read();
if security_config.must_use_auth_token_for_push && !authentication.has_auth_token() {
return Ok(RepoResponse::Unauthorized);
{
let security_config = self.security.read();
if security_config.visibility.is_private() && !user.can_read_repository(self.id) {
return Ok(RepoResponse::Unauthorized);
}
}
if !user.can_write_to_repository(self.id) {
return Ok(RepoResponse::Unauthorized);
{
let push_rules = self.push_rules.read();

if !user.can_write_to_repository(self.id) {
return Ok(RepoResponse::Unauthorized);
}
}
info!("Saving File: {}", path);
let body = body.body_as_bytes().await?;
// TODO: Validate Against Push Rules

Expand All @@ -255,9 +268,10 @@ impl Repository for MavenHosted {
let save_path = format!(
"/repositories/{}/{}/{}",
self.storage.storage_config().storage_config.storage_name,
repository.name,
repository_name,
path
);

Ok(RepoResponse::put_response(created, save_path))
}

Expand Down
100 changes: 58 additions & 42 deletions nitro_repo/src/repository/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#![allow(unused_variables)]

use std::future::Future;

use axum::{
body::Body,
response::{IntoResponse, Response},
Expand Down Expand Up @@ -31,72 +33,86 @@ pub trait Repository: Send + Sync + Clone {
Ok(())
}
/// Handles a get request to a Repo
async fn handle_get(
fn handle_get(
&self,
request: RepositoryRequest,
) -> Result<RepoResponse, RepositoryHandlerError> {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
) -> impl Future<Output = Result<RepoResponse, RepositoryHandlerError>> + Send {
async {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
}
}
/// Handles a Post Request to a Repo
async fn handle_post(
fn handle_post(
&self,
request: RepositoryRequest,
) -> Result<RepoResponse, RepositoryHandlerError> {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
) -> impl Future<Output = Result<RepoResponse, RepositoryHandlerError>> + Send {
async {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
}
}
/// Handles a PUT Request to a Repo
async fn handle_put(
fn handle_put(
&self,
request: RepositoryRequest,
) -> Result<RepoResponse, RepositoryHandlerError> {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
) -> impl Future<Output = Result<RepoResponse, RepositoryHandlerError>> + Send {
async {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
}
}
/// Handles a PATCH Request to a Repo
async fn handle_patch(
fn handle_patch(
&self,
request: RepositoryRequest,
) -> Result<RepoResponse, RepositoryHandlerError> {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
) -> impl Future<Output = Result<RepoResponse, RepositoryHandlerError>> + Send {
async {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
}
}
async fn handle_delete(
fn handle_delete(
&self,
request: RepositoryRequest,
) -> Result<RepoResponse, RepositoryHandlerError> {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
) -> impl Future<Output = Result<RepoResponse, RepositoryHandlerError>> + Send {
async {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
}
}
/// Handles a HAPIResponseAD Request to a Repo
async fn handle_head(
fn handle_head(
&self,
request: RepositoryRequest,
) -> Result<RepoResponse, RepositoryHandlerError> {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
) -> impl Future<Output = Result<RepoResponse, RepositoryHandlerError>> + Send {
async {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
}
}
async fn handle_other(
fn handle_other(
&self,
request: RepositoryRequest,
) -> Result<RepoResponse, RepositoryHandlerError> {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
) -> impl Future<Output = Result<RepoResponse, RepositoryHandlerError>> + Send {
async {
Ok(RepoResponse::unsupported_method_response(
request.parts.method,
self.get_type(),
))
}
}
}

Expand Down
Loading

0 comments on commit a1f6a1d

Please sign in to comment.