headless_lms_server/controllers/main_frontend/
user_details.rs1use models::{pages::SearchRequest, user_details::UserDetail};
2
3use crate::prelude::*;
4use headless_lms_utils::ip_to_country::IpToCountryMapper;
5use std::net::IpAddr;
6
7#[instrument(skip(pool))]
11pub async fn get_user_details(
12 user: AuthUser,
13 pool: web::Data<PgPool>,
14 user_id: web::Path<Uuid>,
15) -> ControllerResult<web::Json<UserDetail>> {
16 let mut conn = pool.acquire().await?;
17
18 let token = authorize(
19 &mut conn,
20 Act::ViewUserProgressOrDetails,
21 Some(user.id),
22 Res::GlobalPermissions,
23 )
24 .await?;
25 let res = models::user_details::get_user_details_by_user_id(&mut conn, *user_id).await?;
26 token.authorized_ok(web::Json(res))
27}
28
29#[instrument(skip(pool))]
33pub async fn search_users_by_email(
34 user: AuthUser,
35 pool: web::Data<PgPool>,
36 payload: web::Json<SearchRequest>,
37) -> ControllerResult<web::Json<Vec<UserDetail>>> {
38 let mut conn = pool.acquire().await?;
39
40 let token = authorize(
41 &mut conn,
42 Act::ViewUserProgressOrDetails,
43 Some(user.id),
44 Res::GlobalPermissions,
45 )
46 .await?;
47 let res =
48 models::user_details::search_for_user_details_by_email(&mut conn, &payload.query).await?;
49 token.authorized_ok(web::Json(res))
50}
51
52#[instrument(skip(pool))]
56pub async fn search_users_by_other_details(
57 user: AuthUser,
58 pool: web::Data<PgPool>,
59 payload: web::Json<SearchRequest>,
60) -> ControllerResult<web::Json<Vec<UserDetail>>> {
61 let mut conn = pool.acquire().await?;
62
63 let token = authorize(
64 &mut conn,
65 Act::ViewUserProgressOrDetails,
66 Some(user.id),
67 Res::GlobalPermissions,
68 )
69 .await?;
70 let res =
71 models::user_details::search_for_user_details_by_other_details(&mut conn, &payload.query)
72 .await?;
73 token.authorized_ok(web::Json(res))
74}
75
76#[instrument(skip(pool))]
80pub async fn search_users_fuzzy_match(
81 user: AuthUser,
82 pool: web::Data<PgPool>,
83 payload: web::Json<SearchRequest>,
84) -> ControllerResult<web::Json<Vec<UserDetail>>> {
85 let mut conn = pool.acquire().await?;
86
87 let token = authorize(
88 &mut conn,
89 Act::ViewUserProgressOrDetails,
90 Some(user.id),
91 Res::GlobalPermissions,
92 )
93 .await?;
94 let res = models::user_details::search_for_user_details_fuzzy_match(&mut conn, &payload.query)
95 .await?;
96 token.authorized_ok(web::Json(res))
97}
98
99pub async fn get_users_by_course_id(
103 course_id: web::Path<Uuid>,
104 user: AuthUser,
105 pool: web::Data<PgPool>,
106) -> ControllerResult<web::Json<Vec<UserDetail>>> {
107 let mut conn = pool.acquire().await?;
108
109 let token = authorize(
110 &mut conn,
111 Act::ViewUserProgressOrDetails,
112 Some(user.id),
113 Res::Course(*course_id),
114 )
115 .await?;
116 let res = models::user_details::get_users_by_course_id(&mut conn, *course_id).await?;
117 token.authorized_ok(web::Json(res))
118}
119
120pub async fn get_user_country_by_ip(
121 req: HttpRequest,
122 ip_to_country_mapper: web::Data<IpToCountryMapper>,
123) -> ControllerResult<String> {
124 let connection_info = req.connection_info();
125
126 let ip: Option<IpAddr> = connection_info
127 .realip_remote_addr()
128 .and_then(|ip| ip.parse::<IpAddr>().ok());
129
130 let country = ip
131 .and_then(|ip| ip_to_country_mapper.map_ip_to_country(&ip))
132 .map(|c| c.to_string())
133 .unwrap_or_default();
134
135 let token = skip_authorize();
136 token.authorized_ok(country)
137}
138
139pub fn _add_routes(cfg: &mut ServiceConfig) {
140 cfg.route("/search-by-email", web::post().to(search_users_by_email))
141 .route(
142 "/search-by-other-details",
143 web::post().to(search_users_by_other_details),
144 )
145 .route(
146 "/search-fuzzy-match",
147 web::post().to(search_users_fuzzy_match),
148 )
149 .route("/user/{user_id}", web::get().to(get_user_details))
150 .route("/users-ip-country", web::get().to(get_user_country_by_ip))
151 .route(
152 "/{course_id}/get-users-by-course-id",
153 web::get().to(get_users_by_course_id),
154 );
155}