Skip to content

Commit b8fad80

Browse files
committed
Added command for updating own profile
Signed-off-by: Kevin Stanley <stanleyk@objectcomputing.com>
1 parent daa6ceb commit b8fad80

3 files changed

Lines changed: 147 additions & 1 deletion

File tree

unityauth-cli/docs/user-guide.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Complete command reference for the UnityAuth command-line interface.
1717
- [user create](#user-create)
1818
- [user list](#user-list)
1919
- [user update](#user-update)
20+
- [user update-profile](#user-update-profile)
2021
- [Tenant Commands](#tenant-commands)
2122
- [tenant list](#tenant-list)
2223
- [tenant users](#tenant-users)
@@ -364,6 +365,66 @@ unityauth user update 10 --tenant-id 1 --role-ids 2
364365

365366
---
366367

368+
### user update-profile
369+
370+
Update your own user profile (first name, last name, or password).
371+
372+
```
373+
unityauth user update-profile USER_ID [OPTIONS]
374+
```
375+
376+
**Arguments:**
377+
378+
| Argument | Description |
379+
|----------|-------------|
380+
| `USER_ID` | Your user ID (from `token-info`) |
381+
382+
**Options:**
383+
384+
| Option | Description |
385+
|--------|-------------|
386+
| `--first-name TEXT` | New first name (1-100 characters) |
387+
| `--last-name TEXT` | New last name (1-100 characters) |
388+
| `--password TEXT` | New password (minimum 8 characters) |
389+
390+
**Behavior:**
391+
392+
- This is a **self-service** command: you can only update your own profile
393+
- The `USER_ID` must match your authenticated user ID
394+
- At least one option must be provided
395+
- Only the specified fields are updated; others remain unchanged
396+
397+
**Examples:**
398+
399+
```bash
400+
# First, check your user ID
401+
unityauth token-info
402+
403+
# Update your first name
404+
unityauth user update-profile 5 --first-name John
405+
406+
# Update your last name
407+
unityauth user update-profile 5 --last-name Smith
408+
409+
# Change your password
410+
unityauth user update-profile 5 --password "NewSecureP@ss123"
411+
412+
# Update multiple fields at once
413+
unityauth user update-profile 5 --first-name John --last-name Smith --password "NewP@ss"
414+
```
415+
416+
**Common Errors:**
417+
418+
| Error | Cause | Solution |
419+
|-------|-------|----------|
420+
| "Permission denied" | User ID doesn't match authenticated user | Use `token-info` to find your user ID |
421+
| "At least one field must be provided" | No options specified | Provide `--first-name`, `--last-name`, or `--password` |
422+
| "Password must be at least 8 characters" | Password too short | Use a longer password |
423+
424+
**Note:** To update another user's profile or roles, use `user update` (requires admin permissions).
425+
426+
---
427+
367428
## Tenant Commands
368429

369430
### tenant list

unityauth-cli/src/unityauth_cli/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def register_commands() -> None:
235235
"""Register all CLI commands with the main group."""
236236
from unityauth_cli.commands.login import login, logout, token_info
237237
from unityauth_cli.commands.config import config
238-
from unityauth_cli.commands.users import create, update, list_users
238+
from unityauth_cli.commands.users import create, update, update_profile, list_users
239239
from unityauth_cli.commands.tenants import list_tenants, tenant_users
240240
from unityauth_cli.commands.roles import list_roles
241241

@@ -255,6 +255,7 @@ def user():
255255

256256
user.add_command(create)
257257
user.add_command(update)
258+
user.add_command(update_profile)
258259
user.add_command(list_users, name='list')
259260

260261
# Register tenant discovery commands

unityauth-cli/src/unityauth_cli/commands/users.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)