Merge pull request 'update-sqlx' (#18) from update-sqlx into master
ci/woodpecker/push/woodpecker Pipeline was successful Details

Reviewed-on: #18
This commit is contained in:
Aravinth Manivannan 2023-10-17 22:48:41 +05:30
commit ca34646b0c
35 changed files with 1418 additions and 431 deletions

1
.gitignore vendored
View File

@ -17,3 +17,4 @@ __pycache__/
*.py[cod]
*$py.class
src/sailfish/
src/libcachebust_data.json

View File

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_admins \n (name , password, secret) VALUES ($1, $2, $3)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text",
"Varchar"
]
},
"nullable": []
},
"hash": "0d22134cc5076304b7895827f006ee8269cc500f400114a7472b83f0f1c568b5"
}

View File

@ -0,0 +1,26 @@
{
"db_name": "PostgreSQL",
"query": "SELECT name, id FROM survey_campaigns ORDER BY id;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "id",
"type_info": "Uuid"
}
],
"parameters": {
"Left": []
},
"nullable": [
false,
false
]
},
"hash": "10924f3726a45c3bc709118375d691f2867bbcd50dc47a000ac9bf3ff878c97c"
}

View File

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_responses (\n user_id,\n campaign_id,\n device_user_provided,\n device_software_recognised,\n threads,\n submitted_at,\n submission_bench_type_id\n ) VALUES (\n $1, $2, $3, $4, $5, $6,\n (SELECT ID FROM survey_bench_type WHERE name = $7)\n )\n RETURNING ID;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
}
],
"parameters": {
"Left": [
"Uuid",
"Uuid",
"Varchar",
"Varchar",
"Int4",
"Timestamptz",
"Text"
]
},
"nullable": [
false
]
},
"hash": "117f1ae18f6a3936f27446b75b555951fe217d3a3cefe40a006fdd3cb31f0ac4"
}

View File

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT password FROM survey_admins WHERE name = ($1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "password",
"type_info": "Text"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false
]
},
"hash": "1373df097fa0e58b23a374753318ae53a44559aa0e7eb64680185baf1c481723"
}

View File

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n survey_admins.name\n FROM\n survey_admins\n INNER JOIN survey_campaigns ON\n survey_admins.ID = survey_campaigns.user_id\n WHERE\n survey_campaigns.ID = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false
]
},
"hash": "15a8484de6f035e56c34ce3f6979eadea81f125933f76261c8b3c8319d43bbe0"
}

View File

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT name, password FROM survey_admins WHERE email = ($1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "password",
"type_info": "Text"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false,
false
]
},
"hash": "19686bfe8772cbc6831d46d18994e2b9aa40c7181eae9a31e51451cce95f04e8"
}

View File

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "DELETE \n FROM survey_campaigns \n WHERE \n user_id = (\n SELECT \n ID \n FROM \n survey_admins \n WHERE \n name = $1\n )\n AND\n id = ($2)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Uuid"
]
},
"nullable": []
},
"hash": "1972be28a6bda2c3a3764a836e95c8cb0c5db277fc4c8a9b19951a03166c6492"
}

View File

@ -0,0 +1,17 @@
{
"db_name": "PostgreSQL",
"query": "insert into survey_admins \n (name , password, email, secret) values ($1, $2, $3, $4)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text",
"Varchar",
"Varchar"
]
},
"nullable": []
},
"hash": "1b7e17bfc949fa97e8dec1f95e35a02bcf3aa1aa72a1f6f6c8884e885fc3b953"
}

View File

@ -0,0 +1,14 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM survey_admins WHERE name = ($1)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text"
]
},
"nullable": []
},
"hash": "2ccaecfee4d2f29ef5278188b304017719720aa986d680d4727a1facbb869c7a"
}

View File

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "\n INSERT INTO survey_users (created_at, id) VALUES($1, $2)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Timestamptz",
"Uuid"
]
},
"nullable": []
},
"hash": "43b3e771f38bf8059832169227705be06a28925af1b3799ffef5371d511fd138"
}

