🏡 index : ~doyle/gitlab-cargo-shim.git

author Jordan Doyle <jordan@doyle.la> 2022-03-12 18:18:08.0 +00:00:00
committer Jordan Doyle <jordan@doyle.la> 2022-03-12 18:18:42.0 +00:00:00
commit
fd5386864c53a3b7a0665a1185026a255bf0ecc8 [patch]
tree
82ef5da814e133e72c6f37e03c6ee06ca7866856
parent
de189f137cdb8a378077942f3b0eba4a739b0a70
download
fd5386864c53a3b7a0665a1185026a255bf0ecc8.tar.gz

Add config.toml parsing for gitlab config



Diff

 Cargo.lock              | 120 +++++++++++++++++++++++++++++++++++++++++++++----
 Cargo.toml              |   7 ++-
 config.toml             |   9 ++++-
 src/config.rs           |  28 +++++++++++-
 src/main.rs             |  16 ++++---
 src/providers/gitlab.rs |  21 +++------
 6 files changed, 172 insertions(+), 29 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 9b7c4d7..5b8015b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -46,12 +46,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"

[[package]]
name = "arrayvec"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"

[[package]]
name = "async-trait"
version = "0.1.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -63,6 +57,17 @@ dependencies = [
]

[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
 "hermit-abi",
 "libc",
 "winapi",
]

