summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: a3a7f76da6f9c25ac752a7c235e237003f6fdacd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use actix_web::client::Client;
use actix_web::{middleware, web, App, HttpServer};

use rusoto_core::Region;
use rusoto_s3::S3Client;

use serde::{Deserialize, Serialize};

mod media;
mod micropub;
mod oauth;

#[derive(Serialize, Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct SiteConfig {
    bind: String,

    media_url: String,
    token_endpoint: String,
    s3_bucket: String,

    default_width: u32,
    default_height: u32,
}

impl SiteConfig {
    pub fn bind(&self) -> &str {
        &self.bind
    }

    /// Base URL for serving files
    pub fn media_url(&self) -> &str {
        &self.media_url
    }

    /// The URI to use to validate an access token.
    pub fn token_endpoint(&self) -> &str {
        &self.token_endpoint
    }

    /// S3 output bucket
    pub fn s3_bucket(&self) -> &str {
        &self.s3_bucket
    }

    pub fn default_width(&self) -> u32 {
        self.default_width
    }

    pub fn default_height(&self) -> u32 {
        self.default_height
    }
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    std::env::set_var("RUST_LOG", "actix_web=info");
    env_logger::init();

    let site_config = SiteConfig {
        bind: std::env::var("BIND").unwrap_or_else(|_| "127.0.0.1:8180".to_string()),
        s3_bucket: std::env::var("S3_BUCKET").expect("Expected S3_BUCKET env var"),
        media_url: std::env::var("MEDIA_URL").expect("Expected MEDIA_URL env var"),
        token_endpoint: std::env::var("TOKEN_ENDPOINT").expect("Expected TOKEN_ENDPOINT env var"),
        default_width: std::env::var("DEFAULT_WIDTH").ok().and_then(|v| v.parse().ok()).unwrap_or(1000),
        default_height: std::env::var("DEFAULT_HEIGHT").ok().and_then(|v| v.parse().ok()).unwrap_or(0),
    };

    let bind = site_config.bind().to_string();
    let s3_client = S3Client::new(Region::default());
    let token_endpoint = site_config.token_endpoint().to_string();

    HttpServer::new(move || {
        App::new()
            .wrap(middleware::Logger::default())
            .data(Client::new())
            .data(site_config.clone())
            .data(s3_client.clone())
            .data(oauth::VerificationService::new(token_endpoint.clone()))
            .service(
                web::resource("/micropub/media").route(web::post().to(micropub::handle_upload)),
            )
            .configure(media::configure)
    })
    .bind(bind)?
    .run()
    .await
}