summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/hashserv/__init__.py
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/lib/hashserv/__init__.py
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/lib/hashserv/__init__.py')
-rw-r--r--bitbake/lib/hashserv/__init__.py69
1 files changed, 46 insertions, 23 deletions
diff --git a/bitbake/lib/hashserv/__init__.py b/bitbake/lib/hashserv/__init__.py
index 9a8ee4e88b..552a33278f 100644
--- a/bitbake/lib/hashserv/__init__.py
+++ b/bitbake/lib/hashserv/__init__.py
@@ -8,6 +8,7 @@ from contextlib import closing
8import re 8import re
9import itertools 9import itertools
10import json 10import json
11from collections import namedtuple
11from urllib.parse import urlparse 12from urllib.parse import urlparse
12 13
13UNIX_PREFIX = "unix://" 14UNIX_PREFIX = "unix://"
@@ -18,6 +19,8 @@ ADDR_TYPE_UNIX = 0
18ADDR_TYPE_TCP = 1 19ADDR_TYPE_TCP = 1
19ADDR_TYPE_WS = 2 20ADDR_TYPE_WS = 2
20 21
22User = namedtuple("User", ("username", "permissions"))
23
21 24
22def parse_address(addr): 25def parse_address(addr):
23 if addr.startswith(UNIX_PREFIX): 26 if addr.startswith(UNIX_PREFIX):
@@ -43,7 +46,10 @@ def create_server(
43 upstream=None, 46 upstream=None,
44 read_only=False, 47 read_only=False,
45 db_username=None, 48 db_username=None,
46 db_password=None 49 db_password=None,
50 anon_perms=None,
51 admin_username=None,
52 admin_password=None,
47): 53):
48 def sqlite_engine(): 54 def sqlite_engine():
49 from .sqlite import DatabaseEngine 55 from .sqlite import DatabaseEngine
@@ -62,7 +68,17 @@ def create_server(
62 else: 68 else:
63 db_engine = sqlite_engine() 69 db_engine = sqlite_engine()
64 70
65 s = server.Server(db_engine, upstream=upstream, read_only=read_only) 71 if anon_perms is None:
72 anon_perms = server.DEFAULT_ANON_PERMS
73
74 s = server.Server(
75 db_engine,
76 upstream=upstream,
77 read_only=read_only,
78 anon_perms=anon_perms,
79 admin_username=admin_username,
80 admin_password=admin_password,
81 )
66 82
67 (typ, a) = parse_address(addr) 83 (typ, a) = parse_address(addr)
68 if typ == ADDR_TYPE_UNIX: 84 if typ == ADDR_TYPE_UNIX:
@@ -76,33 +92,40 @@ def create_server(
76 return s 92 return s
77 93
78 94
79def create_client(addr): 95def create_client(addr, username=None, password=None):
80 from . import client 96 from . import client
81 97
82 c = client.Client() 98 c = client.Client(username, password)
83
84 (typ, a) = parse_address(addr)
85 if typ == ADDR_TYPE_UNIX:
86 c.connect_unix(*a)
87 elif typ == ADDR_TYPE_WS:
88 c.connect_websocket(*a)
89 else:
90 c.connect_tcp(*a)
91 99
92 return c 100 try:
101 (typ, a) = parse_address(addr)
102 if typ == ADDR_TYPE_UNIX:
103 c.connect_unix(*a)
104 elif typ == ADDR_TYPE_WS:
105 c.connect_websocket(*a)
106 else:
107 c.connect_tcp(*a)
108 return c
109 except Exception as e:
110 c.close()
111 raise e
93 112
94 113
95async def create_async_client(addr): 114async def create_async_client(addr, username=None, password=None):
96 from . import client 115 from . import client
97 116
98 c = client.AsyncClient() 117 c = client.AsyncClient(username, password)
99 118
100 (typ, a) = parse_address(addr) 119 try:
101 if typ == ADDR_TYPE_UNIX: 120 (typ, a) = parse_address(addr)
102 await c.connect_unix(*a) 121 if typ == ADDR_TYPE_UNIX:
103 elif typ == ADDR_TYPE_WS: 122 await c.connect_unix(*a)
104 await c.connect_websocket(*a) 123 elif typ == ADDR_TYPE_WS:
105 else: 124 await c.connect_websocket(*a)
106 await c.connect_tcp(*a) 125 else:
126 await c.connect_tcp(*a)
107 127
108 return c 128 return c
129 except Exception as e:
130 await c.close()
131 raise e