Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions kernelci/api/latest.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ def whoami(self) -> dict:
def password_hash(self, password: str) -> dict:
return self._post('/hash', {'password': password}).json()

def change_password(self, username: str, current: str, new: str) -> dict:
"""Change a password for a given user"""
return self._post(
'/password',
{
'current_password': {'password': current},
'new_password': {'password': new},
},
{
'username': username,
},
Comment on lines +57 to +64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I'm wondering if having /password/<username> would be a better design for the API endpoint. But that's just an implementation detail, wanted to share it here as a thought.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(or /<username>/password)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(or /<username>/password)

+1 on this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the original idea was that the username wasn't required if the query was using an API token for authentication. But since it requires the old password we don't rely on a token so the user endpoint makes more sense.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(or /<username>/password)

+1 on this.

Do you mean a new API path or should it be a part of /user, i.e. /user/<username>/password?

I can adjust it to also accept API token instead of only the old password.

).json()

def create_token(self, username: str, password: str,
scopes: Optional[Sequence[str]] = None) -> str:
data = {
Expand Down
15 changes: 15 additions & 0 deletions kernelci/cli/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ def _api_call(self, api, configs, args):
return True


class cmd_change_password(APICommand): # pylint: disable=invalid-name
"""Change a password for a given user"""
args = APICommand.args + [Args.username]

def _api_call(self, api, configs, args):
current = getpass.getpass("Current password: ")
new = getpass.getpass("New password: ")
retyped = getpass.getpass("Retype new password: ")
if new != retyped:
print("Sorry, passwords do not match.")
return False
api.change_password(args.username, current, new)
return True


class cmd_get_group(APICommand): # pylint: disable=invalid-name
"""Get a user group with a given ID"""
args = APICommand.args + [Args.group_id]
Expand Down