Skip to content

Commit cd4104b

Browse files
committed
search curators
1 parent dc60135 commit cd4104b

5 files changed

Lines changed: 152 additions & 7 deletions

File tree

openapi.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,13 @@ paths:
758758
schema:
759759
$ref: "#/components/schemas/TrustType"
760760
example: Ndaed
761+
- in: query
762+
name: c
763+
description: search for potential curators (requires g to be set)
764+
required: false
765+
schema:
766+
type: string
767+
example: true
761768
responses:
762769
"200":
763770
description: the top matches of users

src/api/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub enum ApiError {
2525
ScopeError(TrustError),
2626
#[fail(display = "Groups scope Error: {}", _0)]
2727
GroupsScopeError(GroupsTrustError),
28+
#[fail(display = "Invalid query parameters.")]
29+
InvalidQuery,
2830
}
2931

3032
fn to_json_error(e: &impl Display) -> Value {

src/api/users.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ struct SearchUsersQuery {
1616
q: String,
1717
t: Option<TrustType>,
1818
g: Option<String>,
19+
#[serde(default)]
20+
c: bool,
1921
}
2022

2123
#[guard(Ndaed)]
@@ -24,13 +26,18 @@ async fn search_users(
2426
scope_and_user: ScopeAndUser,
2527
query: web::Query<SearchUsersQuery>,
2628
) -> impl Responder {
27-
match operations::users::search_users(
28-
&pool,
29-
scope_and_user,
30-
query.g.clone(),
31-
query.t.clone(),
32-
&query.q,
33-
) {
29+
let query = query.into_inner();
30+
let users = if query.c {
31+
match query.g {
32+
Some(group_name) => {
33+
operations::users::search_admins(&pool, scope_and_user, group_name, &query.q)
34+
}
35+
_ => return Err(ApiError::InvalidQuery),
36+
}
37+
} else {
38+
operations::users::search_users(&pool, scope_and_user, query.g, query.t, &query.q)
39+
};
40+
match users {
3441
Ok(users) => Ok(HttpResponse::Ok().json(users)),
3542
Err(e) => Err(ApiError::GenericBadRequest(e)),
3643
}

src/db/internal/user.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::db::internal;
22
use crate::db::schema;
3+
use crate::db::types::RoleType;
34
use crate::db::types::TrustType;
45
use crate::db::users::UserProfile;
56
use crate::db::users::*;
@@ -165,6 +166,7 @@ pub fn update_user_cache(connection: &PgConnection, profile: &Profile) -> Result
165166
.execute(connection)?;
166167
Ok(())
167168
}
169+
168170
macro_rules! scoped_search_users_for_group {
169171
($g:ident, $t:ident, $typ:ident, $q:ident, $trust:ident, $limit:ident, $connection:ident) => {{
170172
use schema::$t as u;
@@ -200,6 +202,51 @@ macro_rules! scoped_search_users_for_group {
200202
}};
201203
}
202204

205+
/*
206+
.inner_join(schema::roles::table)
207+
.on(schema::roles::role_id.eq(schema::memberships::role_id))
208+
.filter(schema::memberships::group_id.eq($g))
209+
.filter(schema::roles::typ.ne(RoleType::Member))
210+
.select(schema::memberships::all_columns))
211+
*/
212+
macro_rules! scoped_search_curators_for_group {
213+
($g:ident, $t:ident, $typ:ident, $q:ident, $trust:ident, $limit:ident, $connection:ident) => {{
214+
use schema::$t as u;
215+
u::table
216+
.filter(
217+
u::first_name
218+
.concat(" ")
219+
.concat(u::last_name)
220+
.ilike($q)
221+
.or(u::first_name.ilike($q))
222+
.or(u::last_name.ilike($q))
223+
.or(u::username.ilike($q))
224+
.or(u::email.ilike($q)),
225+
)
226+
.filter(u::trust.ge($trust))
227+
.left_outer_join(
228+
schema::memberships::table.on(schema::memberships::user_uuid
229+
.eq(u::user_uuid)
230+
.and(schema::memberships::group_id.eq($g))),
231+
)
232+
.left_outer_join(
233+
schema::roles::table.on(schema::roles::role_id.eq(schema::memberships::role_id)),
234+
)
235+
.filter(
236+
schema::memberships::group_id
237+
.is_null()
238+
.or(schema::memberships::group_id
239+
.ne($g)
240+
.or(schema::roles::typ.eq(RoleType::Member))),
241+
)
242+
.select(u::all_columns)
243+
.limit($limit)
244+
.get_results::<$typ>($connection)
245+
.map(|users| users.into_iter().map(|u| u.into()).collect())
246+
.map_err(Into::into)
247+
}};
248+
}
249+
203250
macro_rules! scoped_search_users {
204251
($t:ident, $typ:ident, $q:ident, $trust:ident, $limit:ident, $connection:ident) => {{
205252
use schema::$t as u;
@@ -222,6 +269,64 @@ macro_rules! scoped_search_users {
222269
}};
223270
}
224271

272+
pub fn search_curators_for_group(
273+
connection: &PgConnection,
274+
group_name: &str,
275+
scope: TrustType,
276+
q: &str,
277+
limit: i64,
278+
) -> Result<Vec<DisplayUser>, Error> {
279+
let q: &str = &format!("{}%", q);
280+
let group_id = internal::group::get_group(connection, group_name)?.id;
281+
let trust = TrustType::Ndaed;
282+
match scope {
283+
TrustType::Staff => scoped_search_curators_for_group!(
284+
group_id,
285+
users_staff,
286+
UsersStaff,
287+
q,
288+
trust,
289+
limit,
290+
connection
291+
),
292+
TrustType::Ndaed => scoped_search_curators_for_group!(
293+
group_id,
294+
users_ndaed,
295+
UsersNdaed,
296+
q,
297+
trust,
298+
limit,
299+
connection
300+
),
301+
TrustType::Vouched => scoped_search_curators_for_group!(
302+
group_id,
303+
users_vouched,
304+
UsersVouched,
305+
q,
306+
trust,
307+
limit,
308+
connection
309+
),
310+
TrustType::Authenticated => scoped_search_curators_for_group!(
311+
group_id,
312+
users_authenticated,
313+
UsersAuthenticated,
314+
q,
315+
trust,
316+
limit,
317+
connection
318+
),
319+
TrustType::Public => scoped_search_curators_for_group!(
320+
group_id,
321+
users_public,
322+
UsersPublic,
323+
q,
324+
trust,
325+
limit,
326+
connection
327+
),
328+
}
329+
}
225330
pub fn search_users_for_group(
226331
connection: &PgConnection,
227332
group_name: &str,

src/db/operations/users.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,30 @@ pub fn search_users(
6666
}
6767
}
6868

69+
pub fn search_admins(
70+
pool: &Pool,
71+
scope_and_user: ScopeAndUser,
72+
group_name: String,
73+
q: &str,
74+
) -> Result<Vec<DisplayUser>, Error> {
75+
let connection = pool.get()?;
76+
let host = internal::user::user_by_id(&connection, &scope_and_user.user_id)?;
77+
SEARCH_USERS.run(&RuleContext::minimal(
78+
pool,
79+
&scope_and_user,
80+
&group_name,
81+
&host.user_uuid,
82+
))?;
83+
84+
internal::user::search_curators_for_group(
85+
&connection,
86+
&group_name,
87+
scope_and_user.scope.into(),
88+
q,
89+
5,
90+
)
91+
}
92+
6993
pub fn delete_user(pool: &Pool, user: &User) -> Result<(), Error> {
7094
let connection = pool.get()?;
7195
internal::user::delete_user(&connection, user)

0 commit comments

Comments
 (0)