summaryrefslogtreecommitdiffstats
path: root/bitbake/bin/bitbake-hashclient
diff options
context:
space:
mode:
authorJoshua Watt <JPEWhacker@gmail.com>2023-11-03 08:26:31 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-11-09 17:33:03 +0000
commit1af725b2eca63fa113cedb6d77eb5c5f1de6e2f0 (patch)
treeadf200a0b03b8ee1f1a56c55e2ec657dcc7ed04a /bitbake/bin/bitbake-hashclient
parent6e67b000efb89c4e3121fd907a47dc7042c07bed (diff)
downloadpoky-1af725b2eca63fa113cedb6d77eb5c5f1de6e2f0.tar.gz
bitbake: hashserv: Add user permissions
Adds support for the hashserver to have per-user permissions. User management is done via a new "auth" RPC API where a client can authenticate itself with the server using a randomly generated token. The user can then be given permissions to read, report, manage the database, or manage other users. In addition to explicit user logins, the server supports anonymous users which is what all users start as before they make the "auth" RPC call. Anonymous users can be assigned a set of permissions by the server, making it unnecessary for users to authenticate to use the server. The set of Anonymous permissions defines the default behavior of the server, for example if set to "@read", Anonymous users are unable to report equivalent hashes with authenticating. Similarly, setting the Anonymous permissions to "@none" would require authentication for users to perform any action. User creation and management is entirely manual (although bitbake-hashclient is very useful as a front end). There are many different mechanisms that could be implemented to allow user self-registration (e.g. OAuth, LDAP, etc.), and implementing these is outside the scope of the server. Instead, it is recommended to implement a registration service that validates users against the necessary service, then adds them as a user in the hash equivalence server. (Bitbake rev: 69e5417413ee2414fffaa7dd38057573bac56e35) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/bin/bitbake-hashclient')
-rwxr-xr-xbitbake/bin/bitbake-hashclient84
1 files changed, 82 insertions, 2 deletions
diff --git a/bitbake/bin/bitbake-hashclient b/bitbake/bin/bitbake-hashclient
index a02a65b937..328c15cdec 100755
--- a/bitbake/bin/bitbake-hashclient
+++ b/bitbake/bin/bitbake-hashclient
@@ -14,6 +14,7 @@ import sys
14import threading 14import threading
15import time 15import time
16import warnings 16import warnings
17import netrc
17warnings.simplefilter("default") 18warnings.simplefilter("default")
18 19
19try: 20try:
@@ -36,10 +37,18 @@ except ImportError:
36sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib')) 37sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib'))
37 38
38import hashserv 39import hashserv
40import bb.asyncrpc
39 41
40DEFAULT_ADDRESS = 'unix://./hashserve.sock' 42DEFAULT_ADDRESS = 'unix://./hashserve.sock'
41METHOD = 'stress.test.method' 43METHOD = 'stress.test.method'
42 44
45def print_user(u):
46 print(f"Username: {u['username']}")
47 if "permissions" in u:
48 print("Permissions: " + " ".join(u["permissions"]))
49 if "token" in u:
50 print(f"Token: {u['token']}")
51
43 52
44def main(): 53def main():
45 def handle_stats(args, client): 54 def handle_stats(args, client):
@@ -125,9 +134,39 @@ def main():
125 print("Removed %d rows" % (result["count"])) 134 print("Removed %d rows" % (result["count"]))
126 return 0 135 return 0
127 136
137 def handle_refresh_token(args, client):
138 r = client.refresh_token(args.username)
139 print_user(r)
140
141 def handle_set_user_permissions(args, client):
142 r = client.set_user_perms(args.username, args.permissions)
143 print_user(r)
144
145 def handle_get_user(args, client):
146 r = client.get_user(args.username)
147 print_user(r)
148
149 def handle_get_all_users(args, client):
150 users = client.get_all_users()
151 print("{username:20}| {permissions}".format(username="Username", permissions="Permissions"))
152 print(("-" * 20) + "+" + ("-" * 20))
153 for u in users:
154 print("{username:20}| {permissions}".format(username=u["username"], permissions=" ".join(u["permissions"])))
155
156 def handle_new_user(args, client):
157 r = client.new_user(args.username, args.permissions)
158 print_user(r)
159
160 def handle_delete_user(args, client):
161 r = client.delete_user(args.username)
162 print_user(r)
163
128 parser = argparse.ArgumentParser(description='Hash Equivalence Client') 164 parser = argparse.ArgumentParser(description='Hash Equivalence Client')
129 parser.add_argument('--address', default=DEFAULT_ADDRESS, help='Server address (default "%(default)s")') 165 parser.add_argument('--address', default=DEFAULT_ADDRESS, help='Server address (default "%(default)s")')
130 parser.add_argument('--log', default='WARNING', help='Set logging level') 166 parser.add_argument('--log', default='WARNING', help='Set logging level')
167 parser.add_argument('--login', '-l', metavar="USERNAME", help="Authenticate as USERNAME")
168 parser.add_argument('--password', '-p', metavar="TOKEN", help="Authenticate using token TOKEN")
169 parser.add_argument('--no-netrc', '-n', action="store_false", dest="netrc", help="Do not use .netrc")
131 170
132 subparsers = parser.add_subparsers() 171 subparsers = parser.add_subparsers()
133 172
@@ -158,6 +197,31 @@ def main():
158 clean_unused_parser.add_argument("max_age", metavar="SECONDS", type=int, help="Remove unused entries older than SECONDS old") 197 clean_unused_parser.add_argument("max_age", metavar="SECONDS", type=int, help="Remove unused entries older than SECONDS old")
159 clean_unused_parser.set_defaults(func=handle_clean_unused) 198 clean_unused_parser.set_defaults(func=handle_clean_unused)
160 199
200 refresh_token_parser = subparsers.add_parser('refresh-token', help="Refresh auth token")
201 refresh_token_parser.add_argument("--username", "-u", help="Refresh the token for another user (if authorized)")
202 refresh_token_parser.set_defaults(func=handle_refresh_token)
203
204 set_user_perms_parser = subparsers.add_parser('set-user-perms', help="Set new permissions for user")
205 set_user_perms_parser.add_argument("--username", "-u", help="Username", required=True)
206 set_user_perms_parser.add_argument("permissions", metavar="PERM", nargs="*", default=[], help="New permissions")
207 set_user_perms_parser.set_defaults(func=handle_set_user_permissions)
208
209 get_user_parser = subparsers.add_parser('get-user', help="Get user")
210 get_user_parser.add_argument("--username", "-u", help="Username")
211 get_user_parser.set_defaults(func=handle_get_user)
212
213 get_all_users_parser = subparsers.add_parser('get-all-users', help="List all users")
214 get_all_users_parser.set_defaults(func=handle_get_all_users)
215
216 new_user_parser = subparsers.add_parser('new-user', help="Create new user")
217 new_user_parser.add_argument("--username", "-u", help="Username", required=True)
218 new_user_parser.add_argument("permissions", metavar="PERM", nargs="*", default=[], help="New permissions")
219 new_user_parser.set_defaults(func=handle_new_user)
220
221 delete_user_parser = subparsers.add_parser('delete-user', help="Delete user")
222 delete_user_parser.add_argument("--username", "-u", help="Username", required=True)
223 delete_user_parser.set_defaults(func=handle_delete_user)
224
161 args = parser.parse_args() 225 args = parser.parse_args()
162 226
163 logger = logging.getLogger('hashserv') 227 logger = logging.getLogger('hashserv')
@@ -171,10 +235,26 @@ def main():
171 console.setLevel(level) 235 console.setLevel(level)
172 logger.addHandler(console) 236 logger.addHandler(console)
173 237
238 login = args.login
239 password = args.password
240
241 if login is None and args.netrc:
242 try:
243 n = netrc.netrc()
244 auth = n.authenticators(args.address)
245 if auth is not None:
246 login, _, password = auth
247 except FileNotFoundError:
248 pass
249
174 func = getattr(args, 'func', None) 250 func = getattr(args, 'func', None)
175 if func: 251 if func:
176 with hashserv.create_client(args.address) as client: 252 try:
177 return func(args, client) 253 with hashserv.create_client(args.address, login, password) as client:
254 return func(args, client)
255 except bb.asyncrpc.InvokeError as e:
256 print(f"ERROR: {e}")
257 return 1
178 258
179 return 0 259 return 0
180 260