Skip to content

Commit

Permalink
Refactor code, remove binary addition and add docstrings
Browse files Browse the repository at this point in the history
Remove temporary linux build GH action
  • Loading branch information
dormant-user committed Feb 17, 2024
1 parent c7f5d2c commit 6088f95
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 161 deletions.
113 changes: 0 additions & 113 deletions .github/workflows/temp-linux.yml

This file was deleted.

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ path = "src/lib.rs"
name = "rustream"
path = "src/main.rs"

# [build]
# https://docs.rs/releases/queue
# https://docs.rs/about/metadata
# https://doc.rust-lang.org/cargo/reference/config.html?highlight=RUSTDOCFLAGS
# export RUSTDOCFLAGS="document-private-items no-deps"
# rustdocflags = ["document-private-items no-deps"]
[package.metadata.docs.rs]
rustdoc-args = ["--document-private-items"]

[dependencies]
actix-rt = "2.9.0"
Expand Down
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# RuStream

[![made-with-rust](https://img.shields.io/badge/Made%20with-Rust-black?style=for-the-badge&logo=Rust)][rust]
[![made-with-rust][rust-logo]][rust-src-page]

[![build](https://github.com/thevickypedia/RuStream/actions/workflows/rust.yml/badge.svg)][build]
[![build][gh-logo]][build]
[![crates.io][crates-logo]][crates]
[![docs.rs][docs-logo]][docs]

#### Summary
[`RuStream`][1] is an application written in Rust to stream videos using Actix API via authenticated sessions.
[`RuStream`][repo] is an application written in Rust to stream videos using Actix API via authenticated sessions.

## Usage

Expand Down Expand Up @@ -63,7 +65,7 @@ async fn main() {
- `--version` / `-v` - Get package version

#### Config file
[RuStream][1] requires a JSON file with secrets loaded as key-value paris.
[RuStream][repo] requires a JSON file with secrets loaded as key-value paris.

<details>
<summary><i><strong>Sample content of JSON file</strong></i></summary>
Expand Down Expand Up @@ -96,9 +98,16 @@ cargo clippy --no-deps --fix --allow-dirty

&copy; Vignesh Rao

Licensed under the [MIT License][2]
Licensed under the [MIT License][license]

[1]: https://github.com/thevickypedia/RuStream
[2]: https://github.com/thevickypedia/RuStream/blob/main/LICENSE
[repo]: https://github.com/thevickypedia/RuStream
[license]: https://github.com/thevickypedia/RuStream/blob/main/LICENSE
[build]: https://github.com/thevickypedia/RuStream/actions/workflows/rust.yml
[rust]: https://www.rust-lang.org/
[rust-src-page]: https://www.rust-lang.org/
[rust-logo]: https://img.shields.io/badge/Made%20with-Rust-black?style=for-the-badge&logo=Rust
[gh-logo]: https://github.com/thevickypedia/RuStream/actions/workflows/rust.yml/badge.svg
[docs-logo]: https://docs.rs/RuStream/badge.svg
[docs]: https://docs.rs/RuStream
[crates]: https://crates.io/crates/RuStream
[gh-checks]: https://github.com/thevickypedia/RuStream/actions/workflows/rust.yml
[crates-logo]: https://img.shields.io/crates/v/RuStream.svg
20 changes: 9 additions & 11 deletions src/constant.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
use std::{env, path};
use std::env;
use std::collections::HashMap;
use std::sync::Mutex;

use fernet::Fernet;
use lazy_static::lazy_static;

pub fn get_binary() -> String {
let binary = env::args().next().unwrap();
path::Path::new(&binary).file_name().unwrap().to_str().unwrap().to_string()
}

/// Struct to store the cargo information
/// Struct to store the cargo information gathered at compile time using the `env!` macro.
#[derive(Debug)]
pub struct Cargo {
pub binary: String,
pub crate_name: String,
pub manifest_dir: String,
pub authors: Vec<String>,
Expand All @@ -36,7 +30,6 @@ pub struct Cargo {
/// - [GitHub Issues](https://github.com/rust-lang/cargo/issues/11966#issue-1664748892)
pub fn build_info() -> Cargo {
let cargo = Cargo {
binary: get_binary(),
crate_name: env!("CARGO_CRATE_NAME").to_string(),
manifest_dir: env!("CARGO_MANIFEST_DIR").to_string(),
authors: env!("CARGO_PKG_AUTHORS").split(',').map(String::from).collect(),
Expand All @@ -54,11 +47,16 @@ pub fn build_info() -> Cargo {
}

lazy_static! {
pub static ref FERNET: Fernet = Fernet::new(&generate_key()).unwrap();
pub static ref FERNET: Fernet = Fernet::new(&fernet_key()).unwrap();
}

/// Create a [Fernet](https://docs.rs/fernet/latest/fernet/) object to encrypt and decrypt session token.
fn generate_key() -> String {
///
/// Generates a random key, that can be safely passed to `Fernet::new()`
///
/// # Returns
/// Random key as a `String`
fn fernet_key() -> String {
Fernet::generate_key()
}

Expand Down
31 changes: 18 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
#![allow(rustdoc::bare_urls)]
#![doc = include_str!("../README.md")]

#[macro_use]
extern crate actix_web;

use std::io;

use actix_web::{App, HttpServer, middleware, web};
use rand::prelude::SliceRandom;
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use rand::prelude::SliceRandom;

mod squire;
mod jinja;
/// Module to load all the static values and required structs during startup.
mod constant;
/// Module to read the HTML files and load as Jinja templates.
mod jinja;
/// Module for all the API entry points.
mod routes;
/// Module to store all the helper functions.
mod squire;

/// Contains entrypoint and initializer settings to trigger the asynchronous HTTPServer
///
Expand All @@ -33,8 +40,8 @@ pub async fn start() -> io::Result<()> {
let cargo = constant::build_info();
let args = squire::parser::arguments();

squire::startup::init_logger(args.debug, &cargo);
println!("{}[v{}] - {}", cargo.pkg_name, cargo.pkg_version, cargo.description);
squire::startup::init_logger(args.debug, &cargo.crate_name);
println!("{}[v{}] - {}", &cargo.pkg_name, &cargo.pkg_version, &cargo.description);
let arts = [squire::ascii_art::DOG, squire::ascii_art::DOLPHIN, squire::ascii_art::HORSE];
println!("{}", arts.choose(&mut rand::thread_rng()).unwrap());

Expand All @@ -45,7 +52,7 @@ pub async fn start() -> io::Result<()> {
let template_clone = template.clone();
let host = format!("{}:{}", config.video_host, config.video_port);
log::info!("{} [workers:{}] running on http://{} (Press CTRL+C to quit)",
cargo.pkg_name, config.workers, host);
&cargo.pkg_name, &config.workers, &host);
/*
|| syntax is creating a closure that serves as the argument to the HttpServer::new() method.
The closure is defining the configuration for the Actix web server.
Expand Down Expand Up @@ -75,16 +82,14 @@ pub async fn start() -> io::Result<()> {
if config.cert_file.exists() && config.key_file.exists() {
log::info!("Binding SSL certificate to serve over HTTPS");
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder
.set_private_key_file(&config.key_file, SslFiletype::PEM)
.unwrap();
builder.set_private_key_file(&config.key_file, SslFiletype::PEM).unwrap();
builder.set_certificate_chain_file(&config.cert_file).unwrap();
server.bind_openssl(host, builder)?
.run()
.await
.run()
.await
} else {
server.bind(host)?
.run()
.await
.run()
.await
}
}
9 changes: 9 additions & 0 deletions src/routes/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ pub struct DetailError {
///
/// * `config` - Configuration data for the application.
/// * `request` - Actix HttpRequest containing information about the incoming request.
///
/// # Returns
///
/// * `200` - HttpResponse with a session-token and redirect URL to the `/home` entrypoint.
/// * `401` - HttpResponse with an error message for failed authentication.
#[post("/login")]
pub async fn login(config: web::Data<Arc<squire::settings::Config>>, request: HttpRequest) -> HttpResponse {
let verified = routes::authenticator::verify_login(&request, &config);
Expand Down Expand Up @@ -145,6 +150,10 @@ pub async fn home(config: web::Data<Arc<squire::settings::Config>>,
/// # Arguments
///
/// * `request` - Actix HttpRequest containing information about the incoming request.
///
/// # Returns
///
/// HttpResponse with either a session expiry or unauthorized message.
#[get("/error")]
pub async fn error(environment: web::Data<Arc<Mutex<minijinja::Environment<'static>>>>,
request: HttpRequest) -> HttpResponse {
Expand Down
16 changes: 11 additions & 5 deletions src/routes/authenticator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ pub fn verify_token(request: &HttpRequest, config: &Data<Arc<squire::settings::C
return AuthToken {
ok: false,
detail: "Server doesn't recognize your session".to_string(),
username: "NA".to_string()
username: "NA".to_string(),
};
}
if let Some(cookie) = request.cookie("session_token") {
Expand All @@ -157,7 +157,9 @@ pub fn verify_token(request: &HttpRequest, config: &Data<Arc<squire::settings::C
// Max time and expiry for session token is set in the Cookie, but this is a fallback mechanism
if stored_key != *cookie_key {
return AuthToken {
ok: false, detail: "Invalid session token".to_string(), username
ok: false,
detail: "Invalid session token".to_string(),
username,
};
}
if current_time - timestamp > config.session_duration as i64 {
Expand All @@ -166,16 +168,20 @@ pub fn verify_token(request: &HttpRequest, config: &Data<Arc<squire::settings::C
AuthToken {
ok: true,
detail: format!("Session valid for {}s", timestamp + config.session_duration as i64 - current_time),
username
username,
}
} else {
AuthToken {
ok: false, detail: "Invalid session token".to_string(), username: "NA".to_string()
ok: false,
detail: "Invalid session token".to_string(),
username: "NA".to_string(),
}
}
} else {
AuthToken {
ok: false, detail: "Session information not found".to_string(), username: "NA".to_string()
ok: false,
detail: "Session information not found".to_string(),
username: "NA".to_string(),
}
}
}
3 changes: 3 additions & 0 deletions src/routes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/// Module for the primary and health check entrypoints.
pub mod basics;
/// Module for all the video based entrypoints.
pub mod video;
/// Module for `/home`, `/login`, `/logout` and `/error` entrypoints.
pub mod auth;
pub mod authenticator;
pub mod images;
1 change: 0 additions & 1 deletion src/squire/secure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use base64::{Engine as _, engine::general_purpose::URL_SAFE};
use rand::{Rng, thread_rng};
use sha2::{Digest, Sha512};


/// Calculates the SHA-512 hash value for the given payload.
///
/// # Arguments
Expand Down
4 changes: 2 additions & 2 deletions src/squire/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ pub struct Config {
pub website: Vec<String>,

// Path to the full certificate chain file for SSL certificate
#[serde(default="default_ssl")]
#[serde(default = "default_ssl")]
pub cert_file: path::PathBuf,
// Path to the private key file for SSL certificate
#[serde(default="default_ssl")]
#[serde(default = "default_ssl")]
pub key_file: path::PathBuf
}

Expand Down
Loading

0 comments on commit 6088f95

Please sign in to comment.