use crate::{appstate::AppState, errors::AtomicServerResult};
use actix_web::{web, HttpResponse};
use atomic_lib::{commit::CommitOpts, parse::parse_json_ad_commit_resource, Commit, Storelike};
#[tracing::instrument(skip(appstate))]
pub async fn post_commit(
appstate: web::Data<AppState>,
body: String,
) -> AtomicServerResult<HttpResponse> {
if appstate.config.opts.slow_mode {
use rand::Rng;
let mut rng = rand::thread_rng();
let random_number = rng.gen_range(100..1000);
tokio::time::sleep(tokio::time::Duration::from_millis(random_number)).await;
}
let store = &appstate.store;
let mut builder = HttpResponse::Ok();
let incoming_commit_resource = parse_json_ad_commit_resource(&body, store)?;
let incoming_commit = Commit::from_resource(incoming_commit_resource)?;
if !incoming_commit.subject.contains(
&store
.get_self_url()
.ok_or("Cannot apply commits to this store. No self_url is set.")?,
) {
return Err("Subject of commit should be sent to other domain - this store can not own this resource.".into());
}
let opts = CommitOpts {
validate_schema: true,
validate_signature: true,
validate_timestamp: true,
validate_rights: true,
validate_previous_commit: false,
validate_for_agent: Some(incoming_commit.signer.to_string()),
update_index: true,
};
let commit_response = incoming_commit.apply_opts(store, &opts)?;
let message = commit_response.commit_resource.to_json_ad()?;
Ok(builder.body(message))
}