RUA!
Avatar

Sonetto

DefectingCat

ε’Έι±ΌπŸŸ

DefectingCat /jwt.rs

Last active: 2 months ago

Rust jwt

use jsonwebtoken::{
    decode, encode, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation,
};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
pub struct Claims {
    // aud: String, // Optional. Audience
    pub exp: usize, // Required (validate_exp defaults to true in validation). Expiration time (as UTC timestamp)
    pub iat: usize, // Optional. Issued at (as UTC timestamp)
    // iss: String, // Optional. Issuer
    // nbf: usize,  // Optional. Not Before (as UTC timestamp)
    pub sub: String, // Optional. Subject (whom token refers to)
}

pub fn encode_jwt(claims: &Claims, key: &[u8]) -> Result<String, jsonwebtoken::errors::Error> {
    encode(
        &Header::new(Algorithm::HS256),
        &claims,
        &EncodingKey::from_secret(key),

DefectingCat /tower_compat.rs

Last active: 3 months ago

compat module between xitca-http and axum. https://github.com/TechEmpower/FrameworkBenchmarks/blob/db303286a70ce0bd90f2ca02c95b01d7c5456548/frameworks/Rust/xitca-web/src/main_axum.rs

// compat module between xitca-http and axum.
mod tower_compat {
    use core::{cell::RefCell, fmt, future::Future, marker::PhantomData};

    use std::net::SocketAddr;

    use http_body::Body;
    use xitca_http::{
        bytes::Bytes,
        h1::RequestBody,
        http::{Request, RequestExt, Response},
        HttpServiceBuilder,
    };
    use xitca_io::net::io_uring::TcpStream;
    use xitca_service::{fn_build, middleware::UncheckedReady, ready::ReadyService, Service, ServiceExt};
    use xitca_web::service::tower_http_compat::{CompatReqBody, CompatResBody};

    pub struct TowerHttp<S, B> {
        service: RefCell<S>,
        _p: PhantomData<fn(B)>,

DefectingCat /mod.go

Last active: 3 months ago

golang json parse date time

type Datetime struct {
	time.Time
}

func (t *Datetime) UnmarshalJSON(input []byte) error {
	strInput := strings.Trim(string(input), `"`)
	newTime, err := time.Parse("2006-01-02", strInput)
	if err != nil {
		return err
	}

	t.Time = newTime
	return nil
}

DefectingCat /binding_arr.rs

Last active: 5 months ago

rust at operator binding

fn main() {
    let strs = ["hello world", "1", "hello", "world"];
    let mut remaining: &[&str] = &strs;

    while let [current, tail @ ..] = remaining {
        println!("{} - {:?}", current, tail);
        remaining = tail;
    }
    println!("The real strs {:?}", strs);
}

DefectingCat /.gitlab-ci.yml

Last active: 6 months ago

gitlab ci docker runner use ssh private key

before_script:
  - "command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )"
  - eval $(ssh-agent -s)
  - chmod 400 "$SSH_PRIVATE_KEY"
  - ssh-add "$SSH_PRIVATE_KEY"
  - mkdir -p ~/.ssh
  - chmod 700 ~/.ssh

DefectingCat /daemon.json

Last active: 6 months ago

docker daemon

{
  "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"],
  "insecure-registries" : ["192.168.1.57:8004"],
  "data-root": "/home/xfy/data/docker-var"
}

DefectingCat /validator.rs

Last active: 6 months ago

axum json and form validator

use axum::{
    async_trait,
    extract::{rejection::FormRejection, FromRequest, Request},
    Form, Json,
};
use once_cell::sync::Lazy;
use regex::Regex;
use serde::de::DeserializeOwned;
use validator::Validate;

use crate::error::{AppError, AppResult};

#[derive(Debug, Clone, Copy, Default)]
pub struct ValidatedForm<T>(pub T);

#[async_trait]
impl<T, S> FromRequest<S> for ValidatedForm<T>
where
    T: DeserializeOwned + Validate,
    S: Send + Sync,

DefectingCat /jwt.rs

Last active: 6 months ago

rust jsonwebtoken

use std::sync::OnceLock;

use jsonwebtoken::{DecodingKey, EncodingKey, Header};
use serde::{Deserialize, Serialize};

pub struct Keys {
    pub encoding: EncodingKey,
    pub decoding: DecodingKey,
}
impl Keys {
    fn new(secret: &[u8]) -> Self {
        Self {
            encoding: EncodingKey::from_secret(secret),
            decoding: DecodingKey::from_secret(secret),
        }
    }
}

static KEYS: OnceLock<Keys> = OnceLock::new();
pub fn get_jwt_keys() -> &'static Keys {

DefectingCat /password.rs

Last active: 6 months ago

argon2 password hash

use anyhow::{anyhow, Context};
use tokio::task;

use argon2::password_hash::SaltString;
use argon2::{password_hash, Argon2, PasswordHash, PasswordHasher, PasswordVerifier};

/// η”Ÿζˆ hash
///
/// ## Arguments
///
/// - `password`: η”¨ζˆ·θΎ“ε…₯ηš„ζ˜Žζ–‡ε―†η 
pub async fn hash(password: String) -> anyhow::Result<String> {
    task::spawn_blocking(move || {
        let salt = SaltString::generate(rand::thread_rng());
        Ok(Argon2::default()
            .hash_password(password.as_bytes(), &salt)
            .map_err(|e| anyhow!(e).context("failed to hash password"))?
            .to_string())
    })
    .await

DefectingCat /full.rs

Last active: 6 months ago

axum routes nest and trace layer

use std::{collections::HashMap, time::Duration};

use axum::{
    async_trait,
    body::Bytes,
    extract::{FromRequestParts, MatchedPath, Path, Request},
    http::{request::Parts, HeaderMap, StatusCode, Uri},
    middleware,
    response::{IntoResponse, Response},
    routing::get,
    RequestPartsExt, Router,
};
use tower::ServiceBuilder;
use tower_http::{
    classify::ServerErrorsFailureClass, compression::CompressionLayer, cors::CorsLayer,
    timeout::TimeoutLayer, trace::TraceLayer,
};
use tracing::{error, info, info_span, Span};

use crate::{middlewares::add_version, AppState};

DefectingCat /mod.rs

Last active: 6 months ago

axum routes nest and trace layer

pub fn routes() -> Router<AppState> {
    Router::new()
        .route("/", get(hello).post(hello))
        .nest("/:version/", users::routes())
        .fallback(fallback)
        .layer(
            ServiceBuilder::new()
                .layer(middleware::from_fn(add_version))
                .layer(CorsLayer::permissive())
                .layer(TimeoutLayer::new(Duration::from_secs(15)))
                .layer(CompressionLayer::new()),
        )
        .layer(
            TraceLayer::new_for_http()
                .make_span_with(|request: &Request<_>| {
                    let matched_path = request
                        .extensions()
                        .get::<MatchedPath>()
                        .map(MatchedPath::as_str);
                    info_span!(