1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//! Service layer for user data.

use reqwest::StatusCode;
use uuid::Uuid;

use crate::{
    config::data::{SharedHttpClient, SharedKeycloakApi, SharedPool},
    error::ServiceError,
    keycloak_api::dtos::UserDto,
    model::{
        dto::{PageParameters, UserSearchParameters, UsersDto},
        entity::Users,
    },
};

/// Create a user data entry for a new user.
///
/// # Errors
/// If the connection to the database could not be established.
pub async fn create(
    user_id: Uuid,
    user_data: UsersDto,
    pool: &SharedPool,
) -> Result<UsersDto, ServiceError> {
    let mut conn = pool.get().await?;
    let result = Users::create(user_data, user_id, &mut conn).await?;
    Ok(result)
}

/// Get a user by its id.
///
/// # Errors
/// * If the connection to the Keycloak API could not be established.
pub async fn find_by_id(
    user_id: Uuid,
    keycloak_api: &SharedKeycloakApi,
    http_client: &SharedHttpClient,
) -> Result<UserDto, ServiceError> {
    let user = keycloak_api
        .get_user_by_id(http_client, user_id)
        .await
        .map_err(|e| {
            log::error!("Error getting user data from Keycloak API: {e}");
            ServiceError::new(
                StatusCode::INTERNAL_SERVER_ERROR,
                "Error getting user data from Keycloak API",
            )
        })?;

    Ok(user)
}

/// Get users by their ids.
///
/// # Errors
/// * If the connection to the Keycloak API could not be established.
pub async fn find_by_ids(
    user_ids: Vec<Uuid>,
    keycloak_api: &SharedKeycloakApi,
    http_client: &SharedHttpClient,
) -> Result<Vec<UserDto>, ServiceError> {
    let users = keycloak_api
        .get_users_by_ids(http_client, user_ids)
        .await
        .map_err(|e| {
            log::error!("Error getting user data from Keycloak API: {e}");
            ServiceError::new(
                StatusCode::INTERNAL_SERVER_ERROR,
                "Error getting user data from Keycloak API",
            )
        })?;

    Ok(users)
}

/// Search for users by their username.
///
/// # Errors
/// * If the connection to the Keycloak API could not be established.
pub async fn search_by_username(
    search_params: &UserSearchParameters,
    pagination: &PageParameters,
    user_id: Uuid,
    keycloak_api: &SharedKeycloakApi,
    http_client: &SharedHttpClient,
) -> Result<Vec<UserDto>, ServiceError> {
    let users = keycloak_api
        .search_users_by_username(search_params, pagination, http_client)
        .await
        .map_err(|e| {
            log::error!("Error getting user data from Keycloak API: {e}");
            ServiceError::new(
                StatusCode::INTERNAL_SERVER_ERROR,
                format!("Error getting user data from Keycloak API: {e}").as_str(),
            )
        })?;

    // Filter out the user making the request
    let filtered_users = users
        .iter()
        .filter(|user| user.id != user_id)
        .cloned()
        .collect::<Vec<_>>();

    Ok(filtered_users)
}