View File

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS (SELECT 1 from survey_admins WHERE name = $1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
null
]
},
"hash": "536541ecf2e1c0403c74b6e2e09b42b73a7741ae4a348ff539ac410022e03ace"
}

View File

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE survey_admins set password = $1\n WHERE name = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": []
},
"hash": "55dde28998a6d12744806035f0a648494a403c7d09ea3caf91bf54869a81aa73"
}

View File

@ -0,0 +1,61 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n survey_responses.ID,\n survey_responses.device_software_recognised,\n survey_responses.threads,\n survey_responses.user_id,\n survey_responses.submitted_at,\n survey_responses.device_user_provided,\n survey_bench_type.name\n FROM\n survey_responses\n INNER JOIN survey_bench_type ON\n survey_responses.submission_bench_type_id = survey_bench_type.ID\n WHERE\n survey_responses.campaign_id = (\n SELECT ID FROM survey_campaigns\n WHERE\n ID = $1\n AND\n user_id = (SELECT ID FROM survey_admins WHERE name = $2)\n )\n LIMIT $3 OFFSET $4",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "device_software_recognised",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "threads",
"type_info": "Int4"
},
{
"ordinal": 3,
"name": "user_id",
"type_info": "Uuid"
},
{
"ordinal": 4,
"name": "submitted_at",
"type_info": "Timestamptz"
},
{
"ordinal": 5,
"name": "device_user_provided",
"type_info": "Varchar"
},
{
"ordinal": 6,
"name": "name",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Uuid",
"Text",
"Int8",
"Int8"
]
},
"nullable": [
false,
false,
true,
false,
false,
false,
false
]
},
"hash": "57c673ad8529371d77aa305917cf680dd2273ead74c3583ef0322f472b1d33fd"
}

View File

@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT name \n FROM survey_campaigns\n WHERE \n id = $1\n AND\n user_id = (SELECT ID from survey_admins WHERE name = $2)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Uuid",
"Text"
]
},
"nullable": [
false
]
},
"hash": "58ec3b8f98c27e13ec2732f8ee23f6eb9845ac5d9fd97b1e5c9f2eed4b1f5693"
}

View File

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE survey_admins set email = $1\n WHERE name = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "683707dbc847b37c58c29aaad0d1a978c9fe0657da13af99796e4461134b5a43"
}

View File

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS (SELECT 1 from survey_admins WHERE email = $1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
null
]
},
"hash": "6a26daa84578aed2b2085697cb8358ed7c0a50ba9597fd387b4b09b0a8a154db"
}

View File

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT \n name, id\n FROM \n survey_campaigns \n WHERE\n user_id = (\n SELECT \n ID\n FROM \n survey_admins\n WHERE\n name = $1\n )",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "id",
"type_info": "Uuid"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false,
false
]
},
"hash": "70cc7bfc9b6ff5b68db70c069c0947d51bfc4a53cedc020016ee25ff98586c93"
}

View File

@ -0,0 +1,62 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n survey_responses.ID,\n survey_responses.device_software_recognised,\n survey_responses.threads,\n survey_responses.user_id,\n survey_responses.submitted_at,\n survey_responses.device_user_provided,\n survey_bench_type.name\n FROM\n survey_responses\n INNER JOIN survey_bench_type ON\n survey_responses.submission_bench_type_id = survey_bench_type.ID\n WHERE\n survey_bench_type.name = $3\n AND\n survey_responses.campaign_id = (\n SELECT ID FROM survey_campaigns\n WHERE\n ID = $1\n AND\n user_id = (SELECT ID FROM survey_admins WHERE name = $2)\n )\n LIMIT $4 OFFSET $5",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "device_software_recognised",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "threads",
"type_info": "Int4"
},
{
"ordinal": 3,
"name": "user_id",
"type_info": "Uuid"
},
{
"ordinal": 4,
"name": "submitted_at",
"type_info": "Timestamptz"
},
{
"ordinal": 5,
"name": "device_user_provided",
"type_info": "Varchar"
},
{
"ordinal": 6,
"name": "name",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Uuid",
"Text",
"Text",
"Int8",
"Int8"
]
},
"nullable": [
false,
false,
true,
false,
false,
false,
false
]
},
"hash": "74c41e33f91cf31ea13582c8b3ca464544374842450d580517ca2bd01d67402e"
}

