The big sqlite refactor

* refactor: safe sql access

* Clean up the worst rebase mistakes

* Some more progress on the rebase fallout and this branch

* upgrade and compile again

* cleanup from rebase

* example of how to prepare now

* rebase fixes

* add sql.query_map

* less preparation

* more improvements in sql code

* fix string truncation

* more prepare conversions

* most prep done

* fix tests

* fix ffi

* fix last prepares

* fix segfaults and some queries

* use r2d2 pool

* fix dc_job sql call, to reduce contention

* try newer rust

* No more vararg printing (drop dc_log_)

* ignore expected errors

* fix: uses exists instead of execute where needed

* fix: get_contacts logic was broken

* fix: contact creation

* test on 32bit linux

* ci: try running 32bit without cross

* undo 32bit tests

* refactor: rename dc_sqlite3 to sql

* fix: safer string conversions

* more string fixes

* try fixing appveyor build to 64bit

* chore(ci): hardcode target

* chore(ci): appveyor

* some cleanup work

* try fix darwin

* fix and improve sql escaping

* fix various bugs

* fix chat deletion

* refactor: cleanup config values and move to their own file

* refactor: move more methods onto the sql struct

* dont panic on failed state loading

* first round of cr

* one more cr fix

* stop using strange defaults

* remove unused escapes
This commit is contained in:
Friedel Ziegelmayer
2019-07-18 00:24:45 +02:00
committed by GitHub
parent 3e3403d3d7
commit 8a0fc609e6
47 changed files with 7356 additions and 9608 deletions

View File

@@ -1,13 +1,10 @@
use std::collections::HashMap;
use std::ffi::CString;
use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET};
use serde::Deserialize;
use crate::context::Context;
use crate::dc_sqlite3::*;
use crate::dc_tools::*;
use crate::types::*;
const OAUTH2_GMAIL: Oauth2 = Oauth2 {
client_id: "959970109878-4mvtgf6feshskf7695nfln6002mom908.apps.googleusercontent.com",
@@ -51,10 +48,10 @@ pub fn dc_get_oauth2_url(
redirect_uri: impl AsRef<str>,
) -> Option<String> {
if let Some(oauth2) = Oauth2::from_address(addr) {
set_config(
context.sql.set_config(
context,
"oauth2_pending_redirect_uri",
redirect_uri.as_ref(),
Some(redirect_uri.as_ref()),
);
let oauth2_url = replace_in_uri(&oauth2.get_code, "$CLIENT_ID", &oauth2.client_id);
let oauth2_url = replace_in_uri(&oauth2_url, "$REDIRECT_URI", redirect_uri.as_ref());
@@ -79,16 +76,18 @@ pub fn dc_get_oauth2_access_token(
// read generated token
if 0 == flags & 0x1 && !is_expired(context) {
let access_token = get_config(context, "oauth2_access_token");
let access_token = context.sql.get_config(context, "oauth2_access_token");
if access_token.is_some() {
// success
return access_token;
}
}
let refresh_token = get_config(context, "oauth2_refresh_token");
let refresh_token_for =
get_config(context, "oauth2_refresh_token_for").unwrap_or_else(|| "unset".into());
let refresh_token = context.sql.get_config(context, "oauth2_refresh_token");
let refresh_token_for = context
.sql
.get_config(context, "oauth2_refresh_token_for")
.unwrap_or_else(|| "unset".into());
let (redirect_uri, token_url, update_redirect_uri_on_success) =
if refresh_token.is_none() || refresh_token_for != code.as_ref() {
@@ -97,7 +96,9 @@ pub fn dc_get_oauth2_access_token(
0, "Generate OAuth2 refresh_token and access_token...",
);
(
get_config(context, "oauth2_pending_redirect_uri")
context
.sql
.get_config(context, "oauth2_pending_redirect_uri")
.unwrap_or_else(|| "unset".into()),
oauth2.init_token,
true,
@@ -108,7 +109,10 @@ pub fn dc_get_oauth2_access_token(
0, "Regenerate OAuth2 access_token by refresh_token...",
);
(
get_config(context, "oauth2_redirect_uri").unwrap_or_else(|| "unset".into()),
context
.sql
.get_config(context, "oauth2_redirect_uri")
.unwrap_or_else(|| "unset".into()),
oauth2.refresh_token,
false,
)
@@ -151,23 +155,33 @@ pub fn dc_get_oauth2_access_token(
println!("response: {:?}", &parsed);
let response = parsed.unwrap();
if let Some(ref token) = response.refresh_token {
set_config(context, "oauth2_refresh_token", token);
set_config(context, "oauth2_refresh_token_for", code.as_ref());
context
.sql
.set_config(context, "oauth2_refresh_token", Some(token));
context
.sql
.set_config(context, "oauth2_refresh_token_for", Some(code.as_ref()));
}
// after that, save the access token.
// if it's unset, we may get it in the next round as we have the refresh_token now.
if let Some(ref token) = response.access_token {
set_config(context, "oauth2_access_token", token);
context
.sql
.set_config(context, "oauth2_access_token", Some(token));
let expires_in = response
.expires_in
// refresh a bet before
.map(|t| time() + t as i64 - 5)
.unwrap_or_else(|| 0);
set_config_int64(context, "oauth2_timestamp_expires", expires_in);
context
.sql
.set_config_int64(context, "oauth2_timestamp_expires", expires_in);
if update_redirect_uri_on_success {
set_config(context, "oauth2_redirect_uri", redirect_uri.as_ref());
context
.sql
.set_config(context, "oauth2_redirect_uri", Some(redirect_uri.as_ref()));
}
} else {
warn!(context, 0, "Failed to find OAuth2 access token");
@@ -279,35 +293,11 @@ impl Oauth2 {
}
}
fn get_config(context: &Context, key: &str) -> Option<String> {
let key_c = CString::new(key).unwrap();
let res =
unsafe { dc_sqlite3_get_config(context, &context.sql, key_c.as_ptr(), std::ptr::null()) };
if res.is_null() {
return None;
}
Some(to_string(res))
}
fn set_config(context: &Context, key: &str, value: &str) {
let key_c = CString::new(key).unwrap();
let value_c = CString::new(value).unwrap();
unsafe { dc_sqlite3_set_config(context, &context.sql, key_c.as_ptr(), value_c.as_ptr()) };
}
fn set_config_int64(context: &Context, key: &str, value: i64) {
let key_c = CString::new(key).unwrap();
unsafe { dc_sqlite3_set_config_int64(context, &context.sql, key_c.as_ptr(), value) };
}
fn is_expired(context: &Context) -> bool {
let expire_timestamp = dc_sqlite3_get_config_int64(
context,
&context.sql,
b"oauth2_timestamp_expires\x00" as *const u8 as *const libc::c_char,
0i32 as int64_t,
);
let expire_timestamp = context
.sql
.get_config_int64(context, "oauth2_timestamp_expires")
.unwrap_or_default();
if expire_timestamp <= 0 {
return false;