from typing import List, Dict, Any, Optional from sigma_api_client import SigmaAPIClient from user_management import UserManager class TeamManager: """ Manages Sigma teams and team membership """ def __init__(self, api_client: SigmaAPIClient): self.api = api_client self.user_manager = UserManager(api_client) def list_teams(self, limit: int = 50) -> List[Dict[str, Any]]: """ List all teams in the organization Args: limit: Maximum number of teams to return """ try: params = {'limit': limit} response = self.api.get('/v2/teams', params=params) return response.get('entries', []) except Exception as e: print(f"Error listing teams: {e}") return [] def get_team_by_name(self, team_name: str) -> Optional[Dict[str, Any]]: """ Find a team by name Args: team_name: Name of the team to find """ teams = self.list_teams() for team in teams: if team.get('name', '').lower() == team_name.lower(): return team return None def get_team_details(self, team_id: str) -> Optional[Dict[str, Any]]: """ Get detailed information about a team Args: team_id: ID of the team """ try: return self.api.get(f'/v2/teams/{team_id}') except Exception as e: print(f"Error getting team details: {e}") return None def list_team_members(self, team_id: str) -> List[Dict[str, Any]]: """ List all members of a team Args: team_id: ID of the team """ try: # Get team details which includes members array team_details = self.api.get(f'/v2/teams/{team_id}') members = team_details.get('members', []) # Convert member IDs to member objects member_list = [] for member_id in members: member_list.append({'memberId': member_id}) return member_list except Exception as e: print(f"Error listing team members: {e}") return [] def add_users_to_team(self, team_id: str, user_emails: List[str]) -> Dict[str, Any]: """ Add multiple users to a team Args: team_id: ID of the team user_emails: List of user email addresses to add """ results = { 'team_id': team_id, 'requested_users': user_emails, 'successful_additions': [], 'failed_additions': [], 'already_members': [], 'users_not_found': [] } # Get current team members current_members = self.list_team_members(team_id) current_member_ids = {member.get('memberId') for member in current_members} # Resolve user emails to member IDs users_to_add = [] for email in user_emails: user = self.user_manager.get_member_by_email(email) if not user: results['users_not_found'].append(email) continue user_id = user['memberId'] if user_id in current_member_ids: results['already_members'].append(email) continue # Check if user is active if not user.get('isActive', True): results['failed_additions'].append({ 'email': email, 'error': 'User is inactive' }) continue users_to_add.append({ 'email': email, 'user_id': user_id, 'user': user }) # Add users to team if users_to_add: try: # Prepare the member list for the API call # Get current members and add new ones all_member_ids = list(current_member_ids) for user_info in users_to_add: all_member_ids.append(user_info['user_id']) # Update team members update_data = { 'members': [{'memberId': member_id} for member_id in all_member_ids] } response = self.api.patch(f'/v2/teams/{team_id}/members', update_data) # Mark all as successful if the API call succeeded for user_info in users_to_add: results['successful_additions'].append(user_info['email']) except Exception as e: # If bulk update fails, mark all as failed for user_info in users_to_add: results['failed_additions'].append({ 'email': user_info['email'], 'error': str(e) }) return results def remove_users_from_team(self, team_id: str, user_emails: List[str]) -> Dict[str, Any]: """ Remove multiple users from a team Args: team_id: ID of the team user_emails: List of user email addresses to remove """ results = { 'team_id': team_id, 'requested_users': user_emails, 'successful_removals': [], 'failed_removals': [], 'not_members': [], 'users_not_found': [] } # Get current team members current_members = self.list_team_members(team_id) current_member_map = {member.get('memberId'): member for member in current_members} # Resolve user emails to member IDs users_to_remove = [] for email in user_emails: user = self.user_manager.get_member_by_email(email) if not user: results['users_not_found'].append(email) continue user_id = user['memberId'] if user_id not in current_member_map: results['not_members'].append(email) continue users_to_remove.append({ 'email': email, 'user_id': user_id, 'user': user }) # Remove users from team if users_to_remove: try: # Prepare the updated member list (excluding users to remove) users_to_remove_ids = {user_info['user_id'] for user_info in users_to_remove} remaining_member_ids = [ member_id for member_id in current_member_map.keys() if member_id not in users_to_remove_ids ] # Update team members update_data = { 'members': [{'memberId': member_id} for member_id in remaining_member_ids] } response = self.api.patch(f'/v2/teams/{team_id}/members', update_data) # Mark all as successful if the API call succeeded for user_info in users_to_remove: results['successful_removals'].append(user_info['email']) except Exception as e: # If bulk update fails, mark all as failed for user_info in users_to_remove: results['failed_removals'].append({ 'email': user_info['email'], 'error': str(e) }) return results def get_team_summary(self, team_name: str) -> Dict[str, Any]: """ Get a comprehensive summary of a team Args: team_name: Name of the team """ team = self.get_team_by_name(team_name) if not team: return {'error': f'Team "{team_name}" not found'} team_id = team['teamId'] team_details = self.get_team_details(team_id) team_members = self.list_team_members(team_id) # Get member details member_details = [] for member in team_members: member_id = member.get('memberId') if member_id: # Try to find user details user_details = None all_users = self.user_manager.list_members() for user in all_users: if user.get('memberId') == member_id: user_details = user break member_details.append({ 'member_id': member_id, 'email': user_details.get('email', 'Unknown') if user_details else 'Unknown', 'name': f"{user_details.get('firstName', '')} {user_details.get('lastName', '')}" if user_details else 'Unknown', 'account_type': user_details.get('accountType', 'Unknown') if user_details else 'Unknown', 'is_active': user_details.get('isActive', False) if user_details else False }) return { 'team': team, 'details': team_details, 'members': member_details, 'member_count': len(member_details) }