[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -221,6 +226,36 @@ dependencies = [
]

[[package]]
name = "clap"
version = "3.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123"
dependencies = [
 "atty",
 "bitflags",
 "clap_derive",
 "indexmap",
 "lazy_static",
 "os_str_bytes",
 "strsim",
 "termcolor",
 "textwrap",
]

[[package]]
name = "clap_derive"
version = "3.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16"
dependencies = [
 "heck",
 "proc-macro-error",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -514,11 +549,10 @@ name = "gitlab-cargo-shim"
version = "0.1.0"
dependencies = [
 "anyhow",
 "arrayvec",
 "async-trait",
 "base64",
 "bytes",
 "cargo_metadata",
 "clap",
 "flate2",
 "futures",
 "hex",
@@ -538,6 +572,7 @@ dependencies = [
 "time",
 "tokio",
 "tokio-util 0.7.0",
 "toml",
 "tracing",
 "tracing-subscriber",
]
@@ -568,6 +603,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"

[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"

[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -943,6 +984,15 @@ dependencies = [
]

[[package]]
name = "os_str_bytes"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
dependencies = [
 "memchr",
]

[[package]]
name = "parking_lot"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1031,6 +1081,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"

[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
 "proc-macro-error-attr",
 "proc-macro2",
 "quote",
 "syn",
 "version_check",
]

[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
 "proc-macro2",
 "quote",
 "version_check",
]

[[package]]
name = "proc-macro2"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1336,6 +1410,12 @@ dependencies = [
]

[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"

[[package]]
name = "subtle"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1367,6 +1447,21 @@ dependencies = [
]

[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
 "winapi-util",
]

[[package]]
name = "textwrap"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"

[[package]]
name = "thiserror"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1568,6 +1663,15 @@ dependencies = [
]

[[package]]
name = "toml"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [
 "serde",
]

[[package]]
name = "tower-service"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 8535e83..31b4662 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,16 +2,18 @@
name = "gitlab-cargo-shim"
version = "0.1.0"
edition = "2021"
authors = [
    "Jordan Doyle <jordan@doyl.ee>"
]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1"
async-trait = "0.1"
arrayvec = "0.7"
base64 = "0.13"
bytes = "1.1"
cargo_metadata = "0.14"
clap = { version = "3.1", features = ["derive", "cargo"] }
flate2 = "1.0"
futures = "0.3"
hex = "0.4"
@@ -33,3 +35,4 @@ thrussh-keys = "0.21"
time = "0.3"
tokio = { version = "1.17", features = ["full"] }
tokio-util = { version = "0.7", features = ["codec"] }
toml = "0.5"
diff --git a/config.toml b/config.toml
new file mode 100644
index 0000000..dbe3f41
--- /dev/null
+++ b/config.toml
@@ -0,0 +1,9 @@
[gitlab]
# the base url of the gitlab instance
uri = "http://127.0.0.1:3000"

# a personal access token of an admin with permission to `sudo` as other
# users and create impersonation tokens. `sudo` is used to fetch all the
# packages the user can access, and the impersonation token is returned
# to the user to download packages
admin-token = "personal-access-token"
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..812d18e
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,28 @@
#![allow(clippy::module_name_repetitions)]

use clap::Parser;
use serde::{de::DeserializeOwned, Deserialize};

#[derive(Parser)]
#[clap(version = clap::crate_version!(), author = clap::crate_authors!())]
pub struct Args {
    #[clap(short, long, parse(try_from_str = from_toml_path))]
    pub config: Config,
}

#[derive(Deserialize)]
pub struct Config {
    pub gitlab: GitlabConfig,
}

#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct GitlabConfig {
    pub uri: String,
    pub admin_token: String,
}

pub fn from_toml_path<T: DeserializeOwned>(path: &str) -> Result<T, std::io::Error> {
    let contents = std::fs::read(path)?;
    toml::from_slice(&contents).map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
}
diff --git a/src/main.rs b/src/main.rs
index fa3d7ce..f13595e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,26 +1,28 @@
#![deny(clippy::pedantic)]
#![allow(clippy::missing_errors_doc)]

pub mod config;
pub mod git_command_handlers;
pub mod metadata;
pub mod protocol;
pub mod providers;
pub mod util;

use crate::metadata::CargoIndexCrateMetadata;
use crate::protocol::low_level::{HashOutput, PackFileEntry};
use crate::providers::Group;
use crate::util::get_crate_folder;
use crate::{
    config::Args,
    metadata::CargoIndexCrateMetadata,
    protocol::{
        codec::{Encoder, GitCodec},
        high_level::GitRepository,
        low_level::{HashOutput, PackFileEntry},
        packet_line::PktLine,
    },
    providers::{gitlab::Gitlab, PackageProvider, Release, User, UserProvider},
    providers::{gitlab::Gitlab, Group, PackageProvider, Release, User, UserProvider},
    util::get_crate_folder,
};
use anyhow::anyhow;
use bytes::{BufMut, Bytes, BytesMut};
use clap::Parser;
use futures::Future;
use parking_lot::RwLock;
use std::{borrow::Cow, collections::HashMap, fmt::Write, net::SocketAddr, pin::Pin, sync::Arc};
@@ -44,6 +46,8 @@ const AGENT: &str = concat!(
async fn main() -> anyhow::Result<()> {
    tracing_subscriber::fmt::init();

    let args: Args = Args::parse();

    let ed25519_key = thrussh_keys::key::KeyPair::generate_ed25519().unwrap();

    let thrussh_config = Arc::new(thrussh::server::Config {
@@ -52,7 +56,7 @@ async fn main() -> anyhow::Result<()> {
        ..thrussh::server::Config::default()
    });

    let gitlab = Arc::new(Gitlab::new()?);
    let gitlab = Arc::new(Gitlab::new(&args.config.gitlab)?);

    thrussh::server::run(
        thrussh_config,
diff --git a/src/providers/gitlab.rs b/src/providers/gitlab.rs
index cbf276c..a85e8ab 100644
--- a/src/providers/gitlab.rs
+++ b/src/providers/gitlab.rs
@@ -1,5 +1,6 @@
#![allow(clippy::module_name_repetitions)]

use crate::config::GitlabConfig;
use crate::providers::{Group, Release, User};
use async_trait::async_trait;
use futures::{stream::FuturesUnordered, StreamExt, TryStreamExt};
@@ -9,25 +10,24 @@ use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::sync::Arc;

const GITLAB_API_ENDPOINT: &str = "http://127.0.0.1:3000";
// const PAT: &str = "glpat-saSjc4srMhxAA-qDp8F8";
const PAT: &str = "X994NFZjTy1ZYbsCwTLK";

pub struct Gitlab {
    client: reqwest::Client,
    base_url: String,
}

impl Gitlab {
    pub fn new() -> anyhow::Result<Self> {
    pub fn new(config: &GitlabConfig) -> anyhow::Result<Self> {
        let mut headers = header::HeaderMap::new();
        headers.insert("PRIVATE-TOKEN", header::HeaderValue::from_static(PAT));
        headers.insert(
            "PRIVATE-TOKEN",
            header::HeaderValue::from_str(&config.admin_token)?,
        );

        Ok(Self {
            client: reqwest::ClientBuilder::new()
                .default_headers(headers)
                .build()?,
            base_url: format!("{}/api/v4", GITLAB_API_ENDPOINT),
            base_url: format!("{}/api/v4", config.uri),
        })
    }
}
@@ -216,12 +216,7 @@ impl super::PackageProvider for Gitlab {
        path: &Self::CratePath,
        version: &str,
    ) -> anyhow::Result<cargo_metadata::Metadata> {
        let uri = format!(
            "{}{}?private_token={}",
            self.base_url,
            path.metadata_uri(version),
            PAT,
        );
        let uri = format!("{}{}", self.base_url, path.metadata_uri(version),);

        Ok(self.client.get(uri).send().await?.json().await?)
    }