headless_lms_server/controllers/course_material/
user_details.rs

1use std::net::IpAddr;
2
3use headless_lms_utils::ip_to_country::IpToCountryMapper;
4use models::user_details::UserDetail;
5
6use crate::prelude::*;
7
8/**
9GET `/api/v0/course-material/user-details/user` - Find user details by user id
10*/
11#[instrument(skip(pool))]
12pub async fn get_user_details(
13    user: AuthUser,
14    pool: web::Data<PgPool>,
15) -> ControllerResult<web::Json<UserDetail>> {
16    let mut conn = pool.acquire().await?;
17
18    let token = skip_authorize();
19
20    let res = models::user_details::get_user_details_by_user_id(&mut conn, user.id).await?;
21    token.authorized_ok(web::Json(res))
22}
23
24#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
25#[cfg_attr(feature = "ts_rs", derive(TS))]
26pub struct UserInfoPayload {
27    pub first_name: String,
28    pub last_name: String,
29    pub country: String,
30}
31
32/**
33POST `/api/v0/course-material/user-details/update-user-info` - Updates the users first and last name and country to what they have selected
34*/
35#[instrument(skip(pool))]
36pub async fn update_user_info(
37    user: AuthUser,
38    pool: web::Data<PgPool>,
39    payload: web::Json<UserInfoPayload>,
40) -> ControllerResult<web::Json<bool>> {
41    let mut conn = pool.acquire().await?;
42    models::user_details::update_user_info(
43        &mut conn,
44        user.id,
45        &payload.first_name,
46        &payload.last_name,
47        &payload.country,
48    )
49    .await?;
50
51    let token = skip_authorize();
52    token.authorized_ok(web::Json(true))
53}
54
55/**
56GET `/api/v0/course-material/user-details/users-ip-country` - Find users country by their IP  address
57*/
58pub async fn get_user_country_by_ip(
59    req: HttpRequest,
60    ip_to_country_mapper: web::Data<IpToCountryMapper>,
61) -> ControllerResult<String> {
62    let connection_info = req.connection_info();
63
64    let ip: Option<IpAddr> = connection_info
65        .realip_remote_addr()
66        .and_then(|ip| ip.parse::<IpAddr>().ok());
67
68    let country = ip
69        .and_then(|ip| ip_to_country_mapper.map_ip_to_country(&ip))
70        .map(|c| c.to_string())
71        .unwrap_or_default();
72
73    let token = skip_authorize();
74    token.authorized_ok(country.to_string())
75}
76
77/**
78Add a route for each controller in this module.
79
80The name starts with an underline in order to appear before other functions in the module documentation.
81
82We add the routes by calling the route method instead of using the route annotations because this method preserves the function signatures for documentation.
83*/
84pub fn _add_routes(cfg: &mut ServiceConfig) {
85    cfg.route("/user", web::get().to(get_user_details))
86        .route("/update-user-info", web::post().to(update_user_info))
87        .route("/users-ip-country", web::get().to(get_user_country_by_ip));
88}