use lazy_static::lazy_static;
use std::env;
use std::sync::{Arc, RwLock};
use actix_web::HttpMessage;
use actix_web::{HttpRequest, HttpResponse};
use serde::Serialize;
use tera::{Context as TeraContext, Tera};
use crate::commons::read_env;
use crate::core::auth0;
use crate::core::buildinfo;
use crate::core::error2::Result;
use crate::core::error2::{self};
lazy_static! {
static ref BUILD_TIME: String = buildinfo::timestamp();
static ref BUILD_VERSION: String = buildinfo::git_version();
static ref START_UPTIME: String = read_env("STARTUP_TIME", &buildinfo::timestamp());
static ref ENV_NAME: String = read_env("ENV_NAME", "LOCAL");
static ref APP_NAME: String = read_env("APP_NAME", "APP_NAME_UNSET");
static ref GRAPHQL_SERVER: String = read_env("RS_ENV_GRAPHQL_SERVER", "");
static ref STATIC_SERVER: String = read_env("RS_ENV_STATIC_SERVER", "");
}
pub trait Render {
fn render(&self, code: usize, template: &str, context: TeraContext) -> Result<HttpResponse>;
fn json<S: Serialize>(&self, code: usize, payload: S) -> Result<HttpResponse>;
fn text(&self, code: usize, payload: &str) -> Result<HttpResponse>;
fn redirect(&self, location: &str) -> Result<HttpResponse>;
}
impl Render for HttpRequest {
fn render(
&self,
code: usize,
template: &str,
mut context: TeraContext,
) -> Result<HttpResponse> {
let _tera: Option<&Arc<RwLock<Tera>>> = self.app_data();
context.insert("BUILD_TIME", &*BUILD_TIME);
context.insert("BUILD_VERSION", &*BUILD_VERSION);
context.insert("STARTUP_TIME", &*START_UPTIME);
context.insert("APP_NAME", &*APP_NAME);
context.insert("ENV_NAME", &*ENV_NAME);
context.insert("REQUEST_URI", self.path());
context.insert("GRAPHQL_SERVER", &*GRAPHQL_SERVER);
context.insert("STATIC_SERVER", &*STATIC_SERVER);
for (k, v) in env::vars() {
if k.starts_with("JELLY_") {
context.insert(&k, &v);
}
}
if let Some(requestor) = self.extensions().get::<auth0::Requestor>() {
if let Some(user_details) = requestor.get_user() {
context.insert("USER_ID", &user_details.user_id());
context.insert("USER_NAME", &user_details.user_name);
context.insert("USER_INFO", &auth0::UserInfo::build(user_details));
context.insert("IS_AUTHENTICATED", &true);
}
}
let _query_string = self.query_string();
if let Some(eng) = _tera {
let engine = eng
.read()
.map_err(|e| error2::Error::throw("Error acquiring template read lock", Some(e)))?;
let body = match engine.render(template, &context) {
Ok(body) => body,
Err(e) => {
return Err(error2::Error::throw(
"Unable to locate Templates cache",
Some(e),
));
}
};
Ok(match code {
200 | 400 | 404 => HttpResponse::Ok(),
_ => HttpResponse::Ok(),
}
.content_type("text/html; charset=utf-8")
.body(body))
} else {
Err(error2::Error::throw(
"Unable to locate Templates cache",
Some(""),
))
}
}
fn json<S: Serialize>(&self, code: usize, payload: S) -> Result<HttpResponse> {
let o = serde_json::to_string(&payload).map_err(|e| error2::Error::throw("", Some(e)))?;
Ok(match code {
404 => HttpResponse::NotFound(),
400 => HttpResponse::Ok(),
_ => HttpResponse::Ok(),
}
.content_type("application/json")
.body(o))
}
fn text(&self, code: usize, payload: &str) -> Result<HttpResponse> {
Ok(match code {
404 => HttpResponse::NotFound(),
400 => HttpResponse::Ok(),
_ => HttpResponse::Ok(),
}
.content_type("text/plain")
.body(payload.to_string()))
}
fn redirect(&self, location: &str) -> Result<HttpResponse> {
Ok(HttpResponse::Found()
.append_header((actix_web::http::header::LOCATION, location))
.finish())
}
}