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
|
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,
token_endpoint: String,
s3_bucket: String,
media_url: String,
}
impl SiteConfig {
pub fn bind(&self) -> &str {
&self.bind
}
/// 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
}
/// Base URL for S3 bucket assets.
pub fn media_url(&self) -> &str {
&self.media_url
}
}
#[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"),
};
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
}
|