View File

@ -0,0 +1,18 @@
{
"db_name": "PostgreSQL",
"query": "\n INSERT INTO survey_campaigns (\n user_id, ID, name, difficulties, created_at\n ) VALUES(\n (SELECT id FROM survey_admins WHERE name = $1),\n $2, $3, $4, $5\n );",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Uuid",
"Varchar",
"Int4Array",
"Timestamptz"
]
},
"nullable": []
},
"hash": "82feafc36533144e49ba374c8c47ca4aa0d6558a9803778ad28cfa7b62382c3e"
}

View File

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n created_at,\n ID\n FROM\n survey_users\n WHERE\n ID = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "created_at",
"type_info": "Timestamptz"
},
{
"ordinal": 1,
"name": "id",
"type_info": "Uuid"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false,
false
]
},
"hash": "858a4c06a5c1ba7adb79bcac7d42d106d09d0cbff10c197f2242dcb5c437a1df"
}

View File

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT difficulties FROM survey_campaigns WHERE id = $1;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "difficulties",
"type_info": "Int4Array"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false
]
},
"hash": "9cdade613ce724631cc3f187510758ee0929e93ff3f8ce81fe35594756644246"
}

View File

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_benches \n (resp_id, difficulty, duration) \n VALUES ($1, $2, $3);",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int4",
"Int4",
"Float4"
]
},
"nullable": []
},
"hash": "a721cfa249acf328c2f29c4cf8c2aeba1a635bcf49d18ced5474caa10b7cae4f"
}

View File

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE survey_admins set secret = $1\n WHERE name = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "ab951c5c318174c6538037947c2f52c61bcfe5e5be1901379b715e77f5214dd2"
}

View File

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n duration,\n difficulty\n FROM\n survey_benches\n WHERE\n resp_id = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "duration",
"type_info": "Float4"
},
{
"ordinal": 1,
"name": "difficulty",
"type_info": "Int4"
}
],
"parameters": {
"Left": [
"Int4"
]
},
"nullable": [
false,
false
]
},
"hash": "b2619292aa6bd1ac38dca152cbe607b795a151ddc212361a3c6d8c70ea1c93eb"
}

View File

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE survey_admins set name = $1\n WHERE name = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "c757589ef26a005e3285e7ab20d8a44c4f2e1cb125f8db061dd198cc380bf807"
}

View File

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT secret FROM survey_admins WHERE name = ($1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "secret",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false
]
},
"hash": "e9cf5d6d8c9e8327d5c809d47a14a933f324e267f1e7dbb48e1caf1c021adc3f"
}

View File

@ -0,0 +1,38 @@
{
"db_name": "PostgreSQL",
"query": "SELECT ID, name, difficulties, created_at FROM survey_campaigns",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Uuid"
},
{
"ordinal": 1,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "difficulties",
"type_info": "Int4Array"
},
{
"ordinal": 3,
"name": "created_at",
"type_info": "Timestamptz"
}
],
"parameters": {
"Left": []
},
"nullable": [
false,
false,
false,
false
]
},
"hash": "efa0e41910fa5bcb187ba9e2fc8f37bee5b25ffe9a2d175f39a69899bc559965"
}

View File

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_response_tokens \n (resp_id, user_id, id)\n VALUES ($1, $2, $3);",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int4",
"Uuid",
"Uuid"
]
},
"nullable": []
},
"hash": "fcdc5fe5d496eb516c805e64ec96d9626b74ab33cd6e75e5a08ae88967403b72"
}

