Compare commits
10 Commits
5bb55e9177
...
main
Author | SHA1 | Date | |
---|---|---|---|
45755c498c | |||
452c292570 | |||
64ccd0a51b | |||
2b03c60ef2 | |||
c962a53bbe | |||
fab52f7f80 | |||
6cab009b3a | |||
41c111569d | |||
baf9d87556 | |||
b4938c904e |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/target
|
||||
.idea
|
@ -1,7 +1,9 @@
|
||||
FROM rust:1.75.0 as builder
|
||||
|
||||
WORKDIR /usr/src/chaospott-status
|
||||
COPY . .
|
||||
# git clone anstatt copy, damit Dockerfile in extra repository liegen kann. Danke @a3x
|
||||
# git ist im image enthalten, da rust image hiervon abstammt https://hub.docker.com/layers/library/buildpack-deps/bookworm-scm/images/sha256-25f20fd3e3c8be1e9626c246986beb400ccfe19b0ab13d57127399927801d499?context=explore
|
||||
RUN git clone https://git.chaospott.de/Chaospott/chaospott-status.git .
|
||||
|
||||
# use musl to create a truly static binary https://bxbrenden.github.io/
|
||||
RUN rustup component add rust-std-x86_64-unknown-linux-musl
|
||||
|
13
README.md
13
README.md
@ -16,6 +16,19 @@ To start the app, just `cargo run --release` as usual.
|
||||
|
||||
Find scripts for testing in [`scripts/`](scripts/).
|
||||
|
||||
## Build / Deploy
|
||||
|
||||
While building the Docker Container, the sources will be cloned from this repository.
|
||||
|
||||
Set the environment variables to set the update secrets.
|
||||
|
||||
```shell
|
||||
export consumer_key=foo
|
||||
export consumer_secret=bar
|
||||
|
||||
docker compose up
|
||||
```
|
||||
|
||||
## Need help?
|
||||
|
||||
Ask chfkch, starblue, m0veax, CyReVolt or your favourite Rustacean. 🦀
|
||||
|
24
docker-compose.yaml
Normal file
24
docker-compose.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
version: '3'
|
||||
services:
|
||||
spaceapi-v2:
|
||||
build: .
|
||||
container_name: spaceapi-v2
|
||||
restart: always
|
||||
labels:
|
||||
- traefik.frontend.rule=Host:status-v2.chaospott.de
|
||||
- traefik.port=3000
|
||||
- traefik.frontend.passHostHeader=true
|
||||
- traefik.enable=true
|
||||
- traefik.frontend.headers.customResponseHeaders=Access-Control-Allow-Origin:*
|
||||
# NOTE: This is for Traefik v2, apparently.
|
||||
- traefik.http.middlewares.cors.headers.accesscontrolallowmethods=GET,OPTIONS,PUT
|
||||
- traefik.http.middlewares.cors.headers.accesscontrolalloworiginlist=https://chaospott.de
|
||||
- traefik.http.middlewares.cors.headers.accesscontrolmaxage=100
|
||||
- traefik.http.middlewares.cors.headers.addvaryheader=true
|
||||
networks:
|
||||
- extern
|
||||
|
||||
networks:
|
||||
extern:
|
||||
external:
|
||||
name: web
|
@ -1,4 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
## starte server mit env vars passend zum ersten aufruf
|
||||
## TODO das muss noch gescripted werden
|
||||
|
||||
# should return 201 if env vars are set like this payload states
|
||||
curl -XPOST \
|
||||
-H "Content-Type: application/json" \
|
||||
--data '{"consumer_key": "","consumer_secret":"","aerie":true }' \
|
||||
http://localhost:3000/api/update
|
||||
--data '{"consumer_key": "test123","consumer_secret":"123test","aerie":true }' \
|
||||
http://localhost:3000/api/update -vvv
|
||||
|
||||
#should return 403
|
||||
curl -XPOST \
|
||||
-H "Content-Type: application/json" \
|
||||
--data '{"consumer_key": "foo","consumer_secret":"bar","aerie":true }' \
|
||||
http://localhost:3000/api/update -vvv
|
||||
|
50
src/main.rs
50
src/main.rs
@ -1,8 +1,11 @@
|
||||
use std::fs::File;
|
||||
use std::env;
|
||||
use std::fs::{read_to_string, File};
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
|
||||
use axum::{
|
||||
http::StatusCode,
|
||||
body::Body,
|
||||
http::{Response, StatusCode},
|
||||
routing::{get, post},
|
||||
Json, Router,
|
||||
};
|
||||
@ -16,6 +19,13 @@ const STATUS_FILE: &str = "status.json";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
if env::var("consumer_key").is_err() {
|
||||
panic!("env var consumer_key must be set");
|
||||
}
|
||||
if env::var("consumer_secret").is_err() {
|
||||
panic!("env var consumer_secret must be set");
|
||||
}
|
||||
|
||||
let app = Router::new()
|
||||
.route("/status.json", get(root))
|
||||
.route("/api/update", post(the_doors));
|
||||
@ -36,6 +46,15 @@ fn init_status() -> Status {
|
||||
status::status(sensors, state)
|
||||
}
|
||||
|
||||
// check given secret
|
||||
// https://www.youtube.com/watch?v=aHKWVLH-ibY
|
||||
fn auth(p: &TheDoors) -> bool {
|
||||
let consumer_secret = env::var("consumer_secret").unwrap();
|
||||
let consumer_key = env::var("consumer_key").unwrap();
|
||||
|
||||
p.consumer_secret == consumer_secret && p.consumer_key == consumer_key
|
||||
}
|
||||
|
||||
// Write status to file and return JSON string.
|
||||
fn write_status(s: Status) -> String {
|
||||
let s = serde_json::to_string(&s).unwrap();
|
||||
@ -46,12 +65,17 @@ fn write_status(s: Status) -> String {
|
||||
|
||||
// Just output the current file. We assume it to be consistent.
|
||||
// It may cease to or not yet exist. Then create an initial status and persist.
|
||||
async fn root() -> String {
|
||||
if std::path::Path::new(STATUS_FILE).exists() {
|
||||
return std::fs::read_to_string(STATUS_FILE).unwrap_or(String::from("KAPOTT"));
|
||||
}
|
||||
let s = init_status();
|
||||
write_status(s)
|
||||
async fn root() -> Response<Body> {
|
||||
let res = if std::path::Path::new(STATUS_FILE).exists() {
|
||||
read_to_string(STATUS_FILE).unwrap_or(String::from("KAPOTT"))
|
||||
} else {
|
||||
write_status(init_status())
|
||||
};
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(Body::from(res))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
// Input type for the API: Both fields are optional.
|
||||
@ -59,13 +83,19 @@ async fn root() -> String {
|
||||
struct TheDoors {
|
||||
aerie: Option<bool>,
|
||||
cellar: Option<bool>,
|
||||
consumer_key: String,
|
||||
consumer_secret: String,
|
||||
}
|
||||
|
||||
// The door can see through your soul.
|
||||
// https://www.youtube.com/watch?v=bDQDp00oTP4
|
||||
async fn the_doors(Json(payload): Json<TheDoors>) -> StatusCode {
|
||||
let status: Status = if std::path::Path::new(STATUS_FILE).exists() {
|
||||
let contents = std::fs::read_to_string(STATUS_FILE).expect("FCKAFD");
|
||||
if !auth(&payload) {
|
||||
return StatusCode::FORBIDDEN;
|
||||
}
|
||||
|
||||
let status: Status = if Path::new(STATUS_FILE).exists() {
|
||||
let contents = read_to_string(STATUS_FILE).expect("FCKAFD");
|
||||
serde_json::from_str(&contents).unwrap_or_else(|_| init_status())
|
||||
} else {
|
||||
init_status()
|
||||
|
Reference in New Issue
Block a user