Merge pull request #1227 from trheyi/main

Add current team retrieval endpoint and refactor team access checks
This commit is contained in:
Max 2025-10-23 18:15:09 +08:00 committed by GitHub
commit 932a8d2c0e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 85 additions and 5 deletions

View file

@ -49,7 +49,7 @@ func GinTeamConfig(c *gin.Context) {
// GinTeamList handles GET /teams - Get user teams (all teams where user is a member)
func GinTeamList(c *gin.Context) {
// Get authorized user info
authInfo := oauth.GetAuthorizedInfo(c)
authInfo := authorized.GetInfo(c)
if authInfo == nil || authInfo.UserID == "" {
errorResp := &response.ErrorResponse{
Code: response.ErrInvalidClient.Code,
@ -312,6 +312,61 @@ func GinTeamUpdate(c *gin.Context) {
response.RespondWithSuccess(c, http.StatusOK, team)
}
// GinTeamCurrent handles GET /teams/current - Get current team
func GinTeamCurrent(c *gin.Context) {
authInfo := authorized.GetInfo(c)
if authInfo == nil || authInfo.UserID == "" {
errorResp := &response.ErrorResponse{
Code: response.ErrInvalidClient.Code,
ErrorDescription: "User not authenticated",
}
response.RespondWithError(c, response.StatusUnauthorized, errorResp)
return
}
// Get current team
teamID := authInfo.TeamID
// If no team ID, get the user teams from provider first
if teamID == "" {
// Get user teams
teams, err := getOwnerTeams(c.Request.Context(), authInfo.UserID)
if err != nil {
log.Error("Failed to get owner teams: %v", err)
errorResp := &response.ErrorResponse{
Code: response.ErrServerError.Code,
ErrorDescription: "Failed to get owner teams",
}
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
}
if len(teams) == 0 {
errorResp := &response.ErrorResponse{
Code: response.ErrInvalidRequest.Code,
ErrorDescription: "No owner team found for user",
}
response.RespondWithError(c, response.StatusNotFound, errorResp)
return
}
teamID = teams[0]["team_id"].(string)
}
// Get team details
team, err := teamGet(c.Request.Context(), authInfo.UserID, teamID)
if err != nil {
log.Error("Failed to get team details: %v", err)
errorResp := &response.ErrorResponse{
Code: response.ErrServerError.Code,
ErrorDescription: "Failed to get team details",
}
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
}
response.RespondWithSuccess(c, http.StatusOK, team)
}
// GinTeamSelection handles POST /teams/select - Select a team and issue tokens with team_id
func GinTeamSelection(c *gin.Context) {
// Get authorized user info
@ -672,10 +727,14 @@ func teamGet(ctx context.Context, userID, teamID string) (maps.MapStrAny, error)
return nil, fmt.Errorf("failed to retrieve team details: %w", err)
}
// Check if user owns this team
ownerID := toString(teamData["owner_id"])
if ownerID != userID {
return nil, fmt.Errorf("access denied: user does not own this team")
// Validate if user is a member of the team
exists, err := provider.MemberExists(ctx, teamID, userID)
if err != nil {
return nil, fmt.Errorf("failed to retrieve team member record: %w", err)
}
if !exists {
return nil, fmt.Errorf("user is not a member of this team")
}
return teamData, nil
@ -922,6 +981,24 @@ func getUserTeams(ctx context.Context, userID string) ([]maps.MapStr, error) {
return teams, nil
}
// getOwnerTeams gets all teams where the user is the owner
func getOwnerTeams(ctx context.Context, userID string) ([]maps.MapStr, error) {
// Get user provider instance
provider, err := getUserProvider()
if err != nil {
return nil, fmt.Errorf("failed to get user provider: %w", err)
}
// Get owner team
teams, err := provider.GetTeamsByOwner(ctx, userID)
if err != nil {
return nil, fmt.Errorf("failed to retrieve owner team: %w", err)
}
// Return the first team as the owner team
return teams, nil
}
// getUserTeamsCount counts the number of teams a user is a member of
func getUserTeamsCount(ctx context.Context, userID string) (int64, error) {
// Get user provider instance

View file

@ -129,6 +129,9 @@ func attachTeam(group *gin.RouterGroup, oauth types.OAuth) {
team.PUT("/:id", GinTeamUpdate) // PUT /teams/:id - Update team
team.DELETE("/:id", GinTeamDelete) // DELETE /teams/:id - Delete team
// Get Current Team
team.GET("/current", GinTeamCurrent)
// Team Members - Nested resource endpoints
team.GET("/:id/members", GinMemberList) // GET /teams/:id/members - List team members
team.POST("/:id/members", GinMemberCreateDirect) // POST /teams/:id/members - Add team member