View File

@ -7,15 +7,18 @@ pipeline:
- OPEN_API_DOCS=8e77345f1597e40c2e266cb4e6dee74888918a61
- COMPILED_DATE=2021-07-21
commands:
- curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &&\
- apt update && apt-get -y --no-install-recommends install nodejs tar gpg curl wget
- apt-get update
- apt-get install -y ca-certificates curl gnupg tar wget
- mkdir -p /etc/apt/keyrings
- curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
- NODE_MAJOR=18 echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
- apt-get -y install nodejs npm
- npm install --global yarn
- rustup component add rustfmt
- rustup component add clippy
- make dev-env
- make migrate
- make frontend
- make lint
- make test
build_docker_img:

972
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ documentation = "https://github.con/mCaptcha/survey"
readme = "https://github.com/mCaptcha/survey/blob/master/README.md"
license = "AGPLv3 or later version"
authors = ["realaravinth <realaravinth@batsense.net>"]
edition = "2018"
edition = "2021"
default-run = "survey"
build = "build.rs"
@ -31,26 +31,27 @@ actix-cors = "0.6.1"
actix-files = "0.6.0"
actix-service = "2.0.0"
#actix = "0.12"
actix-web-codegen-const-routes = { version = "0.1.0", tag = "0.1.0", git = "https://github.com/realaravinth/actix-web-codegen-const-routes" }
actix-web-codegen-const-routes = "0.2.0"
#libmcaptcha = { branch = "master", git = "https://github.com/mCaptcha/libmcaptcha", features = ["full"] }
futures = "0.3.15"
sqlx = { version = "0.6.2", features = [ "runtime-actix-rustls", "postgres", "time", "offline" ] }
sqlx = { version = "0.7", features = [ "runtime-tokio-rustls", "postgres", "time", "uuid" ] }
#argon2-creds = "0.2.3"
argon2-creds = { branch = "master", git = "https://github.com/realaravinth/argon2-creds"}
derive_builder = "0.11"
validator = { version = "0.14", features = ["derive"]}
derive_more = "0.99"
config = "0.11"
config = "0.13"
serde = "1"
serde_json = "1"
pretty_env_logger = "0.4"
pretty_env_logger = "0.5"
log = "0.4"
lazy_static = "1.4"
@ -58,10 +59,11 @@ url = { version = "2.2", features = ["serde"] }
urlencoding = "2.1.0"
rand = "0.8"
uuid = { version = "0.8.2", features = ["v4", "serde"] }
uuid = { version = "1.4.1", features = ["v4", "serde"] }
mime_guess = "2.0.3"
rust-embed = "6.0.0"
#libcachebust = "0.3.0"
cache-buster = { git = "https://github.com/realaravinth/cache-buster" }
mime = "0.3.16"
@ -81,10 +83,9 @@ version = "0.2"
[build-dependencies]
sqlx = { version = "0.6.2", features = [ "runtime-actix-rustls", "uuid", "postgres", "time", "offline" ] }
#serde_yaml = "0.8.17"
sqlx = { version = "0.7", features = [ "runtime-tokio-rustls", "uuid", "postgres", "time"] }
serde_json = "1"
#yaml-rust = "0.4.5"
cache-buster = { version = "0.2.0", git = "https://github.com/realaravinth/cache-buster" }
mime = "0.3.16"

View File

