Skip to content

Commit e43f771

Browse files
authored
feat: enhance user retrieval and username uniqueness checks in CoderAPI (#86)
- Updated get_users method to support optional query, limit, and offset parameters for improved user filtering. - Refactored get_user_by_email to utilize the updated get_users method for better efficiency. - Added check_username_exists method to verify if a username is already taken. - Improved username creation logic to ensure uniqueness by appending random numbers if necessary, with a maximum of 1000 attempts. - Enhanced documentation for clarity on method functionalities and parameters.
1 parent ae7f86a commit e43f771

File tree

1 file changed

+57
-24
lines changed

1 file changed

+57
-24
lines changed

src/backend/coder.py

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import requests
2+
import random
23
from config import CODER_API_KEY, CODER_URL, CODER_TEMPLATE_ID, CODER_DEFAULT_ORGANIZATION, CODER_WORKSPACE_NAME
34

45
class CoderAPI:
@@ -32,31 +33,59 @@ def _get_all_templates(self):
3233
response.raise_for_status()
3334
return response.json()
3435

35-
36-
def get_users(self):
36+
37+
def get_users(self, query=None, limit=None, offset=None) -> list[dict] | list:
3738
"""
38-
Get all users from the Coder API
39+
Get users from the Coder API
40+
41+
Args:
42+
query (str, optional): Search query to filter users (q parameter)
43+
limit (int, optional): Page limit
44+
offset (int, optional): Page offset
45+
46+
Returns:
47+
list: List of user objects
3948
"""
4049
endpoint = f"{self.coder_url}/api/v2/users"
41-
response = requests.get(endpoint, headers=self.headers)
50+
params = {}
51+
52+
if query:
53+
params['q'] = query
54+
if limit:
55+
params['limit'] = limit
56+
if offset:
57+
params['offset'] = offset
58+
59+
response = requests.get(endpoint, headers=self.headers, params=params)
4260
response.raise_for_status() # Raise exception for 4XX/5XX responses
61+
4362
return response.json()['users']
4463

45-
def get_user_by_email(self, email):
64+
def get_user_by_email(self, email) -> dict | None:
4665
"""
47-
Get a user by email
66+
Get a user by email using the query parameter
4867
4968
Args:
5069
email (str): email to search for
5170
5271
Returns:
5372
dict: User data if found, None otherwise
5473
"""
55-
users = self.get_users()
56-
for user in users:
57-
if user['email'] == email:
58-
return user
59-
return None
74+
users = self.get_users(query=email, limit=1)
75+
return users[0] if users else None
76+
77+
def check_username_exists(self, username):
78+
"""
79+
Check if a username already exists
80+
81+
Args:
82+
username (str): Username to check
83+
84+
Returns:
85+
bool: True if username exists, False otherwise
86+
"""
87+
users = self.get_users(query=username)
88+
return bool(users)
6089

6190
def create_user(self, username, email, name):
6291
"""
@@ -122,19 +151,23 @@ def ensure_user_exists(self, user_info):
122151
if not base_username:
123152
base_username = 'user'
124153

125-
# Ensure username is unique
154+
# Ensure username is unique using random numbers between 1-100000
126155
username = base_username
127-
for i in range(10):
128-
# Check if username exists
129-
users = self.get_users()
130-
username_exists = any(user['username'] == username for user in users)
131-
if not username_exists:
132-
break
133-
# If username exists, append a number
134-
username = f"{base_username}{i}"
135-
else:
136-
raise Exception("Failed to create unique username")
137-
156+
157+
# First check if the base username itself is available
158+
if self.check_username_exists(username):
159+
# Try up to 10 times to find a unique username with random numbers
160+
max_attempts = 1000
161+
for _ in range(max_attempts):
162+
random_suffix = random.randint(1, 100000)
163+
username = f"{base_username}{random_suffix}"
164+
165+
if not self.check_username_exists(username):
166+
break
167+
else:
168+
# If we exhausted all attempts, raise an exception
169+
raise Exception(f"uhh... failed to create unique username for {email} after {max_attempts} attempts")
170+
138171
new_user = self.create_user(username, email, name)
139172
return new_user, True
140173

@@ -310,4 +343,4 @@ def set_workspace_dormancy(self, workspace_id, dormant: bool):
310343
headers['Content-Type'] = 'application/json'
311344
response = requests.put(endpoint, headers=headers, json=data)
312345
response.raise_for_status()
313-
return response.json()
346+
return response.json()

0 commit comments

Comments
 (0)