Visibility in endpoints: don't list hidden results

This commit is contained in:
Brandon Thomas committed 2021-08-11 20:28:57 -04:00
1 parent 7738d45be0
commit a2f2763759
5 files changed
+144 -10

No files matched your search

@@ -49,6 +49,7 @@ pub struct TtsInferenceRecordForList {
/// testability, construction, and correctness.
pub struct ListTtsResultsQueryBuilder {
scope_creator_username: Option<String>,
include_user_hidden: bool,
include_mod_disabled_results: bool,
sort_ascending: bool,
offset: Option<u64>,
@@ -60,6 +61,7 @@ impl ListTtsResultsQueryBuilder {
pub fn new() -> Self {
Self {
scope_creator_username: None,
include_user_hidden: false,
include_mod_disabled_results: false,
sort_ascending: false,
offset: None,
@@ -73,6 +75,11 @@ impl ListTtsResultsQueryBuilder {
self
}
pub fn include_user_hidden(mut self, include_user_hidden: bool) -> Self {
self.include_user_hidden = include_user_hidden;
self
}
pub fn include_mod_disabled_results(mut self, include_mod_disabled_results: bool) -> Self {
self.include_mod_disabled_results = include_mod_disabled_results;
self
@@ -261,6 +268,15 @@ LEFT OUTER JOIN users
}
}
if !self.include_user_hidden {
if !first_predicate_added {
query.push_str(" WHERE tts_results.creator_set_visibility = 'public'");
first_predicate_added = true;
} else {
query.push_str(" AND tts_results.creator_set_visibility = 'public'");
}
}
if !self.include_mod_disabled_results {
if !first_predicate_added {
query.push_str(" WHERE tts_results.user_deleted_at IS NULL");
@@ -317,7 +333,8 @@ mod tests {
let query_builder = ListTtsResultsQueryBuilder::new();
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.user_deleted_at IS NULL \
" WHERE tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id DESC \
LIMIT ?");
@@ -330,19 +347,33 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE users.username = ? \
AND tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_user_hidden() {
let query_builder = ListTtsResultsQueryBuilder::new()
.include_user_hidden(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_deleted() {
let query_builder = ListTtsResultsQueryBuilder::new()
.include_mod_disabled_results(true);
assert_eq!(&query_builder.build_predicates(),
" ORDER BY tts_results.id DESC \
" WHERE tts_results.creator_set_visibility = 'public' \
ORDER BY tts_results.id DESC \
LIMIT ?");
}
@@ -352,7 +383,8 @@ mod tests {
.sort_ascending(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.user_deleted_at IS NULL \
" WHERE tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id ASC \
LIMIT ?");
@@ -365,6 +397,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.id < ? \
AND tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id DESC \
@@ -379,6 +412,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.id > ? \
AND tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id ASC \
@@ -392,7 +426,8 @@ mod tests {
// NB: Does not change the query itself! Just the downstream binding.
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.user_deleted_at IS NULL \
" WHERE tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id DESC \
LIMIT ?");
@@ -405,7 +440,8 @@ mod tests {
// NB: Without a cursor, nothing happens.
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.user_deleted_at IS NULL \
" WHERE tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id DESC \
LIMIT ?");
@@ -420,6 +456,7 @@ mod tests {
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.id > ? \
AND tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id ASC \
@@ -436,6 +473,7 @@ mod tests {
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.id < ? \
AND tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id DESC \
@@ -451,6 +489,27 @@ mod tests {
.cursor_is_reversed(true)
.sort_ascending(true);
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.id < ? \
AND users.username = ? \
AND tts_results.creator_set_visibility = 'public' \
AND tts_results.user_deleted_at IS NULL \
AND tts_results.mod_deleted_at IS NULL \
ORDER BY tts_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_limit_scope_user_show_hidden_offset_cursor_is_reversed_sort_ascending() {
let query_builder = ListTtsResultsQueryBuilder::new()
.limit(1000)
.include_user_hidden(true)
.scope_creator_username(Some("pikachu"))
.offset(Some(100))
.cursor_is_reversed(true)
.sort_ascending(true);
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE tts_results.id < ? \
@@ -52,6 +52,7 @@ pub struct W2lInferenceRecordForList {
/// testability, construction, and correctness.
pub struct ListW2lResultsQueryBuilder {
scope_creator_username: Option<String>,
include_user_hidden: bool,
include_mod_deleted_results: bool,
include_user_deleted_results: bool,
include_templates_not_approved_for_public_listing: bool,
@@ -65,6 +66,7 @@ impl ListW2lResultsQueryBuilder {
pub fn new() -> Self {
Self {
scope_creator_username: None,
include_user_hidden: false,
include_mod_deleted_results: false,
include_user_deleted_results: false,
include_templates_not_approved_for_public_listing: false,
@@ -80,6 +82,11 @@ impl ListW2lResultsQueryBuilder {
self
}
pub fn include_user_hidden(mut self, include_user_hidden: bool) -> Self {
self.include_user_hidden = include_user_hidden;
self
}
pub fn include_mod_deleted_results(mut self, include_mod_deleted_results: bool) -> Self {
self.include_mod_deleted_results = include_mod_deleted_results;
self
@@ -293,6 +300,15 @@ LEFT OUTER JOIN users
}
}
if !self.include_user_hidden {
if !first_predicate_added {
query.push_str(" WHERE w2l_results.creator_set_visibility = 'public'");
first_predicate_added = true;
} else {
query.push_str(" AND w2l_results.creator_set_visibility = 'public'");
}
}
if !self.include_mod_deleted_results {
if !first_predicate_added {
query.push_str(" WHERE w2l_results.mod_deleted_at IS NULL");
@@ -364,6 +380,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
@@ -378,6 +395,20 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE users.username = ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_including_user_hidden() {
let query_builder = ListW2lResultsQueryBuilder::new()
.include_user_hidden(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
@@ -391,6 +422,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
@@ -403,6 +435,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
@@ -416,6 +449,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
@@ -426,7 +460,8 @@ mod tests {
.include_templates_not_approved_for_public_listing(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.mod_deleted_at IS NULL \
" WHERE w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
@@ -439,7 +474,8 @@ mod tests {
.include_mod_deleted_results(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.user_deleted_at IS NULL \
" WHERE w2l_results.creator_set_visibility = 'public' \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
@@ -451,7 +487,8 @@ mod tests {
.include_user_deleted_results(true);
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.mod_deleted_at IS NULL \
" WHERE w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
@@ -464,7 +501,8 @@ mod tests {
.include_templates_not_approved_for_public_listing(true);
assert_eq!(&query_builder.build_predicates(),
" ORDER BY w2l_results.id DESC \
" WHERE w2l_results.creator_set_visibility = 'public' \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
@@ -475,6 +513,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id ASC \
@@ -489,6 +528,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id < ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
@@ -504,6 +544,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id > ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id ASC \
@@ -518,6 +559,7 @@ mod tests {
// NB: Does not change the query itself! Just the downstream binding.
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
@@ -532,6 +574,7 @@ mod tests {
// NB: Without a cursor, nothing happens.
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
@@ -548,6 +591,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id > ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id ASC \
@@ -565,6 +609,7 @@ mod tests {
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id < ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
@@ -580,6 +625,28 @@ mod tests {
.cursor_is_reversed(true)
.sort_ascending(true);
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id < ? \
AND users.username = ? \
AND w2l_templates.is_public_listing_approved IS TRUE \
AND w2l_results.creator_set_visibility = 'public' \
AND w2l_results.mod_deleted_at IS NULL \
AND w2l_results.user_deleted_at IS NULL \
ORDER BY w2l_results.id DESC \
LIMIT ?");
}
#[test]
fn predicates_limit_scope_user_show_hidden_offset_cursor_is_reversed_sort_ascending() {
let query_builder = ListW2lResultsQueryBuilder::new()
.limit(1000)
.include_user_hidden(true)
.scope_creator_username(Some("pikachu"))
.offset(Some(100))
.cursor_is_reversed(true)
.sort_ascending(true);
// NB: This will change the sort order and greater/less than direction!
assert_eq!(&query_builder.build_predicates(),
" WHERE w2l_results.id < ? \
@@ -90,11 +90,14 @@ pub async fn list_user_tts_inference_results_handler(
ListTtsInferenceResultsForUserError::ServerError
})?;
// Permissions & ACLs
let mut viewer_is_user = false;
let mut is_mod_that_can_see_deleted = false;
match maybe_user_session {
None => {},
Some(session) => {
viewer_is_user = path.username == session.username;
is_mod_that_can_see_deleted = session.can_delete_other_users_tts_results;
},
};
@@ -117,9 +120,12 @@ pub async fn list_user_tts_inference_results_handler(
None
};
let include_user_hidden = viewer_is_user || is_mod_that_can_see_deleted;
let mut query_builder = ListTtsResultsQueryBuilder::new()
.sort_ascending(sort_ascending)
.scope_creator_username(Some(path.username.as_ref()))
.include_user_hidden(include_user_hidden)
.include_mod_disabled_results(is_mod_that_can_see_deleted)
.limit(limit)
.cursor_is_reversed(cursor_is_reversed)
@@ -120,11 +120,13 @@ pub async fn list_user_w2l_inference_results_handler(
None
};
let include_user_hidden = is_author || is_mod_that_can_see_deleted;
let include_unapproved = is_author || is_mod_that_can_approve_w2l_templates;
let mut query_builder = ListW2lResultsQueryBuilder::new()
.sort_ascending(sort_ascending)
.scope_creator_username(Some(path.username.as_ref()))
.include_user_hidden(include_user_hidden)
.include_user_deleted_results(is_mod_that_can_see_deleted)
.include_mod_deleted_results(is_mod_that_can_see_deleted)
.include_templates_not_approved_for_public_listing(include_unapproved)
+1 -1
View File
@@ -213,7 +213,7 @@ async fn main_loop(downloader: Downloader) {
if jobs.is_empty() {
noop_logger.log_after_awhile();
std::thread::sleep(Duration::from_millis(downloader.job_batch_wait_millis));
continue;
}