@ -1,4 +1,4 @@
FROM node:16.11-bullseye-slim as frontend
FROM node:18-bookworm-slim as frontend
LABEL org.opencontainers.image.source https://github.com/mCaptcha/survey
RUN apt-get update && apt-get install -y make
COPY package.json yarn.lock /src/
@ -8,14 +8,14 @@ RUN yarn install
COPY . .
RUN make frontend
FROM rust:1-slim-bullseye as rust
FROM rust:1-slim-bookworm as rust
WORKDIR /src
RUN apt-get update && apt-get install -y git
COPY . /src
COPY --from=frontend /src/static/cache/bundle /src/static/cache/bundle
RUN cargo build --release
FROM debian:bullseye-slim
FROM debian:bookworm-slim
RUN useradd -ms /bin/bash -u 1001 mcaptcha-survey
WORKDIR /home/mcaptcha-survey
COPY --from=rust /src/target/release/survey /usr/local/bin/

View File

@ -17,12 +17,14 @@
use std::future::Future;
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use sqlx::types::time::OffsetDateTime;
use sqlx::types::Uuid;
use tokio::fs;
use tokio::io::AsyncWriteExt;
use tokio::sync::oneshot::{self, error::TryRecvError, Sender};
use tokio::task::JoinHandle;
use crate::api::v1::admin::campaigns::runners::get_results;
use crate::api::v1::admin::campaigns::SurveyResponse;
@ -213,7 +215,7 @@ impl Archiver {
pub async fn init_archive_job(
self,
data: AppData,
) -> ServiceResult<(Sender<bool>, impl Future)> {
) -> ServiceResult<(Sender<bool>, JoinHandle<()>)> {
let (tx, mut rx) = oneshot::channel();
let job = async move {

View File

@ -41,34 +41,34 @@ impl Server {
format!("{}:{}", self.ip, self.port)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct DatabaseBuilder {
pub port: u32,
pub hostname: String,
pub username: String,
pub password: String,
pub name: String,
pub url: String,
}
impl DatabaseBuilder {
#[cfg(not(tarpaulin_include))]
fn extract_database_url(url: &Url) -> Self {
debug!("Databse name: {}", url.path());
let mut path = url.path().split('/');
path.next();
let name = path.next().expect("no database name").to_string();
DatabaseBuilder {
port: url.port().expect("Enter database port").into(),
hostname: url.host().expect("Enter database host").to_string(),
username: url.username().into(),
url: url.to_string(),
password: url.password().expect("Enter database password").into(),
name,
}
}
}
//
//#[derive(Debug, Clone, Serialize, Deserialize)]
//struct DatabaseBuilder {
// pub port: u32,
// pub hostname: String,
// pub username: String,
// pub password: String,
// pub name: String,
// pub url: String,
//}
//
//impl DatabaseBuilder {
// #[cfg(not(tarpaulin_include))]
// fn extract_database_url(url: &Url) -> Self {
// debug!("Databse name: {}", url.path());
// let mut path = url.path().split('/');
// path.next();
// let name = path.next().expect("no database name").to_string();
// DatabaseBuilder {
// port: url.port().expect("Enter database port").into(),
// hostname: url.host().expect("Enter database host").to_string(),
// username: url.username().into(),
// url: url.to_string(),
// password: url.password().expect("Enter database password").into(),
// name,
// }
// }
//}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Database {
@ -121,111 +121,66 @@ pub struct Settings {
#[cfg(not(tarpaulin_include))]
impl Settings {
pub fn new() -> Result<Self, ConfigError> {
let mut s = Config::new();
// setting default values
#[cfg(test)]
s.set_default("database.pool", 2.to_string())
.expect("Couldn't get the number of CPUs");
let mut s = Config::builder();
const CURRENT_DIR: &str = "./config/default.toml";
const ETC: &str = "/etc/mcaptcha-survey/config.toml";
if let Ok(path) = env::var("ATHENA_CONFIG") {
s.merge(File::with_name(&path))?;
if let Ok(path) = env::var("SURVEY_CONFIG") {
s = s.add_source(File::with_name(&path));
} else if Path::new(CURRENT_DIR).exists() {
// merging default config from file
s.merge(File::with_name(CURRENT_DIR))?;
s = s.add_source(File::with_name(CURRENT_DIR));
} else if Path::new(ETC).exists() {
s.merge(File::with_name(ETC))?;
s = s.add_source(File::with_name(ETC));
} else {
log::warn!("configuration file not found");
}
s.merge(Environment::with_prefix("MCAPTCHA").separator("__"))?;
check_url(&s);
check_uuid(&s);
s = s.add_source(Environment::with_prefix("MCAPTCHA").separator("__"));
match env::var("PORT") {
Ok(val) => {
s.set("server.port", val).unwrap();
s = s.set_override("server.port", val).unwrap();
}
Err(e) => warn!("couldn't interpret PORT: {}", e),
}
match env::var("DATABASE_URL") {
Ok(val) => {
let url = Url::parse(&val).expect("couldn't parse Database URL");
let database_conf = DatabaseBuilder::extract_database_url(&url);
set_from_database_url(&mut s, &database_conf);
Url::parse(&val).expect("couldn't parse Database URL");
s = s.set_override("database.url", val).unwrap();
}
Err(e) => warn!("couldn't interpret DATABASE_URL: {}", e),
}
set_database_url(&mut s);
let settings = s.build()?.try_deserialize::<Settings>()?;
settings.check_url();
settings.check_uuid();
match s.try_into::<Settings>() {
Ok(val) => {
val.publish.create_root_dir();
Ok(val)
},
Err(e) => Err(ConfigError::Message(format!("\n\nError: {}. If it says missing fields, then please refer to https://github.com/mCaptcha/mcaptcha#configuration to learn more about how mcaptcha reads configuration\n\n", e))),
}
Ok(settings)
}
fn check_url(&self) {
Url::parse(&self.source_code)
.expect("Please enter a URL for source_code in settings");
}
#[cfg(not(tarpaulin_include))]
fn check_uuid(&self) {
use std::str::FromStr;
Uuid::from_str(&self.default_campaign)
.expect("Please enter a UUID for default_campaign in settings");
}
}
#[cfg(not(tarpaulin_include))]
fn check_url(s: &Config) {
let url = s
.get::<String>("source_code")
.expect("Couldn't access source_code");
Url::parse(&url).expect("Please enter a URL for source_code in settings");
}
#[cfg(not(tarpaulin_include))]
fn check_uuid(s: &Config) {
use std::str::FromStr;
let id = s
.get::<String>("default_campaign")
.expect("Couldn't access default_campaign");
Uuid::from_str(&id).expect("Please enter a UUID for default_campaign in settings");
}
#[cfg(not(tarpaulin_include))]
fn set_from_database_url(s: &mut Config, database_conf: &DatabaseBuilder) {
s.set("database.username", database_conf.username.clone())
.expect("Couldn't set database username");
s.set("database.password", database_conf.password.clone())
.expect("Couldn't access database password");
s.set("database.hostname", database_conf.hostname.clone())
.expect("Couldn't access database hostname");
s.set("database.port", database_conf.port as i64)
.expect("Couldn't access database port");
s.set("database.name", database_conf.name.clone())
.expect("Couldn't access database name");
}
#[cfg(not(tarpaulin_include))]
fn set_database_url(s: &mut Config) {
s.set(
"database.url",
format!(
r"postgres://{}:{}@{}:{}/{}",
s.get::<String>("database.username")
.expect("Couldn't access database username"),
s.get::<String>("database.password")
.expect("Couldn't access database password"),
s.get::<String>("database.hostname")
.expect("Couldn't access database hostname"),
s.get::<String>("database.port")
.expect("Couldn't access database port"),
s.get::<String>("database.name")
.expect("Couldn't access database name")
),
)
.expect("Couldn't set databse url");
}
//#[cfg(not(tarpaulin_include))]
//fn check_url(s: &Config) {
// let url = s
// .get::<String>("source_code")
// .expect("Couldn't access source_code");
//
// Url::parse(&url).expect("Please enter a URL for source_code in settings");
//}
//