/* * Copyright (C) 2022 Aravinth Manivannan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use actix_web::HttpMessage; use actix_web::{web, Error, HttpRequest, HttpResponse, Responder}; use actix_web_httpauth::middleware::HttpAuthentication; use serde::{Deserialize, Serialize}; use super::httpauth; use super::SignedInUser; use super::API_V1_ROUTES; use crate::AppCtx; pub mod routes { use super::*; #[derive(Debug, Eq, PartialEq, Deserialize, Serialize)] pub struct Report { pub upload: &'static str, } impl Report { pub const fn new() -> Self { Self { upload: "/api/v1/report/upload", } } } } pub fn services(cfg: &mut web::ServiceConfig) { cfg.service(upload); } #[derive(Serialize, PartialEq, Eq, Deserialize, Debug, Default)] struct Client { #[serde(rename(deserialize = "User-Agent", serialize = "User-Agent"))] user_agent: String, version: String, user_id: String, } #[derive(Serialize, PartialEq, Eq, Deserialize, Debug, Default)] struct Report { user_text: String, app: String, data: Client, labels: Option>, logs: Vec, files: Vec, #[serde(rename(deserialize = "logErrors", serialize = "logErrors"))] log_errors: Option, #[serde(rename(deserialize = "fileErrors", serialize = "fileErrors"))] file_errors: Option, report_url: Option, listing_url: String, } #[actix_web_codegen_const_routes::post( path = "API_V1_ROUTES.report.upload", wrap = "HttpAuthentication::basic(httpauth)" )] async fn upload( _req: HttpRequest, ctx: AppCtx, payload: web::Json, ) -> Result { ctx.gitea.report(&payload).await; Ok(HttpResponse::Ok()) } #[cfg(test)] pub mod tests { use actix_web::{ http::{header, StatusCode}, test, App, }; use super::*; use crate::*; #[actix_rt::test] async fn index_works() { // const USERNAME: &str = "index_works"; // const PASSWORD: &str = "23k4j;123k4j1;l23kj4"; let settings = Settings::new().unwrap(); let creds = settings.creds.get(0).unwrap().clone(); let auth = format!( "Basic {}", base64::encode(format!("{}:{}", creds.username, creds.password)) ); // let settings = Settings::new().unwrap(); let ctx = AppCtx::new(crate::ctx::Ctx::new(&settings).await); let app = test::init_service( App::new() .app_data(ctx.clone()) .configure(crate::routes::services), ) .await; let def_payload = Report::default(); let upload_resp = test::call_service( &app, test::TestRequest::post() .append_header((header::AUTHORIZATION, auth)) .uri(API_V1_ROUTES.report.upload) .set_json(&def_payload) .to_request(), ) .await; if upload_resp.status() != StatusCode::OK { let resp_err: crate::errors::ErrorToResponse = test::read_body_json(upload_resp).await; panic!("{:?}", resp_err.error); } } }