From cb6eef2054219d3c9cd37c3a2cc999368789bfa2 Mon Sep 17 00:00:00 2001 From: MythEclipse Date: Mon, 27 Oct 2025 17:44:13 +0700 Subject: [PATCH] feat: Add endpoint to retrieve the current user's team and corresponding service logic --- imphnen-iam/src/v1/teams/teams_controller.rs | 21 ++++++++++++++ imphnen-iam/src/v1/teams/teams_service.rs | 29 ++++++++++++++++++++ tests/iam/test-teams.sh | 3 ++ 3 files changed, 53 insertions(+) diff --git a/imphnen-iam/src/v1/teams/teams_controller.rs b/imphnen-iam/src/v1/teams/teams_controller.rs index 536eb5b..fcec51a 100644 --- a/imphnen-iam/src/v1/teams/teams_controller.rs +++ b/imphnen-iam/src/v1/teams/teams_controller.rs @@ -390,6 +390,26 @@ pub async fn post_leave_current_team( authenticated(headers, Extension(state), |claims, state| TeamsService::leave_current_team(&state, claims)).await } +#[utoipa::path( + get, + security( + ("Bearer" = []) + ), + path = "/v1/teams/me", + responses( + (status = 200, description = "[AUTH] Get my team", body = ResponseSuccessDto), + (status = 401, description = "[AUTH] Unauthorized"), + (status = 404, description = "[AUTH] User is not a member of any team") + ), + tag = "Teams" +)] +pub async fn get_my_team( + headers: HeaderMap, + Extension(state): Extension, +) -> impl IntoResponse { + authenticated(headers, Extension(state), |claims, state| TeamsService::get_my_team(&state, claims)).await +} + #[utoipa::path( get, security( @@ -486,4 +506,5 @@ pub fn teams_router() -> Router { .route("/{id}/members/{user_id}", axum::routing::delete(delete_remove_team_member)) .route("/{id}/leave", axum::routing::post(post_leave_team)) .route("/leave-me", axum::routing::post(post_leave_current_team)) + .route("/me", axum::routing::get(get_my_team)) } diff --git a/imphnen-iam/src/v1/teams/teams_service.rs b/imphnen-iam/src/v1/teams/teams_service.rs index ee56b5c..580fbb0 100644 --- a/imphnen-iam/src/v1/teams/teams_service.rs +++ b/imphnen-iam/src/v1/teams/teams_service.rs @@ -38,6 +38,7 @@ pub trait TeamsServiceTrait: Send + Sync + 'static { fn get_team_members(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims, team_id: String) -> Pin + Send>>; fn leave_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims, team_id: String) -> Pin + Send>>; fn leave_current_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims) -> Pin + Send>>; + fn get_my_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims) -> Pin + Send>>; fn search_teams(state: &AppState, search_params: TeamsSearchQueryDto) -> Pin + Send>>; fn get_admin_team_list(state: &AppState, meta: MetaRequestDto) -> Pin + Send>>; fn get_admin_team_by_id(state: &AppState, id: String) -> Pin + Send>>; @@ -1058,4 +1059,32 @@ impl TeamsServiceTrait for TeamsService { } }) } + + fn get_my_team(state: &AppState, claims: imphnen_libs::jsonwebtoken::Claims) -> Pin + Send>> { + let state = state.to_owned(); + Box::pin(async move { + let repo = TeamsRepository::new(&state); + let user_thing = make_thing_from_enum(ResourceEnum::Users, &claims.user_id); + + // Find the teams that the user is a member of + let teams = match repo.query_teams_by_user(&user_thing).await { + Ok(teams) => teams, + Err(e) => { + error!("Failed to query user teams: {}", e); + return common_response(StatusCode::INTERNAL_SERVER_ERROR, "Failed to retrieve user teams") + }, + }; + + if teams.is_empty() { + return common_response(StatusCode::NOT_FOUND, "User is not a member of any team"); + } + + // Return the first team (most common case - user is in one team) + let team = &teams[0]; + let team_id = team.id.id.to_raw(); + + // Get full team details + Self::get_public_team_by_id(&state, team_id).await + }) + } } \ No newline at end of file diff --git a/tests/iam/test-teams.sh b/tests/iam/test-teams.sh index 3058a26..8df7baa 100644 --- a/tests/iam/test-teams.sh +++ b/tests/iam/test-teams.sh @@ -84,6 +84,9 @@ test_team_endpoints() { # test_api_endpoint "POST Leave Team" "POST" "/v1/teams/$created_team_id/leave" 200 "" true # test_api_endpoint "POST Leave Current Team" "POST" "/v1/teams/leave-me" 200 "" true + # === Get My Team === + test_api_endpoint "GET My Team" "GET" "/v1/teams/me" 200 "" true + # Delete team (cleanup) test_api_endpoint "DELETE Team" "DELETE" "/v1/teams/delete/$created_team_id" 200 "" true fi