cleaning up komrades.py

posting
quadrismegistus 4 years ago
parent a8f265bd5a
commit cc01f7413f

@ -210,17 +210,20 @@ class CryptList(Crypt): # like inbox
if not val_b: return []
return pickle.loads(val_b)
def prepend(self,x):
def prepend(self,x_l):
return self.append(x,insert=0)
def append(self,x,insert=None):
def append(self,x_l,insert=None):
if type(x_l)!=list: x_l=[x_l]
val_l = self.values
x_l = [x for x in x_l if not x in set(val_l)]
# print('val_l =',val_l)
if insert is not None:
val_l.insert(insert,x)
else:
val_l.append(x)
# print('val_l2 =',val_l)
for x in x_l:
if insert is not None:
val_l.insert(insert,x)
else:
val_l.append(x)
# print('val_l2 =',val_l)
return self.set(val_l)

@ -70,6 +70,24 @@ class KomradeX(Caller):
return answer
## Talking with Operator
def ring_ring(self,msg,route=None,**y):
if type(msg)==dict and not ROUTE_KEYNAME in msg:
msg[ROUTE_KEYNAME]=route
return super().ring_ring(msg,caller=self,**y)
####################################
## (1) Logging in and registering ##
####################################
def register(self, name = None, passphrase = None, is_group=None, show_intro=0,show_body=True,logfunc=None):
# global PHONEBOOK
@ -278,122 +296,92 @@ class KomradeX(Caller):
## MEETING PEOPLE
def find(self,someone):
if type(someone)==str:
return Komrade(name=someone)
if type(someone)==bytes:
return Komrade(pubkey=someone)
self.log('what is type of someoen here?',type(someone))
return someone
# def meet(self,someone):
# # get person obj
# someone = self.find(someone)
# self.log('got someone =',someone,type(someone))
########################
## (2) MEETING PEOPLE ##
########################
def contacts(self):
# who do I know?
return sorted([fn.split('.png')[0] for fn in os.listdir(PATH_QRCODES)])
### MEETING PEOLPE
def meet(self,name=None,pubkey=None,returning=False):
if not name and not pubkey:
return {'success':False,'status':'Meet whom?'}
# already met this person?
keystr=self.name+'->'+name
if self.crypt_keys.get(
keystr,
prefix='/met/'
):
return {
'success':False,
'status':f'You have already sent an introduction to @{name}. It would be rude to send another.'
}
# send msg to op
msg_to_op = {
'name':self.name,
'secret_login':self.secret_login,
'pubkey':self.uri,
def ring_ring(self,msg,route=None,**y):
if type(msg)==dict and not ROUTE_KEYNAME in msg:
msg[ROUTE_KEYNAME]=route
return super().ring_ring(msg,caller=self,**y)
'meet_name':name,
'meet_pubkey':pubkey,
'returning':returning
}
self.log('msg_to_op',msg_to_op)
def fetch_posts(self,n=100,only_from=[],not_from=[]):
# already seen?
seen_post_ids_b = self.crypt_keys.get(
'seen_post_ids',
prefix='/cache/'
res = self.ring_ring(
msg_to_op,
route='introduce_komrades'
)
if seen_post_ids_b:
seen_post_ids=pickle.loads(seen_post_ids_b)
else:
seen_post_ids=[]
self.log('seen_post_ids =',seen_post_ids)
self.log('res from op <-',res)
# ring operator
res_b = self.ring_ring(
{
'seen_post_ids':seen_post_ids,
'only_from':only_from,
'not_from':not_from,
'n':n
},
route='fetch_posts'
# record that I've already tried this
self.crypt_keys.set(
keystr,
b'y',
prefix='/met/'
)
self.log('res_b <-',res_b)
# msg from world?
msg_from_world = Message(
from_whom=self.op,#Komrade(WORLD_NAME),
to_whom=self,
msg=res_b
)
self.log('converted to msg:',msg_from_world.msg_d)
msg_from_world.decrypt()
self.log('decrypted msg:',msg_from_world)
# return result
return res
# get binary blob for all fetched posts
msgs_d = msg_from_world.msg
self.log('msgs_d??',msgs_d)
msgs = msgs_d['msg'].split(BSEP) if msgs_d['msg'] else []
res = {
'status':f'Fetched {len(msgs)} poss.',
'success':True,
'msgs':msgs
}
self.log('->',res)
return res
# def post(self,something,to_name=WORLD_NAME):
# self.log('<-',something,to_name)
# # encryption chain:
# # me -> world
# # me -> op
# # op <- me
# # op -> others
# to_komrade = Komrade(to_name)
# self.log('posting to',to_name,to_komrade,to_komrade.uri)
# # make post data
# # encrypt
# something_encr = SMessage(
# self.privkey.data,
# to_komrade.pubkey.data
# ).wrap(something)
# # make dict (do not use normal msg_d key names!)
# post_d = {
# 'post':{
# 'from':self.uri,
# 'from_name':self.name,
# 'to_name':to_name,
# 'to':to_komrade.uri,
# 'msg':something_encr
# }
# }
# self.log('post_d =',post_d)
# # enclose as message to operator
# self.ring_ring(
# post_d,
# route='post'
# )
def post(self,something):
return self.msg(WORLD_NAME,something)
###################
## (3) MESSAGING ##
###################
@ -439,28 +427,6 @@ class KomradeX(Caller):
)
@property
def inbox_db(self):
if not hasattr(self,'_inbox_db'):
self._inbox_db=self.get_inbox_crypt(
prefix='/inbox/'
)
return self._inbox_db
@property
def inbox_unread_db(self):
if not hasattr(self,'_inbox_unread_db'):
self._inbox_unread_db=self.get_inbox_crypt(
prefix='/inbox/unread/',
)
return self._inbox_unread_db
@property
def inbox_read_db(self):
if not hasattr(self,'_inbox_read_db'):
self._inbox_read_db=self.get_inbox_crypt(
prefix='/inbox/read/',
)
return self._inbox_read_db
def download_inbox(self,uri=None):
@ -485,44 +451,22 @@ class KomradeX(Caller):
route='get_inbox'
)
self.log('got back response:',res)
stop
return self.do_check_msgs(res)
def do_check_msgs(self,res):
# decrypt?
if not res.get('data_encr'):
return {'success':False, 'status':'No data'}
inbox_encr = res['data_encr']
inbox = SMessage(
self.privkey.data,
self.op.pubkey.data
).unwrap(inbox_encr)
self.log('inbox decrypted:',inbox)
# overwrite my local inbox with encrypted one from op?
return self.crypt_keys.set(
self.uri,
inbox,
prefix='/inbox/',
override=True
)
if not res.get('success'): return res
inbox=res.get('inbox',[])
if inbox:
res['res_inbox']=self.inbox_db.prepend(inbox)
return res
def refresh(self,check_msgs=True):
# refresh inbox
if check_msgs:
self.download_inbox()
# status?
inbox_status = self.get_inbox_ids()
if not inbox_status['success']: return inbox_status
unread=inbox_status.get('unread',[])
inbox=inbox_status.get('inbox',[])
# download new messages
self.download_msgs(post_ids = inbox)
inbox_post_ids = self.inbox_db.values
self.download_msgs(
post_ids = inbox_post_ids
)
res = {
'success':True,
@ -764,48 +708,103 @@ class KomradeX(Caller):
### MEETING PEOLPE
def meet(self,name=None,pubkey=None,returning=False):
if not name and not pubkey:
return {'success':False,'status':'Meet whom?'}
keystr=self.name+'->'+name
# if self.crypt_keys.get(
# keystr,
# prefix='/met/'
# ):
# return {
# 'success':False,
# 'status':f'You have already sent an introduction to @{name}. It would be rude to send another.'
# }
msg_to_op = {
'name':self.name,
'secret_login':self.secret_login,
'pubkey':self.uri,
'meet_name':name,
'meet_pubkey':pubkey,
'returning':returning
}
# print('msg_to_op',msg_to_op)
res = self.ring_ring(
msg_to_op,
route='introduce_komrades'
def fetch_posts(self,n=100,only_from=[],not_from=[]):
# already seen?
seen_post_ids_b = self.crypt_keys.get(
'seen_post_ids',
prefix='/cache/'
)
# print('res from op',res)
if seen_post_ids_b:
seen_post_ids=pickle.loads(seen_post_ids_b)
else:
seen_post_ids=[]
self.log('seen_post_ids =',seen_post_ids)
# record that I've already tried this
self.crypt_keys.set(
keystr,
b'y',
prefix='/met/'
# ring operator
res_b = self.ring_ring(
{
'seen_post_ids':seen_post_ids,
'only_from':only_from,
'not_from':not_from,
'n':n
},
route='fetch_posts'
)
self.log('res_b <-',res_b)
# msg from world?
msg_from_world = Message(
from_whom=self.op,#Komrade(WORLD_NAME),
to_whom=self,
msg=res_b
)
self.log('converted to msg:',msg_from_world.msg_d)
msg_from_world.decrypt()
self.log('decrypted msg:',msg_from_world)
# get binary blob for all fetched posts
msgs_d = msg_from_world.msg
self.log('msgs_d??',msgs_d)
msgs = msgs_d['msg'].split(BSEP) if msgs_d['msg'] else []
res = {
'status':f'Fetched {len(msgs)} poss.',
'success':True,
'msgs':msgs
}
self.log('->',res)
return res
def post(self,something):
return self.msg(WORLD_NAME,something)
def test_register():

@ -325,4 +325,28 @@ class Operator(Keymaker):
)
self.log('-->',inbox_crypt)
return inbox_crypt
return inbox_crypt
@property
def inbox_db(self):
if not hasattr(self,'_inbox_db'):
self._inbox_db=self.get_inbox_crypt(
prefix='/inbox/'
)
return self._inbox_db
@property
def inbox_unread_db(self):
if not hasattr(self,'_inbox_unread_db'):
self._inbox_unread_db=self.get_inbox_crypt(
prefix='/inbox/unread/',
)
return self._inbox_unread_db
@property
def inbox_read_db(self):
if not hasattr(self,'_inbox_read_db'):
self._inbox_read_db=self.get_inbox_crypt(
prefix='/inbox/read/',
)
return self._inbox_read_db

@ -328,69 +328,7 @@ class TheOperator(Operator):
# self.log('Operator returning result:',dict_format(res,tab=2))
def fetch_posts(self,msg_to_op):
self.log('<-',msg_to_op)
# get posts by personating world
world = Komrade(WORLD_NAME)
world_inbox_res = world.inbox()
self.log('world_inbox_res',world_inbox_res)
if not world_inbox_res.get('success'):
return world_inbox_res
world_msgs = world_inbox_res.get('msgs')
self.log('world_msgs',world_msgs)
# encrypt to sender from world
world_msgs_b = BSEP.join([msg.msg_b for msg in world_msgs])
world_msg_to_sender = Message(
from_whom=world,
to_whom=msg_to_op.from_whom,
msg=world_msgs_b
)
self.log(world_msg_to_sender,'<- world_msg_to_sender')
# encrypt
world_msg_to_sender.encrypt()
self.log(world_msg_to_sender,'<- world_msg_to_sender encrypted')
return world_msg_to_sender.msg_d
# def post1(self,msg_to_op):
# self.log('post <-',msg_to_op.msg_d)
# self.log('post data <-',msg_to_op.data)
# post_d = msg_to_op.data.get('post')
# self.log('post_d =',post_d)
# # need to decrypt this first -- it's to World,
# # which I on the server have access to private key.
# # I need to decrypt and re-encrypt/reroute
# #msg_to_world = Message(post_d)
# #self.log('msg to world',dict_format(msg_to_world.msg_d))
# # decrypt
# encr_txt = post_d.get('msg')
# txt = SMessage(
# Komrade(post_d.get('to_name')).privkey.data, # requires we have this privkey!!!
# Komrade(post_d.get('from_name')).pubkey.data
# ).unwrap(encr_txt)
# self.log('unencr txt',txt)
# post
# # normally we'd deliver it to the person
# # but here we need to deliver it to...
# # everyone?
# contacts = sorted([fn.split('.png')[0] for fn in os.listdir(PATH_QRCODES)])
# self.log('contacts =',contacts)
# # mass send!
# res = self.mass_deliver_msg(txt,contacts)
# return {
# 'status':'Hold your horses.',
# 'success':False,
# 'res_mass_deliver_msg':res
# }
def mass_deliver_msg(self,post_msg_d,contacts):
def do_mass_deliver_msg(contact,post_msg_d=post_msg_d):
@ -538,20 +476,56 @@ class TheOperator(Operator):
self.log('->',res)
return res
def get_inbox(self,
msg_to_op,
required_fields = [
'secret_login',
'name',
'pubkey',
'inbox',
],do_login=True):
###
# LETS SIMPLIFY THIS
# Komrade -> Op: get_updates()
# gets new DMs, new posts,
# both index/inbox and content/body
###
def require_login(self,msg_to_op,do_login=True):
# logged in?
if do_login:
login_res = self.login(msg_to_op)
if not login_res.get('success'):
return login_res
return {'success':True,'status':'Logged in.'}
else:
return {'success':True,'status':'Login not required.'}
# (0) get updates
# user enters here
def get_updates(self,msg_to_op,do_login=True):
# req login
login_res=self.require_login(msg_to_op,do_login=do_login)
if not login_res.get('success'): return login_res
# (1) get inbox
inbox_res = self.get_inbox()
if not inbox_res.get('success'): return inbox_res
inbox=inbox_res.get('inbox',[])
# (2) get posts
# (1) get inbox
def get_inbox(self,
msg_to_op,
do_login=True,
delete_afterward=False):
# req login
login_res=self.require_login(msg_to_op,do_login=do_login)
if not login_res.get('success'): return login_res
# ok, then find the inbox?
inbox=self.get_inbox_crypt(
@ -561,112 +535,109 @@ class TheOperator(Operator):
res = {
'status':'Succeeded in getting inbox.',
'success':True,
'inbox':inbox.values if inbox else None
'inbox':inbox.values if inbox else []
}
self.log(f'returning from Op.get_inbox --> {res}')
self.log(f'--> {res}')
return res
def download_msgs(self,
msg_to_op,
required_fields = [
'secret_login',
'name',
'pubkey',
'post_ids',
],
delete_afterward=True):
# logged in?
login_res = self.login(msg_to_op)
if not login_res.get('success'):
return login_res
# ok, then find the posts?
post_ids=msg_to_op.data.get('post_ids',[])
if not post_ids: return {'success':False, 'status':'No post_ids specified'}
posts = {}
def get_posts(self,post_ids):
posts={}
for post_id in post_ids:
post = self.crypt_data.get(b64enc(post_id),prefix='/post/')
if post:
posts[post_id] = post
self.log('looking for:',post_id,post)
post = self.crypt_data.get(
post_id,
prefix='/post/'
)
if post: posts[post_id] = post
self.log(f'I {self} found {len(posts)} for {msg_to_op.from_name}')
# delete?
res = {
'status':'Succeeded in downloading new messages.' + (' I\'ve already deleted these messages from the server.' if delete_afterward else ''),
'status':'Succeeded in getting new messages and posts.',
'success':True,
'data_encr':posts
'posts':posts
}
# delete?
if delete_afterward:
res['res_delete_msgs'] = self.delete_msgs(
post_ids,
inbox_uri = b64enc(
msg_to_op.data.get('pubkey')
)
)
# show res
self.log('->',res)
self.log(f'--> {res}')
return res
def delete_msgs(self,post_ids,inbox_uri=None):
# @hack: this a bit dangerous?
def delete_posts(self,post_ids,inbox_uri=None):
# delete from posts
deleted_post_ids=[]
for post_id in post_ids:
self.crypt_data.delete(
if self.crypt_data.delete(
post_id,
prefix='/post/'
)
self.log('deleting post id',post_id,'...')
):
deleted_post_ids.append(post_id)
self.log('deleted_post_ids',deleted_post_ids,'...')
res = {
'deleted':post_ids,
}
# if inbox, remove these posts from it
# delete from inbox
if inbox_uri:
# unwrap
inbox = self.crypt_keys.get(
inbox_uri,
prefix='/inbox/'
inbox_db=self.get_inbox_crypt(
uri=inbox_uri,
pubkey_b=b64dec(inbox_uri)
)
if inbox:
inbox = SMessage(
self.privkey.data,
b64dec(inbox_uri)
).unwrap(inbox)
self.log('unwrapped inbox_encr:',inbox)
inbox_l = inbox.split(BSEP)
self.log('length v1:',len(inbox_l))
# alter
inbox_l = [pid for pid in inbox_l if pid not in post_ids]
self.log('length v2:',len(inbox_l))
# rewrap
inbox = BSEP.join(inbox_l)
if inbox:
#print('inboxxx',inbox)
inbox = SMessage(
self.privkey.data,
b64dec(inbox_uri)
).wrap(inbox)
# overwrite!
self.crypt_keys.set(
inbox_uri,
inbox,
prefix='/inbox/',
override=True
res['deleted_from_inbox']=inbox_db.remove(
deleted_post_ids
)
self.log('-->',res)
return res
## posts
def fetch_posts(self,msg_to_op):
self.log('<-',msg_to_op)
# get posts by personating world
world = Komrade(WORLD_NAME)
world_inbox_res = world.inbox()
self.log('world_inbox_res',world_inbox_res)
if not world_inbox_res.get('success'):
return world_inbox_res
world_msgs = world_inbox_res.get('msgs')
self.log('world_msgs',world_msgs)
# encrypt to sender from world
world_msgs_b = BSEP.join([msg.msg_b for msg in world_msgs])
world_msg_to_sender = Message(
from_whom=world,
to_whom=msg_to_op.from_whom,
msg=world_msgs_b
)
self.log(world_msg_to_sender,'<- world_msg_to_sender')
# encrypt
world_msg_to_sender.encrypt()
self.log(world_msg_to_sender,'<- world_msg_to_sender encrypted')
return world_msg_to_sender.msg_d
return {
'success':True,
'deleted':post_ids,
}
###
# INTRODUCTIONS/MEETING
###
def introduce_komrades(self,msg_to_op):
# # logged in?

Loading…
Cancel
Save