sb-auth 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sb_auth/__init__.py ADDED
File without changes
sb_auth/exec.py ADDED
@@ -0,0 +1,29 @@
1
+ from .sb_local import *
2
+ from .sb_client import *
3
+ from .sb_serve import *
4
+
5
+ while True:
6
+ s = input("(s) server (c) client (l) local[offline]: ")
7
+ s = s.strip().lower()
8
+
9
+ if s in {"s","c","l"}:
10
+ break
11
+
12
+ if s == "s":
13
+ sbs = SBAuthServer()
14
+ asyncio.run(sbs.service())
15
+
16
+ elif s == "c":
17
+ sbc = SBAuthClient()
18
+ asyncio.run(sbc.contact())
19
+ else:
20
+ while True:
21
+ s = input("(s) server OR (c) client side: ")
22
+ s = s.strip().lower()
23
+
24
+ if s in {"s","c"}:
25
+ break
26
+
27
+ stat = s == "s"
28
+ sls = SBLocalService(stat)
29
+ sls.run()
@@ -0,0 +1,33 @@
1
+ """
2
+ read/write operations for Seqbuild's Comm Lang language.
3
+ """
4
+ import websockets
5
+ import asyncio
6
+ from .sb_op import *
7
+ import json
8
+ from morebs2.matrix_methods import vector_to_string,cr
9
+ from morebs2.globalls import is_alphanumeric
10
+
11
+ DEFAULT_PORT = 8765
12
+
13
+ """
14
+ outputs the program's conventional filename
15
+ for `info` (client name or server address).
16
+ """
17
+ def filename_for_CL(info,is_server_side:bool):
18
+ assert type(is_server_side) == bool
19
+
20
+ if is_server_side:
21
+ return "client__" + info + ".txt"
22
+
23
+ q = info.split(".")
24
+ assert len(q) == 4
25
+
26
+ q1 = q[-1].split(":")
27
+ assert len(q1) == 2
28
+
29
+ q[-1] = q1[0]
30
+ q1 = q1[1]
31
+
32
+ s = "_".join(q)
33
+ return "server__" + s + "-" + q1 + ".txt"
sb_auth/sb_client.py ADDED
@@ -0,0 +1,271 @@
1
+ from .rw_comm_lang import *
2
+
3
+ class SBAuthClient:
4
+
5
+ def __init__(self):
6
+ self.addr = None
7
+ self.user_idn = None
8
+ self.utable = UserTable(False)
9
+ self.is_new_user = False
10
+
11
+ self.finstat = False
12
+ self.active_clp = None
13
+ return
14
+
15
+ async def contact(self):
16
+ s = await asyncio.get_running_loop().run_in_executor(None, \
17
+ input, "enter in IP address: ")
18
+ s1 = await asyncio.get_running_loop().run_in_executor(None, \
19
+ input, "enter in port number: ")
20
+
21
+ self.addr = s + ":" + s1
22
+ server = "ws://" + self.addr
23
+ await self.act(server)
24
+
25
+ async def act(self,server):
26
+ async with websockets.connect(server) as wsock:
27
+ print("Connected to server!")
28
+ while True:
29
+ await self.recv(wsock)
30
+ if self.finstat:
31
+ break
32
+
33
+ async def recv(self,wsock):
34
+ async for message in wsock:
35
+ print(message)
36
+
37
+ try:
38
+ message2 = json.loads(message)
39
+ message = message2
40
+ except: pass
41
+
42
+ # case: data input, CL key or data
43
+ if type(message) == list:
44
+ #q = message.split("\n")
45
+ # case: receive COMM LANG key
46
+ if message[0].strip() == "COMM LANG":
47
+ gen_name = message[1]
48
+ cl_string = message[2]
49
+ stat = self.write_key_to_file(cl_string,gen_name,False)
50
+ if not stat:
51
+ self.finstat = True
52
+ return
53
+ continue
54
+
55
+ # case: initial login
56
+ elif message.strip() == "username. leave blank if you are new:":
57
+ response = await self.login(wsock)
58
+ continue
59
+
60
+ elif message.strip() == "read (r) or write (w) or quit (q)?":
61
+ stat = await self.rw_ops(wsock)
62
+ if stat == -1:
63
+ self.finstat = True
64
+ return
65
+ continue
66
+
67
+ async def login(self,wsock):
68
+ s = await asyncio.get_running_loop().run_in_executor(None, input, "[x] ")
69
+
70
+ await wsock.send(s)
71
+ self.user_idn = s
72
+ response = await wsock.recv()
73
+ print(response)
74
+ response = response.strip()
75
+ q = response.split(" ")
76
+
77
+ # case: new user
78
+ if response == "new username:":
79
+ s2 = await asyncio.get_running_loop().run_in_executor(None, input, "[x] ")
80
+ await wsock.send(s2)
81
+ self.user_idn = s2
82
+ response = wsock.recv()
83
+ self.is_new_user = True
84
+ # case: username does not exist.
85
+ elif q[-2] == ["try","again!"]:
86
+ print("Username does not exist. Please try again.")
87
+ s2 = await asyncio.get_running_loop().run_in_executor(None, input, "[x] ")
88
+ response = await wsock.send(s2)
89
+ # case: provide the key
90
+ elif q[:4] == ["enter","in","your","key"]:
91
+ num_iter = int(q[5])
92
+ await self.send_passwd(wsock,num_iter,is_login=True)
93
+
94
+ return response
95
+
96
+ def write_key_to_file(self,cl_string,gen_name,is_update:bool):
97
+ user_str = filename_for_CL(self.addr,False)
98
+ fp = os.path.join(DEFAULT_SB_USER_DIR, user_str)
99
+
100
+ fobj = open(fp, "w")
101
+ fobj.write(cl_string)
102
+ fobj.close()
103
+
104
+ try:
105
+ if not is_update:
106
+ self.utable.add_user(self.addr,user_str,gen_name)
107
+ else:
108
+ self.utable.delta_user(self.addr,user_str,gen_name)
109
+ except:
110
+ print("key already present for server/port OR could not be updated")
111
+ return False
112
+ return True
113
+
114
+ async def send_passwd(self,wsock,num_iter,is_login:bool):
115
+
116
+ user_str = filename_for_CL(self.addr,False)
117
+
118
+ if type(self.active_clp) == type(None):
119
+ fp = filename_for_CL(self.addr,False)
120
+ full_fp = os.path.join(DEFAULT_SB_USER_DIR,fp)
121
+ self.active_clp = CommLangParser(full_fp)
122
+ self.active_clp.process_file()
123
+
124
+ gen_name = self.utable.user_to_X(self.addr,"g-name")
125
+
126
+ prev_elements = 0
127
+ if is_login:
128
+ prev_elements = self.utable.user_to_X(self.addr,"# iterations")
129
+
130
+ total_elements = prev_elements + num_iter
131
+ q = process_CommLang_generator(self.active_clp,gen_name,\
132
+ total_elements+1,num_iter)
133
+
134
+ self.utable.update_user(self.addr,num_iter)
135
+ s = vector_to_string(q,cr)
136
+ print("\t\t sending key")
137
+ print(s)
138
+ await wsock.send(s)
139
+
140
+ #------------------------------- post login
141
+
142
+ async def rw_ops(self,wsock):
143
+ # read/write
144
+ rw_stat = None
145
+ fpath = None
146
+ while True:
147
+ q = await asyncio.get_running_loop().run_in_executor(None, input, "[x] ")
148
+ await wsock.send(q)
149
+ s = await wsock.recv()
150
+ print(s)
151
+ if s.strip() == "enter in filepath:":
152
+ rw_stat = q
153
+ break
154
+
155
+ if q == "q":
156
+ rw_stat = "q"
157
+ break
158
+
159
+ if rw_stat == "q":
160
+ return -1
161
+
162
+ F = self.r_ops if rw_stat == "r" else self.w_ops
163
+ stat = await F(wsock)
164
+ return stat
165
+
166
+ async def r_ops(self,wsock):
167
+ fpath = await asyncio.get_running_loop().run_in_executor(None, input, "[x] ")
168
+ await wsock.send(fpath)
169
+
170
+ #while True:
171
+ sec_check_prompt = await wsock.recv()
172
+ sec_check_prompt = sec_check_prompt.strip().split(" ")
173
+ assert sec_check_prompt[:4] == ["enter","in","your","key"]
174
+ #break
175
+
176
+ num_iter = int(sec_check_prompt[5])
177
+ await self.send_passwd(wsock,num_iter,is_login=False)
178
+
179
+ sec_check_two = await wsock.recv()
180
+ try:
181
+ sec_check_two_ = json.loads(sec_check_two)
182
+ sec_check_two = sec_check_two_
183
+ except:
184
+ return False
185
+
186
+ # case: correct key
187
+ if type(sec_check_two) == list:
188
+ ##fpath2 = await asyncio.get_running_loop().run_in_executor(None, input, "[x] write out path? ")
189
+ stat = await self.record_read_file(sec_check_two[1])
190
+ if not stat:
191
+ print("could not write out contents to file.")
192
+ return False
193
+ else:
194
+ print("Security check failed.")
195
+ return False
196
+
197
+ x = await wsock.recv()
198
+ self.update_key_proc(x)
199
+ return True
200
+
201
+ async def record_read_file(self,contents):
202
+
203
+ fpath2 = await asyncio.get_running_loop().run_in_executor(None, input, "[x] write out path? ")
204
+
205
+ try:
206
+ with open(fpath2,"w") as f:
207
+ f.write(contents)
208
+ except:
209
+ return False
210
+ return True
211
+
212
+ async def w_ops(self,wsock):
213
+ q = await wsock.recv()
214
+ print(q)
215
+
216
+ while True:
217
+ fpath = await asyncio.get_running_loop().run_in_executor(None, input, "[x]: ")
218
+
219
+ contents = None
220
+ try:
221
+ with open(fpath,"r") as f:
222
+ contents_ = f.read()
223
+ contents = contents_
224
+ except:
225
+ pass
226
+
227
+ if type(contents) == type(None):
228
+ print("invalid path.")
229
+ continue
230
+ break
231
+
232
+ sec_check_prompt = await wsock.recv()
233
+ sec_check_prompt = sec_check_prompt.strip().split(" ")
234
+ assert sec_check_prompt[:4] == ["enter","in","your","key"]
235
+
236
+ num_iter = int(sec_check_prompt[5])
237
+ await self.send_passwd(wsock,num_iter,is_login=False)
238
+
239
+ sec_check_two = await wsock.recv()
240
+ print(sec_check_two)
241
+
242
+ if sec_check_two[:8] != "proceed.":
243
+ print("Security check failed.")
244
+ return False
245
+
246
+ fpath2 = await asyncio.get_running_loop().run_in_executor(None, input, "[x] server side path: ")
247
+ C = json.dumps([fpath2,contents])
248
+ await wsock.send(C)
249
+ s = await wsock.recv()
250
+ print(s)
251
+
252
+ if s == "Wrote content.":
253
+ x = await wsock.recv()
254
+ self.update_key_proc(x)
255
+ return True
256
+
257
+ def update_key_proc(self,x):
258
+
259
+ # check for update to key here
260
+ try:
261
+ x_ = json.loads(x)
262
+
263
+ #
264
+ if type(x_) == list:
265
+ print("updating key")
266
+ #q = ["COMM LANG",gen_name,content]
267
+ gen_name = x_[1]
268
+ cl_string = x_[2]
269
+ self.write_key_to_file(cl_string,gen_name,is_update=True)
270
+ except:
271
+ print(x)
sb_auth/sb_local.py ADDED
@@ -0,0 +1,160 @@
1
+ from .rw_comm_lang import *
2
+
3
+
4
+ CLIENT_LIST_TITLE = "\t\t USER LIST"
5
+ CLIENT_LIST_INPUT = "press (enter) for the next group of users OR\nenter in the name of a user: "
6
+
7
+ CLIENT_PERMISSIONS_INPUT0 = "(ro) read folder (ri) read file (wo) write folder (wi) write file (b) go back: "
8
+ CLIENT_PERMISSIONS_INPUT1 = "(a) add | (d) delete | (b) go back | press (enter) for the next group: "
9
+
10
+ CLIENT_PERMISSIONS_TITLE = "\t\t USER EXCLUSION: "
11
+ CLIENT_PERMISSIONS_ADD_INPUT = "add exclusion: "
12
+ CLIENT_PERMISSIONS_DELETE_INPUT = "delete exclusion: "
13
+
14
+ def display_loop(L,ref_index,title,input_str):
15
+
16
+ print(title)
17
+ end = min(len(L),ref_index + 50)
18
+ for i in range(ref_index,end):
19
+ print(L[i] + "\n")
20
+ print("\n\n")
21
+ x = input(input_str)
22
+ return x
23
+
24
+ """
25
+ server side
26
+ """
27
+ class SBLocalService:
28
+
29
+ def __init__(self,is_server_side:bool):
30
+ self.is_server_side = is_server_side
31
+ self.utable = UserTable(self.is_server_side)
32
+ self.user_list = sorted(self.utable.t0.keys())
33
+
34
+ # for server side
35
+ self.uperms = dict()
36
+
37
+ self.preprocess()
38
+ return
39
+
40
+ def load_user_permissions(self):
41
+
42
+ for u in self.user_list:
43
+ fp_user = user_idn_to_default_permissions_file_path(u)
44
+ uperm = UserPermissions(fp_user)
45
+ self.uperms[u] = uperm
46
+
47
+ def preprocess(self):
48
+
49
+ if self.is_server_side:
50
+ self.load_user_permissions()
51
+ return
52
+
53
+ def run(self):
54
+ mode = "user"
55
+ user_idn = None
56
+ perm_op = None
57
+
58
+ while True:
59
+ #if type(extra) == type(None):
60
+ if mode == "user":
61
+ user_idn,i = self.display_list(mode)
62
+ mode = "perm view"
63
+ elif mode == "perm view":
64
+ perm_op = self.user_selection(user_idn)
65
+ if perm_op == "b":
66
+ mode = "user"
67
+ continue
68
+ mode = "perm op"
69
+ else:
70
+ op,i = self.display_list(mode,user_idn,perm_op)
71
+
72
+ if op == "b":
73
+ mode = "user"
74
+ continue
75
+
76
+ uperm = self.uperms[user_idn]
77
+ if op == "a":
78
+ to_add = True
79
+ S = CLIENT_PERMISSIONS_ADD_INPUT
80
+ elif op == "d":
81
+ to_add = False
82
+ S = CLIENT_PERMISSIONS_DELETE_INPUT
83
+ else:
84
+ continue
85
+
86
+ P = input(S)
87
+ uperm.update(perm_op[0],P,to_add=to_add)
88
+ mode = "user"
89
+
90
+ return
91
+
92
+ def display_list(self,list_type,*args):
93
+ assert list_type in {"user","perm op"}
94
+
95
+ F = self.display_user_list_ if list_type == \
96
+ "user" else self.display_usr_perm_list
97
+ i = 0
98
+ name = None
99
+
100
+ while True:
101
+ stat = F(i,*args)
102
+ stat = stat.strip()
103
+ if stat == "":
104
+ i = i + 50
105
+ if i >= len(self.user_list):
106
+ i = 0
107
+ else:
108
+ name = stat
109
+ break
110
+ return name,i
111
+
112
+ def user_selection(self,user_idn):
113
+ if user_idn not in self.user_list:
114
+ print("* user does not exist!")
115
+ return None
116
+
117
+ while True:
118
+ s = input(CLIENT_PERMISSIONS_INPUT0)
119
+ s = s.strip().lower()
120
+
121
+ if s in {"ro","ri","wo","wi","b"}:
122
+ break
123
+ return s
124
+
125
+ def user_op(self,user_idn,action):
126
+ assert action in {"ro","ri","wo","wi"}
127
+ return self.display_list("perm view",user_idn,action)
128
+
129
+ def display_usr_perm_list(self,ref_index,user_idn,action):
130
+ if user_idn not in self.uperms:
131
+ return "b"
132
+ uperm = self.uperms[user_idn]
133
+
134
+ if action == "ro":
135
+ Q = uperm.read_folder_ex
136
+
137
+ elif action == "ri":
138
+ Q = uperm.read_file_ex
139
+
140
+ elif action == "wo":
141
+ Q = uperm.write_folder_ex
142
+
143
+ elif action == "wi":
144
+ Q = uperm.write_file_ex
145
+
146
+ else:
147
+ return ""
148
+
149
+ return display_loop(Q,ref_index,title="\t\t* exclusion list",\
150
+ input_str=CLIENT_PERMISSIONS_INPUT1)
151
+
152
+ def display_user_list_(self,ref_index):
153
+ return display_loop(self.user_list,ref_index,title=CLIENT_LIST_TITLE,\
154
+ input_str=CLIENT_LIST_INPUT)
155
+
156
+ def delete_client(self):
157
+ return -1
158
+
159
+ def delete_server(self):
160
+ return -1
sb_auth/sb_op.py ADDED
@@ -0,0 +1,87 @@
1
+ from .usr_table import *
2
+ from seqbuild.face.easy_gen_struct import *
3
+ from morebs2.matrix_methods import is_number
4
+
5
+ # DEFAULT VARIABLES
6
+ PROHIBITED_COMMLANG_COMMANDS = {"load","show","chaintest","qualtest","open"}
7
+ PROHIBITED_SB_AUTH_NAMES = {"server_dir","client_dir","default",""}
8
+ DEFAULT_SB_AUTH_KEYSIZE_RANGE = [24,58]
9
+ DEFAULT_SB_AUTH_INDEX_RANGE = [627,1450] # [0,5] #
10
+ DEFAULT_SB_SKIPSIZE_RANGE = [0,3]
11
+
12
+ """
13
+ checks if file abides by constrained Comm Lang rules.
14
+ """
15
+ def verify_CommLang_file(f,gen_name):
16
+ if not os.path.isfile(f): return False
17
+
18
+ clp = CommLangParser(f)
19
+
20
+ while not clp.finstat:
21
+ clp.load_next_command()
22
+
23
+ if len(clp.cmdlines) > 0:
24
+ q = clp.cmdlines[0]
25
+ c = q.split(" ")
26
+ if c[0] in PROHIBITED_COMMLANG_COMMANDS:
27
+ return False
28
+ if c[0] == "set":
29
+ if "open" in c: return False
30
+
31
+ clp.process_command()
32
+ clp.check_finstat()
33
+
34
+ if type(gen_name) == type(None):
35
+ gen_name = clp.single_output_generator_list()[-1]
36
+
37
+ clp.close()
38
+
39
+ try:
40
+ stat = process_CommLang_generator(f,gen_name,0)
41
+ return stat
42
+ except:
43
+ return False
44
+
45
+ # TODO:
46
+ '''
47
+ if num_iter = 0: checks generator first 50 outputs are real numbers.
48
+ otherwise: outputs `num_iter` values
49
+ '''
50
+ def process_CommLang_generator(f,generator_name,num_iter=0,output_last=0):
51
+ if type(f) == str:
52
+ assert os.path.isfile(f)
53
+ clp = CommLangParser(f)
54
+ clp.process_file()
55
+ else:
56
+ assert type(f) == CommLangParser
57
+ clp = f
58
+
59
+ assert num_iter >= 0
60
+
61
+ excluded_types = {complex,np.complex64,np.complex128}
62
+ def vfunc():
63
+ for _ in range(50):
64
+ try:
65
+ x = G()
66
+ stat = is_number(x,excluded_types)
67
+ if not stat: return False
68
+ except:
69
+ return False
70
+ return True
71
+
72
+ def nfunc():
73
+ X = []
74
+ for _ in range(num_iter):
75
+ r = G()
76
+ X.append(float(round(r,5)))
77
+ return X[-output_last:]
78
+
79
+ F = vfunc if num_iter == 0 else nfunc
80
+
81
+ assert generator_name in clp.vartable, "got {}, available {}".format(generator_name,\
82
+ set(clp.vartable.keys()))
83
+
84
+ G = clp.vartable[generator_name]
85
+ G = MAIN_method_for_object(G)
86
+ assert type(G) in {FunctionType,MethodType}
87
+ return F()