@@ -207,6 +207,90 @@ def update(
207207 handle_error (e )
208208
209209
210+ @click .command ('update-profile' )
211+ @click .argument ('user_id' , type = int )
212+ @click .option ('--first-name' , help = 'New first name' )
213+ @click .option ('--last-name' , help = 'New last name' )
214+ @click .option ('--password' , help = 'New password (min 8 characters)' )
215+ @pass_context
216+ @require_auth
217+ def update_profile (
218+ ctx : CLIContext ,
219+ user_id : int ,
220+ first_name : str | None ,
221+ last_name : str | None ,
222+ password : str | None ,
223+ client : UnityAuthAPIClient ,
224+ ) -> None :
225+ """Update your own user profile.
226+
227+ Updates your profile information (first name, last name, password).
228+ You can only update your own profile - the user ID must match
229+ the authenticated user.
230+
231+ At least one field must be provided.
232+
233+ \b
234+ Examples:
235+ unityauth user update-profile 5 --first-name John
236+ unityauth user update-profile 5 --last-name Smith
237+ unityauth user update-profile 5 --password NewSecureP@ss123
238+ unityauth user update-profile 5 --first-name John --last-name Smith --password NewP@ss
239+ """
240+ try :
241+ # Validate user ID
242+ if user_id <= 0 :
243+ raise ValidationError ("User ID must be a positive integer" )
244+
245+ # Ensure at least one field is provided
246+ if not any ([first_name , last_name , password ]):
247+ raise ValidationError (
248+ "At least one field must be provided: --first-name, --last-name, or --password"
249+ )
250+
251+ # Validate password length if provided
252+ if password and len (password ) < 8 :
253+ raise ValidationError ("Password must be at least 8 characters" )
254+
255+ # Validate name lengths if provided
256+ if first_name and len (first_name ) > 100 :
257+ raise ValidationError ("First name must be 1-100 characters" )
258+
259+ if last_name and len (last_name ) > 100 :
260+ raise ValidationError ("Last name must be 1-100 characters" )
261+
262+ # Build request payload - only include non-None fields
263+ payload = {}
264+ if first_name :
265+ payload ['firstName' ] = first_name
266+ if last_name :
267+ payload ['lastName' ] = last_name
268+ if password :
269+ payload ['password' ] = password
270+
271+ # Make update request
272+ if ctx .verbose :
273+ fields = ', ' .join (payload .keys ())
274+ info (f"Updating profile for user { user_id } (fields: { fields } )..." )
275+
276+ result = client .patch (f'/api/users/{ user_id } ' , data = payload )
277+
278+ success (f"Profile updated successfully for user { user_id } " )
279+
280+ if ctx .verbose and result :
281+ info (f"Updated user: { result } " )
282+
283+ except AuthorizationError as e :
284+ error (
285+ str (e ),
286+ "You can only update your own profile. The user ID must match your authenticated user.\n "
287+ "Use 'unityauth token-info' to see your user details."
288+ )
289+ sys .exit (3 )
290+ except Exception as e :
291+ handle_error (e )
292+
293+
210294@click .command ()
211295@click .option ('--tenant-id' , type = int , required = True , help = 'Tenant ID to list users from' )
212296@pass_context
0 commit comments