feat: DB methods to save analytics from mCaptcha/mCaptcha
This commit is contained in:
parent
ca34646b0c
commit
8e0e94f98b
5 changed files with 843 additions and 621 deletions
314
Cargo.lock
generated
314
Cargo.lock
generated
|
@ -430,14 +430,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.66"
|
||||
name = "async-compression"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc"
|
||||
checksum = "f658e2baef915ba0f26f1f7c42bfb8e12f532a01f449a090ded75ae7a07e9ba2"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"futures-core",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -719,6 +732,16 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
|
@ -1090,6 +1113,21 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.1.0"
|
||||
|
@ -1266,9 +1304,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.16"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d"
|
||||
checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
|
@ -1389,6 +1427,17 @@ dependencies = [
|
|||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-range"
|
||||
version = "0.1.5"
|
||||
|
@ -1419,6 +1468,43 @@ version = "2.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hyper",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.53"
|
||||
|
@ -1522,6 +1608,12 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
|
@ -1772,6 +1864,24 @@ dependencies = [
|
|||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.4"
|
||||
|
@ -1858,6 +1968,50 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-multimap"
|
||||
version = "0.4.3"
|
||||
|
@ -2234,6 +2388,46 @@ version = "0.6.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"base64 0.21.0",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-util",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
|
@ -2405,6 +2599,15 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
|
@ -2427,6 +2630,29 @@ dependencies = [
|
|||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.16"
|
||||
|
@ -2862,6 +3088,7 @@ dependencies = [
|
|||
"actix-web",
|
||||
"actix-web-codegen-const-routes",
|
||||
"argon2-creds",
|
||||
"async-trait",
|
||||
"cache-buster",
|
||||
"config",
|
||||
"csv-async",
|
||||
|
@ -2875,6 +3102,7 @@ dependencies = [
|
|||
"mktemp",
|
||||
"pretty_env_logger",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -2910,6 +3138,27 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration-sys"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.8.0"
|
||||
|
@ -3055,6 +3304,16 @@ dependencies = [
|
|||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.12"
|
||||
|
@ -3089,6 +3348,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
|
@ -3122,6 +3387,12 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.16.0"
|
||||
|
@ -3399,6 +3670,15 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
|
||||
dependencies = [
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
@ -3430,6 +3710,18 @@ dependencies = [
|
|||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.84"
|
||||
|
@ -3647,6 +3939,16 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.50.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
|
|
|
@ -22,7 +22,7 @@ name = "tests-migrate"
|
|||
path = "./src/tests-migrate.rs"
|
||||
|
||||
[dependencies]
|
||||
actix-web = "4.0.1"
|
||||
actix-web = "4.3"
|
||||
actix-identity = "0.4.0"
|
||||
actix-session = { version = "0.6.1", features = ["cookie-session"]}
|
||||
actix-http = "3.0.4"
|
||||
|
@ -72,6 +72,8 @@ tracing = { version = "0.1.37", features = ["log"] }
|
|||
tera = { version="1.17.1", features=["builtins"]}
|
||||
tokio = { version = "1.25.0", features = ["fs"] }
|
||||
csv-async = { version = "1.2.5", features = ["serde", "tokio"] }
|
||||
async-trait = "0.1.68"
|
||||
reqwest = { version = "0.11.18", features = ["json", "gzip"] }
|
||||
|
||||
#tokio = "1.11.0"
|
||||
|
||||
|
|
22
migrations/20230701082846_survey_mcaptcha_upload.sql
Normal file
22
migrations/20230701082846_survey_mcaptcha_upload.sql
Normal file
|
@ -0,0 +1,22 @@
|
|||
CREATE TABLE IF NOT EXISTS survey_mcaptcha_hostname (
|
||||
url VARCHAR(3000) UNIQUE NOT NULL,
|
||||
secret VARCHAR(100) UNIQUE NOT NULL,
|
||||
ID SERIAL PRIMARY KEY NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS survey_mcaptcha_campaign (
|
||||
campaign_id VARCHAR(100) NOT NULL,
|
||||
public_id VARCHAR(100) NOT NULL,
|
||||
url_id INTEGER NOT NULL references survey_mcaptcha_hostname(ID) ON DELETE CASCADE,
|
||||
synced_till INTEGER NOT NULL DEFAULT 0,
|
||||
ID SERIAL PRIMARY KEY NOT NULL
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS survey_mcaptcha_analytics (
|
||||
campaign_id INTEGER references survey_mcaptcha_campaign(ID) ON DELETE CASCADE,
|
||||
time INTEGER NOT NULL,
|
||||
difficulty_factor INTEGER NOT NULL,
|
||||
worker_type VARCHAR(100) NOT NULL,
|
||||
ID SERIAL PRIMARY KEY NOT NULL
|
||||
);
|
615
sqlx-data.json
615
sqlx-data.json
|
@ -1,616 +1,3 @@
|
|||
{
|
||||
"db": "PostgreSQL",
|
||||
"0d22134cc5076304b7895827f006ee8269cc500f400114a7472b83f0f1c568b5": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Varchar"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO survey_admins \n (name , password, secret) VALUES ($1, $2, $3)"
|
||||
},
|
||||
"10924f3726a45c3bc709118375d691f2867bbcd50dc47a000ac9bf3ff878c97c": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 1,
|
||||
"type_info": "Uuid"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
}
|
||||
},
|
||||
"query": "SELECT name, id FROM survey_campaigns ORDER BY id;"
|
||||
},
|
||||
"117f1ae18f6a3936f27446b75b555951fe217d3a3cefe40a006fdd3cb31f0ac4": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Int4",
|
||||
"Timestamptz",
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"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;"
|
||||
},
|
||||
"1373df097fa0e58b23a374753318ae53a44559aa0e7eb64680185baf1c481723": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "password",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT password FROM survey_admins WHERE name = ($1)"
|
||||
},
|
||||
"15a8484de6f035e56c34ce3f6979eadea81f125933f76261c8b3c8319d43bbe0": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"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 "
|
||||
},
|
||||
"19686bfe8772cbc6831d46d18994e2b9aa40c7181eae9a31e51451cce95f04e8": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT name, password FROM survey_admins WHERE email = ($1)"
|
||||
},
|
||||
"1972be28a6bda2c3a3764a836e95c8cb0c5db277fc4c8a9b19951a03166c6492": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"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)"
|
||||
},
|
||||
"1b7e17bfc949fa97e8dec1f95e35a02bcf3aa1aa72a1f6f6c8884e885fc3b953": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text",
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "insert into survey_admins \n (name , password, email, secret) values ($1, $2, $3, $4)"
|
||||
},
|
||||
"2ccaecfee4d2f29ef5278188b304017719720aa986d680d4727a1facbb869c7a": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "DELETE FROM survey_admins WHERE name = ($1)"
|
||||
},
|
||||
"43b3e771f38bf8059832169227705be06a28925af1b3799ffef5371d511fd138": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Timestamptz",
|
||||
"Uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "\n INSERT INTO survey_users (created_at, id) VALUES($1, $2)"
|
||||
},
|
||||
"536541ecf2e1c0403c74b6e2e09b42b73a7741ae4a348ff539ac410022e03ace": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "exists",
|
||||
"ordinal": 0,
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
null
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT EXISTS (SELECT 1 from survey_admins WHERE name = $1)"
|
||||
},
|
||||
"55dde28998a6d12744806035f0a648494a403c7d09ea3caf91bf54869a81aa73": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "UPDATE survey_admins set password = $1\n WHERE name = $2"
|
||||
},
|
||||
"57c673ad8529371d77aa305917cf680dd2273ead74c3583ef0322f472b1d33fd": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"name": "device_software_recognised",
|
||||
"ordinal": 1,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "threads",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"name": "user_id",
|
||||
"ordinal": 3,
|
||||
"type_info": "Uuid"
|
||||
},
|
||||
{
|
||||
"name": "submitted_at",
|
||||
"ordinal": 4,
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"name": "device_user_provided",
|
||||
"ordinal": 5,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 6,
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text",
|
||||
"Int8",
|
||||
"Int8"
|
||||
]
|
||||
}
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"58ec3b8f98c27e13ec2732f8ee23f6eb9845ac5d9fd97b1e5c9f2eed4b1f5693": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"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)"
|
||||
},
|
||||
"683707dbc847b37c58c29aaad0d1a978c9fe0657da13af99796e4461134b5a43": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "UPDATE survey_admins set email = $1\n WHERE name = $2"
|
||||
},
|
||||
"6a26daa84578aed2b2085697cb8358ed7c0a50ba9597fd387b4b09b0a8a154db": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "exists",
|
||||
"ordinal": 0,
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
null
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT EXISTS (SELECT 1 from survey_admins WHERE email = $1)"
|
||||
},
|
||||
"70cc7bfc9b6ff5b68db70c069c0947d51bfc4a53cedc020016ee25ff98586c93": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 1,
|
||||
"type_info": "Uuid"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"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 )"
|
||||
},
|
||||
"74c41e33f91cf31ea13582c8b3ca464544374842450d580517ca2bd01d67402e": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"name": "device_software_recognised",
|
||||
"ordinal": 1,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "threads",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"name": "user_id",
|
||||
"ordinal": 3,
|
||||
"type_info": "Uuid"
|
||||
},
|
||||
{
|
||||
"name": "submitted_at",
|
||||
"ordinal": 4,
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"name": "device_user_provided",
|
||||
"ordinal": 5,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 6,
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid",
|
||||
"Text",
|
||||
"Text",
|
||||
"Int8",
|
||||
"Int8"
|
||||
]
|
||||
}
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"82feafc36533144e49ba374c8c47ca4aa0d6558a9803778ad28cfa7b62382c3e": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Uuid",
|
||||
"Varchar",
|
||||
"Int4Array",
|
||||
"Timestamptz"
|
||||
]
|
||||
}
|
||||
},
|
||||
"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 );"
|
||||
},
|
||||
"858a4c06a5c1ba7adb79bcac7d42d106d09d0cbff10c197f2242dcb5c437a1df": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 0,
|
||||
"type_info": "Timestamptz"
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 1,
|
||||
"type_info": "Uuid"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT\n created_at,\n ID\n FROM\n survey_users\n WHERE\n ID = $1\n "
|
||||
},
|
||||
"9cdade613ce724631cc3f187510758ee0929e93ff3f8ce81fe35594756644246": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "difficulties",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int4Array"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT difficulties FROM survey_campaigns WHERE id = $1;"
|
||||
},
|
||||
"a721cfa249acf328c2f29c4cf8c2aeba1a635bcf49d18ced5474caa10b7cae4f": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Int4",
|
||||
"Float4"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO survey_benches \n (resp_id, difficulty, duration) \n VALUES ($1, $2, $3);"
|
||||
},
|
||||
"ab951c5c318174c6538037947c2f52c61bcfe5e5be1901379b715e77f5214dd2": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "UPDATE survey_admins set secret = $1\n WHERE name = $2"
|
||||
},
|
||||
"b2619292aa6bd1ac38dca152cbe607b795a151ddc212361a3c6d8c70ea1c93eb": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "duration",
|
||||
"ordinal": 0,
|
||||
"type_info": "Float4"
|
||||
},
|
||||
{
|
||||
"name": "difficulty",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT\n duration,\n difficulty\n FROM\n survey_benches\n WHERE\n resp_id = $1\n "
|
||||
},
|
||||
"c757589ef26a005e3285e7ab20d8a44c4f2e1cb125f8db061dd198cc380bf807": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "UPDATE survey_admins set name = $1\n WHERE name = $2"
|
||||
},
|
||||
"e9cf5d6d8c9e8327d5c809d47a14a933f324e267f1e7dbb48e1caf1c021adc3f": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "secret",
|
||||
"ordinal": 0,
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "SELECT secret FROM survey_admins WHERE name = ($1)"
|
||||
},
|
||||
"efa0e41910fa5bcb187ba9e2fc8f37bee5b25ffe9a2d175f39a69899bc559965": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Uuid"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 1,
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"name": "difficulties",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int4Array"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 3,
|
||||
"type_info": "Timestamptz"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
}
|
||||
},
|
||||
"query": "SELECT ID, name, difficulties, created_at FROM survey_campaigns"
|
||||
},
|
||||
"fcdc5fe5d496eb516c805e64ec96d9626b74ab33cd6e75e5a08ae88967403b72": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int4",
|
||||
"Uuid",
|
||||
"Uuid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"query": "INSERT INTO survey_response_tokens \n (resp_id, user_id, id)\n VALUES ($1, $2, $3);"
|
||||
}
|
||||
"db": "PostgreSQL"
|
||||
}
|
509
src/api/v1/mcaptcha/db.rs
Normal file
509
src/api/v1/mcaptcha/db.rs
Normal file
|
@ -0,0 +1,509 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
use url::Url;
|
||||
|
||||
use crate::api::v1::get_random;
|
||||
use crate::errors::*;
|
||||
use crate::mcaptcha::PerformanceAnalytics;
|
||||
use crate::Data;
|
||||
|
||||
impl Data {
|
||||
/// Check if an mCaptcha instance is registered on the database
|
||||
pub async fn mcaptcha_url_exists(&self, url: &str) -> ServiceResult<bool> {
|
||||
let res = sqlx::query!(
|
||||
"SELECT EXISTS (SELECT 1 from survey_mcaptcha_hostname WHERE url = $1)",
|
||||
url
|
||||
)
|
||||
.fetch_one(&self.db)
|
||||
.await?;
|
||||
|
||||
let mut resp = false;
|
||||
if let Some(x) = res.exists {
|
||||
if x {
|
||||
resp = true;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
/// Register an mCaptcha instance
|
||||
pub async fn mcaptcha_register_instance(&self, url: &str) -> ServiceResult<String> {
|
||||
let secret = get_random(32);
|
||||
sqlx::query!(
|
||||
"INSERT INTO survey_mcaptcha_hostname (url, secret) VALUES ($1, $2)",
|
||||
url,
|
||||
&secret,
|
||||
)
|
||||
.execute(&self.db)
|
||||
.await?;
|
||||
Ok(secret)
|
||||
}
|
||||
|
||||
/// Update the secret of an mCaptcha instance
|
||||
pub async fn mcaptcha_update_secret(&self, url: &str) -> ServiceResult<String> {
|
||||
let secret = get_random(32);
|
||||
sqlx::query!(
|
||||
"UPDATE survey_mcaptcha_hostname set secret = $1 WHERE url = $2",
|
||||
&secret,
|
||||
url
|
||||
)
|
||||
.execute(&self.db)
|
||||
.await?;
|
||||
Ok(secret)
|
||||
}
|
||||
|
||||
/// Authenticate an mCaptcha instance and return its URL
|
||||
pub async fn mcaptcha_authenticate_and_get_url(
|
||||
&self,
|
||||
secret: &str,
|
||||
) -> ServiceResult<Url> {
|
||||
struct U {
|
||||
url: String,
|
||||
}
|
||||
|
||||
let res = sqlx::query!(
|
||||
"SELECT EXISTS (
|
||||
SELECT
|
||||
url
|
||||
FROM
|
||||
survey_mcaptcha_hostname
|
||||
WHERE secret = $1
|
||||
)",
|
||||
secret
|
||||
)
|
||||
.fetch_one(&self.db)
|
||||
.await?;
|
||||
|
||||
if !match res.exists {
|
||||
Some(true) => true,
|
||||
_ => false,
|
||||
} {
|
||||
return Err(ServiceError::WrongPassword);
|
||||
}
|
||||
|
||||
let url = sqlx::query_as!(
|
||||
U,
|
||||
"SELECT
|
||||
url
|
||||
FROM
|
||||
survey_mcaptcha_hostname
|
||||
WHERE
|
||||
secret = $1; ",
|
||||
secret
|
||||
)
|
||||
.fetch_one(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(Url::parse(&url.url).unwrap())
|
||||
}
|
||||
|
||||
/// Delete mCaptcha instance from database
|
||||
pub async fn mcaptcha_delete_mcaptcha_instance(
|
||||
&self,
|
||||
url: &str,
|
||||
secret: &str,
|
||||
) -> ServiceResult<()> {
|
||||
sqlx::query!(
|
||||
"DELETE FROM survey_mcaptcha_hostname WHERE secret = $1 AND url =$2",
|
||||
secret,
|
||||
url
|
||||
)
|
||||
.execute(&self.db)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
/// Delete mCaptcha camapign from database
|
||||
pub async fn mcaptcha_delete_mcaptcha_campaign(
|
||||
&self,
|
||||
campaign_id: &uuid::Uuid,
|
||||
secret: &str,
|
||||
) -> ServiceResult<()> {
|
||||
let campaign_str = campaign_id.to_string();
|
||||
let res = sqlx::query!(
|
||||
"DELETE FROM
|
||||
survey_mcaptcha_campaign
|
||||
WHERE
|
||||
campaign_id = $1
|
||||
AND
|
||||
url_id = (
|
||||
SELECT
|
||||
ID
|
||||
FROM
|
||||
survey_mcaptcha_hostname
|
||||
WHERE
|
||||
secret = $2
|
||||
)",
|
||||
&campaign_str,
|
||||
secret
|
||||
)
|
||||
.execute(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check if an mCaptcha instance campaign is registered on DB
|
||||
pub async fn mcaptcha_campaign_is_registered(
|
||||
&self,
|
||||
campaign_id: &uuid::Uuid,
|
||||
secret: &str,
|
||||
) -> ServiceResult<bool> {
|
||||
let campaign_str = campaign_id.to_string();
|
||||
|
||||
let res = sqlx::query!(
|
||||
"SELECT EXISTS (
|
||||
SELECT
|
||||
ID
|
||||
FROM
|
||||
survey_mcaptcha_campaign
|
||||
WHERE
|
||||
campaign_id = $1
|
||||
AND
|
||||
url_id = (
|
||||
SELECT
|
||||
ID
|
||||
FROM
|
||||
survey_mcaptcha_hostname
|
||||
WHERE
|
||||
secret = $2
|
||||
)
|
||||
)",
|
||||
&campaign_str,
|
||||
secret
|
||||
)
|
||||
.fetch_one(&self.db)
|
||||
.await?;
|
||||
|
||||
let mut resp = false;
|
||||
if let Some(x) = res.exists {
|
||||
if x {
|
||||
resp = true;
|
||||
}
|
||||
}
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
/// Register an mCaptcha instance campaign on DB
|
||||
pub async fn mcaptcha_register_campaign(
|
||||
&self,
|
||||
campaign_id: &uuid::Uuid,
|
||||
secret: &str,
|
||||
) -> ServiceResult<()> {
|
||||
let campaign_str = campaign_id.to_string();
|
||||
let public_id = uuid::Uuid::new_v4();
|
||||
|
||||
sqlx::query!(
|
||||
"INSERT INTO
|
||||
survey_mcaptcha_campaign (campaign_id, public_id, url_id)
|
||||
VALUES ($1, $2, (SELECT ID FROM survey_mcaptcha_hostname WHERE secret = $3));",
|
||||
&campaign_str,
|
||||
&public_id.to_string(),
|
||||
secret,
|
||||
)
|
||||
.execute(&self.db)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Register an mCaptcha instance campaign on DB
|
||||
pub async fn mcaptcha_get_campaign_public_id(
|
||||
&self,
|
||||
campaign_id: &uuid::Uuid,
|
||||
secret: &str,
|
||||
) -> ServiceResult<uuid::Uuid> {
|
||||
let campaign_str = campaign_id.to_string();
|
||||
struct S {
|
||||
public_id: String,
|
||||
}
|
||||
|
||||
let res = sqlx::query_as!(
|
||||
S,
|
||||
"SELECT
|
||||
public_id
|
||||
FROM
|
||||
survey_mcaptcha_campaign
|
||||
WHERE
|
||||
campaign_id = $1
|
||||
AND
|
||||
url_id = (SELECT ID FROM survey_mcaptcha_hostname WHERE secret = $2);",
|
||||
&campaign_str,
|
||||
secret,
|
||||
)
|
||||
.fetch_one(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(uuid::Uuid::parse_str(&res.public_id).unwrap())
|
||||
}
|
||||
|
||||
/// Get an mCaptcha instance campaign checkpoint
|
||||
pub async fn mcaptcha_get_checkpoint(
|
||||
&self,
|
||||
campaign_id: &uuid::Uuid,
|
||||
secret: &str,
|
||||
) -> ServiceResult<usize> {
|
||||
let campaign_str = campaign_id.to_string();
|
||||
|
||||
struct CheckPoint {
|
||||
synced_till: i32,
|
||||
}
|
||||
|
||||
let checkpoint = sqlx::query_as!(
|
||||
CheckPoint,
|
||||
"SELECT
|
||||
synced_till
|
||||
FROM
|
||||
survey_mcaptcha_campaign
|
||||
WHERE
|
||||
campaign_id = $1
|
||||
AND
|
||||
url_id = (
|
||||
SELECT ID FROM survey_mcaptcha_hostname WHERE secret = $2
|
||||
);",
|
||||
&campaign_str,
|
||||
secret
|
||||
)
|
||||
.fetch_one(&self.db)
|
||||
.await?;
|
||||
let checkpoint = checkpoint.synced_till as usize;
|
||||
Ok(checkpoint)
|
||||
}
|
||||
|
||||
/// Set an mCaptcha instance campaign checkpoint
|
||||
pub async fn mcaptcha_set_checkpoint(
|
||||
&self,
|
||||
campaign_id: &uuid::Uuid,
|
||||
secret: &str,
|
||||
checkpoint: usize,
|
||||
) -> ServiceResult<()> {
|
||||
let campaign_str = campaign_id.to_string();
|
||||
sqlx::query!(
|
||||
"UPDATE
|
||||
survey_mcaptcha_campaign
|
||||
SET
|
||||
synced_till = $1
|
||||
WHERE
|
||||
campaign_id = $2
|
||||
AND
|
||||
url_id = (
|
||||
SELECT ID FROM survey_mcaptcha_hostname WHERE secret = $3
|
||||
)
|
||||
",
|
||||
checkpoint as i32,
|
||||
&campaign_str,
|
||||
secret
|
||||
)
|
||||
.execute(&self.db)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Store mCaptcha instance campaign analytics
|
||||
pub async fn mcaptcha_insert_analytics(
|
||||
&self,
|
||||
campaign_id: &uuid::Uuid,
|
||||
secret: &str,
|
||||
r: &PerformanceAnalytics,
|
||||
) -> ServiceResult<()> {
|
||||
let campaign_str = campaign_id.to_string();
|
||||
sqlx::query!(
|
||||
"INSERT INTO
|
||||
survey_mcaptcha_analytics (
|
||||
campaign_id, time, difficulty_factor, worker_type
|
||||
)
|
||||
VALUES ((
|
||||
SELECT
|
||||
ID
|
||||
FROM
|
||||
survey_mcaptcha_campaign
|
||||
WHERE
|
||||
campaign_id = $1
|
||||
AND
|
||||
url_id = (
|
||||
SELECT ID FROM survey_mcaptcha_hostname WHERE secret = $2
|
||||
)
|
||||
), $3, $4, $5
|
||||
);",
|
||||
&campaign_str,
|
||||
secret,
|
||||
r.time as i32,
|
||||
r.difficulty_factor as i32,
|
||||
&r.worker_type,
|
||||
)
|
||||
.execute(&self.db)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// fetch PoW analytics
|
||||
pub async fn mcaptcha_analytics_fetch(
|
||||
&self,
|
||||
public_id: &uuid::Uuid,
|
||||
limit: usize,
|
||||
offset: usize,
|
||||
) -> ServiceResult<Vec<PerformanceAnalytics>> {
|
||||
let public_id_str = public_id.to_string();
|
||||
struct P {
|
||||
id: i32,
|
||||
time: i32,
|
||||
difficulty_factor: i32,
|
||||
worker_type: String,
|
||||
}
|
||||
|
||||
impl From<P> for PerformanceAnalytics {
|
||||
fn from(v: P) -> Self {
|
||||
Self {
|
||||
time: v.time as u32,
|
||||
difficulty_factor: v.difficulty_factor as u32,
|
||||
worker_type: v.worker_type,
|
||||
id: v.id as usize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut c = sqlx::query_as!(
|
||||
P,
|
||||
"SELECT id, time, difficulty_factor, worker_type FROM survey_mcaptcha_analytics
|
||||
WHERE
|
||||
campaign_id = (
|
||||
SELECT
|
||||
ID FROM survey_mcaptcha_campaign
|
||||
WHERE
|
||||
public_id = $1
|
||||
)
|
||||
ORDER BY ID
|
||||
OFFSET $2 LIMIT $3
|
||||
",
|
||||
&public_id_str,
|
||||
offset as i32,
|
||||
limit as i32
|
||||
)
|
||||
.fetch_all(&self.db)
|
||||
.await?;
|
||||
let mut res = Vec::with_capacity(c.len());
|
||||
for i in c.drain(0..) {
|
||||
res.push(i.into())
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{mcaptcha::PerformanceAnalytics, tests::*};
|
||||
|
||||
use url::Url;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_db_mcaptcha_works() {
|
||||
let url = Url::parse("http://test_add_campaign.example").unwrap();
|
||||
let data = get_test_data().await;
|
||||
let url_str = url.to_string();
|
||||
if data.mcaptcha_url_exists(&url_str).await.unwrap() {
|
||||
let secret = data.mcaptcha_update_secret(&url_str).await.unwrap();
|
||||
data.mcaptcha_delete_mcaptcha_instance(&url_str, &secret)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
assert!(!data.mcaptcha_url_exists(&url_str).await.unwrap());
|
||||
|
||||
let secret = data.mcaptcha_register_instance(&url_str).await.unwrap();
|
||||
assert!(data.mcaptcha_url_exists(&url_str).await.unwrap());
|
||||
let secret2 = data.mcaptcha_update_secret(&url_str).await.unwrap();
|
||||
assert_ne!(secret2, secret);
|
||||
let secret = secret2;
|
||||
|
||||
assert_eq!(
|
||||
data.mcaptcha_authenticate_and_get_url(&secret)
|
||||
.await
|
||||
.unwrap(),
|
||||
url
|
||||
);
|
||||
|
||||
let uuid = uuid::Uuid::new_v4();
|
||||
|
||||
if data
|
||||
.mcaptcha_campaign_is_registered(&uuid, &secret)
|
||||
.await
|
||||
.unwrap()
|
||||
{
|
||||
data.mcaptcha_delete_mcaptcha_campaign(&uuid, &secret)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
assert!(!data
|
||||
.mcaptcha_campaign_is_registered(&uuid, &secret)
|
||||
.await
|
||||
.unwrap());
|
||||
data.mcaptcha_register_campaign(&uuid, &secret)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(data
|
||||
.mcaptcha_campaign_is_registered(&uuid, &secret)
|
||||
.await
|
||||
.unwrap());
|
||||
|
||||
assert_eq!(
|
||||
data.mcaptcha_get_checkpoint(&uuid, &secret).await.unwrap(),
|
||||
0
|
||||
);
|
||||
data.mcaptcha_set_checkpoint(&uuid, &secret, 1)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
data.mcaptcha_get_checkpoint(&uuid, &secret).await.unwrap(),
|
||||
1
|
||||
);
|
||||
|
||||
let analytics = PerformanceAnalytics {
|
||||
id: 1,
|
||||
time: 1,
|
||||
difficulty_factor: 1,
|
||||
worker_type: "foo".to_string(),
|
||||
};
|
||||
data.mcaptcha_insert_analytics(&uuid, &secret, &analytics)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let public_id = data
|
||||
.mcaptcha_get_campaign_public_id(&uuid, &secret)
|
||||
.await
|
||||
.unwrap();
|
||||
let db_analytics = data
|
||||
.mcaptcha_analytics_fetch(&public_id, 50, 0)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(db_analytics.len(), 1);
|
||||
assert_eq!(db_analytics[0].time, analytics.time);
|
||||
assert_eq!(
|
||||
db_analytics[0].difficulty_factor,
|
||||
analytics.difficulty_factor
|
||||
);
|
||||
assert_eq!(db_analytics[0].worker_type, analytics.worker_type);
|
||||
|
||||
assert_eq!(
|
||||
data.mcaptcha_analytics_fetch(&public_id, 50, 1)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec![]
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue