vks: add simple updated-prefixes route

This commit is contained in:
Vincent Breitmoser
2025-02-11 02:59:34 +01:00
parent c7891c543a
commit 3e6a2aa550
6 changed files with 65 additions and 1 deletions

View File

@@ -7,6 +7,7 @@ use std::io::Write;
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
use chrono::NaiveDate;
use pathdiff::diff_paths;
use std::time::SystemTime;
use tempfile;
@@ -617,6 +618,10 @@ impl<'a> Database<'a> for Filesystem {
Fingerprint::from_str(last_entry)
}
fn get_updates_since(&self, _day: NaiveDate) -> Vec<Fingerprint> {
vec![]
}
fn check_link_fpr(
&self,
fpr: &Fingerprint,

View File

@@ -5,7 +5,7 @@ use std::str::FromStr;
use openpgp::serialize::SerializeInto;
use chrono::prelude::Utc;
use chrono::{prelude::Utc, NaiveDate};
#[macro_use]
extern crate anyhow;
@@ -176,6 +176,7 @@ pub trait Database<'a>: Sync + Send {
fn by_primary_fpr(&self, fpr: &Fingerprint) -> Option<String>;
fn get_last_log_entry(&self) -> Result<Fingerprint>;
fn get_updates_since(&self, day: NaiveDate) -> Vec<Fingerprint>;
fn write_log_append(&self, filename: &str, fpr_primary: &Fingerprint) -> Result<()>;

View File

@@ -1,3 +1,5 @@
use chrono::{NaiveDate, NaiveDateTime, NaiveTime, Utc};
use self_cell::self_cell;
use std::convert::TryFrom;
@@ -473,6 +475,28 @@ impl<'a> Database<'a> for Sqlite {
Ok(())
}
fn get_updates_since(&self, since_day: NaiveDate) -> Vec<Fingerprint> {
let conn = self.pool.get().unwrap();
let midnight = NaiveTime::from_hms_opt(0, 0, 0).expect("noon exists");
let until_day_midnight = Utc::now().with_time(midnight).unwrap();
let since_day_midnight = NaiveDateTime::new(since_day, midnight);
let fprs: Vec<Fingerprint> = conn
.prepare(
"SELECT primary_fingerprint FROM certs WHERE updated_at > ?1 AND updated_at < ?2",
)
.expect("query must be correct")
.query_map(
params![since_day_midnight.and_utc().timestamp_millis(), until_day_midnight.timestamp_millis()],
|row| row.get::<_, Fingerprint>(0),
)
.expect("query must not fail")
.flatten()
.collect();
fprs
}
fn get_last_log_entry(&self) -> Result<Fingerprint> {
let conn = self.pool.get().unwrap();
Ok(conn.query_row(

View File

@@ -102,6 +102,18 @@ impl FromStr for Email {
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Fingerprint([u8; 20]);
impl Fingerprint {
pub fn to_prefix(&self) -> String {
let mut prefix_bytes = [0u8; 8];
prefix_bytes.copy_from_slice(&self.0[0..8]);
let mut result = String::new();
prefix_bytes.write_hex_upper(&mut result).expect("writing bytes as hex cannot fail");
result
}
}
impl FromSql for Fingerprint {
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
value

View File

@@ -428,6 +428,7 @@ fn rocket_factory(
vks_api::vks_v1_by_email,
vks_api::vks_v1_by_fingerprint,
vks_api::vks_v1_by_keyid,
vks_api::vks_v1_updated_prefixes,
vks_api::upload_json,
vks_api::upload_fallback,
vks_api::request_verify_json,

View File

@@ -1,3 +1,5 @@
use chrono::NaiveDate;
use database::Database;
use rocket::http::{ContentType, Status};
use rocket::request::Request;
use rocket::response::{self, Responder, Response};
@@ -5,6 +7,7 @@ use rocket::serde::json::Json;
use rocket_i18n::{I18n, Translations};
use serde_json::json;
use std::io::Cursor;
use std::str::FromStr;
use crate::database::types::{Email, Fingerprint, KeyID};
use crate::database::{KeyDatabase, Query, StatefulTokens};
@@ -200,3 +203,21 @@ pub fn vks_v1_by_keyid(db: &rocket::State<KeyDatabase>, i18n: I18n, kid: String)
web::key_to_response_plain(db, i18n, query)
}
#[get("/vks/v1/updated-prefixes/since/<day>")]
pub fn vks_v1_updated_prefixes(
db: &rocket::State<KeyDatabase>,
day: &str,
) -> MyResponse {
let day = match NaiveDate::from_str(day) {
Ok(day) => day,
Err(_) => return MyResponse::bad_request_plain("malformed iso8601 timestamp"),
};
let updates = db.get_updates_since(day);
let prefixes: Vec<String> = updates.iter().map(|fpr| fpr.to_prefix()).collect();
let prefix_text = prefixes.join("\n");
MyResponse::Plain(prefix_text)
}