Skip to content

Commit 32e062f

Browse files
committed
kernelci.cli: implement main parts of user subcommand
Implement the main parts of the `kci user` subcommand with whoami, find, token, password update / add. Some missing features on the API side mean we can't yet implement update, activate, deactivate and password reset. Also the token expiry date can't yet be specified. These things will need to be implemented as follow-ups when the features become available. Signed-off-by: Guillaume Tucker <[email protected]>
1 parent 1c20ae7 commit 32e062f

File tree

1 file changed

+78
-2
lines changed

1 file changed

+78
-2
lines changed

kernelci/cli/user.py

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@
33
# Copyright (C) 2023 Collabora Limited
44
# Author: Guillaume Tucker <[email protected]>
55
# Author: Jeny Sadadia <[email protected]>
6+
# Author: Paweł Wieczorek <[email protected]>
67

78
"""Tool to manage KernelCI API users"""
89

10+
import getpass
911
import json
1012

1113
import click
1214

1315
import kernelci.api
1416
import kernelci.config
15-
from . import Args, kci
17+
from . import Args, kci, split_attributes
1618

1719

1820
@kci.group(name='user')
@@ -25,9 +27,83 @@ def kci_user():
2527
@Args.api
2628
@Args.indent
2729
def whoami(config, api, indent, secrets):
28-
"""Use whoami to get current user info with API authentication"""
30+
"""Get the current user's details with API authentication"""
2931
configs = kernelci.config.load(config)
3032
api_config = configs['api'][api]
3133
api = kernelci.api.get_api(api_config, secrets.api.token)
3234
data = api.whoami()
3335
click.echo(json.dumps(data, indent=indent))
36+
37+
38+
@kci_user.command
39+
@click.argument('attributes', nargs=-1)
40+
@Args.config
41+
@Args.api
42+
@Args.indent
43+
def find(attributes, config, api, indent):
44+
"""Find user profiles with arbitrary attributes"""
45+
configs = kernelci.config.load(config)
46+
api_config = configs['api'][api]
47+
api = kernelci.api.get_api(api_config)
48+
users = api.get_user_profiles(split_attributes(attributes))
49+
data = json.dumps(users, indent=indent)
50+
echo = click.echo_via_pager if len(users) > 1 else click.echo
51+
echo(data)
52+
53+
54+
@kci_user.command
55+
@click.argument('username')
56+
@Args.config
57+
@Args.api
58+
@Args.indent
59+
@click.option('--scope', multiple=True, help="Security scope(s)")
60+
def token(username, config, api, indent, scope):
61+
"""Create a new API token using a user name and password"""
62+
password = getpass.getpass()
63+
configs = kernelci.config.load(config)
64+
api_config = configs['api'][api]
65+
api = kernelci.api.get_api(api_config)
66+
user_token = api.create_token(username, password, scope)
67+
click.echo(json.dumps(user_token, indent=indent))
68+
69+
70+
@kci_user.group(name='password')
71+
def user_password():
72+
"""Manage user passwords"""
73+
74+
75+
@user_password.command
76+
@click.argument('username')
77+
@Args.config
78+
@Args.api
79+
def update(username, config, api):
80+
"""Update the password for a given user"""
81+
current = getpass.getpass("Current password: ")
82+
new = getpass.getpass("New password: ")
83+
retyped = getpass.getpass("Retype new password: ")
84+
if new != retyped:
85+
raise click.ClickException("Sorry, passwords do not match")
86+
configs = kernelci.config.load(config)
87+
api_config = configs['api'][api]
88+
api = kernelci.api.get_api(api_config)
89+
api.change_password(username, current, new)
90+
91+
92+
@kci_user.command(secrets=True)
93+
@click.argument('username')
94+
@click.argument('email')
95+
@Args.config
96+
@Args.api
97+
def add(username, email, config, api, secrets):
98+
"""Add a new user account"""
99+
profile = {
100+
'email': email,
101+
}
102+
password = getpass.getpass()
103+
retyped = getpass.getpass("Confirm password: ")
104+
if password != retyped:
105+
raise click.ClickException("Sorry, passwords do not match")
106+
configs = kernelci.config.load(config)
107+
api_config = configs['api'][api]
108+
api = kernelci.api.get_api(api_config, secrets.api.token)
109+
api.create_user(username, password, profile)

0 commit comments

Comments
 (0)