fixing up gui finally

back-to-app
quadrismegistus 4 years ago
parent 26ea9ac383
commit 4adc044ffa

@ -1 +0,0 @@
{"user": {"username": "marx"}}

Before

Width:  |  Height:  |  Size: 333 KiB

After

Width:  |  Height:  |  Size: 333 KiB

Before

Width:  |  Height:  |  Size: 276 KiB

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Before

Width:  |  Height:  |  Size: 568 KiB

After

Width:  |  Height:  |  Size: 568 KiB

@ -31,7 +31,7 @@ if platform.platform().startswith('Linux'):
HEIGHT *= 1.25 HEIGHT *= 1.25
WINDOW_SIZE=int(HEIGHT * ASPECT_RATIO),int(HEIGHT) WINDOW_SIZE=int(HEIGHT),int(HEIGHT * ASPECT_RATIO)
BG_IMG='assets/bg-brown.png' BG_IMG='assets/bg-brown.png'

@ -5,7 +5,8 @@ from config import *
import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..'))) import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
from komrade import * from komrade import *
from komrade.api import Api from komrade.api import Api
import logging
logger=logging.getLogger(__name__)
# monkeypatching the things that asyncio needs # monkeypatching the things that asyncio needs
import subprocess import subprocess
@ -94,6 +95,15 @@ class MyLayout(MDBoxLayout):
self.post_id=post_id self.post_id=post_id
self.change_screen('view') self.change_screen('view')
class ProgressPopup(MDDialog): pass class ProgressPopup(MDDialog): pass
class MessagePopup(MDDialog): pass class MessagePopup(MDDialog): pass
class MyBoxLayout(MDBoxLayout): pass class MyBoxLayout(MDBoxLayout): pass
@ -134,28 +144,6 @@ class MyToolbar(MDToolbar):
def get_tor_proxy_session():
session = requests.session()
# Tor uses the 9050 port as the default socks port
session.proxies = {'http': 'socks5://127.0.0.1:9150',
'https': 'socks5://127.0.0.1:9150'}
return session
def get_async_tor_proxy_session():
from requests_futures.sessions import FuturesSession
session = FuturesSession()
# Tor uses the 9050 port as the default socks port
session.proxies = {'http': 'socks5://127.0.0.1:9150',
'https': 'socks5://127.0.0.1:9150'}
return session
def get_tor_python_session():
from torpy.http.requests import TorRequests
with TorRequests() as tor_requests:
with tor_requests.get_session() as s:
return s
def draw_background(widget, img_fn='assets/bg.png'): def draw_background(widget, img_fn='assets/bg.png'):
from kivy.core.image import Image as CoreImage from kivy.core.image import Image as CoreImage
from kivy.graphics import Color, Rectangle from kivy.graphics import Color, Rectangle
@ -195,74 +183,39 @@ def route(uri):
# DEFAULT_SCREEN = route(DEFAULT_URI) # DEFAULT_SCREEN = route(DEFAULT_URI)
class MainApp(MDApp): class MainApp(MDApp, Logger):
title = 'Komrade' title = 'Komrade'
logged_in=False logged_in=False
# store = JsonStore('../p2p/.keys.json')
# store_global = JsonStore('../p2p/.keys.global.json')
store = JsonStore('app.json')
login_expiry = 60 * 60 * 24 * 7 # once a week login_expiry = 60 * 60 * 24 * 7 # once a week
texture = ObjectProperty() texture = ObjectProperty()
uri = '/inbox/world' uri='/do/login'
# def connect(self):
# # connect to kad?
# self.node = p2p.connect()
def rgb(self,*_): return rgb(*_) def rgb(self,*_): return rgb(*_)
def change_screen(self, screen, *args): def change_screen(self, screen, *args):
self.screen=screen self.screen=screen
self.root.change_screen(screen,*args) self.root.change_screen(screen,*args)
@property def get_username(self): return self._name
def channel(self):
if not hasattr(self,'uri'): return None
if self.uri.count('/')<2: return None
return self.uri.split('/')[2]
def change_screen_from_uri(self,uri,*args):
self.uri=uri
self.log('CHANGING SCREEN',uri,'??')
return self.root.change_screen_from_uri(uri,*args)
@property @property
def logger(self): def crypt(self):
if not hasattr(self,'_logger'): if not hasattr(self,'_crypt'):
import logging from komrade.backend.crypt import Crypt
handler = logging.StreamHandler() self._crypt = Crypt(
formatter = logging.Formatter('[%(asctime)s]\n%(message)s\n') fn=PATH_CRYPT_CA_DATA,
handler.setFormatter(formatter) encrypt_values=False,
self._logger = logger = logging.getLogger('komrade') )
logger.addHandler(handler) return self._crypt
logger.setLevel(logging.DEBUG)
return self._logger
def log(self,*args,**msgs):
line = ' '.join(str(x) for x in args)
self.logger.debug(line)
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.event_loop_worker = None self.event_loop_worker = None
self.loop=asyncio.get_event_loop() self.loop=asyncio.get_event_loop()
# load json storage
self.username=''
self.load_store()
self.uri=DEFAULT_URI
# connect to API # connect to API
self.api = Api(log=self.log) self.komrade=None
self._name=''
@property
async def node(self):
return await self.api.node
def get_username(self):
if hasattr(self,'username'): return self.username
self.load_store()
if hasattr(self,'username'): return self.username
return ''
def build(self): def build(self):
@ -288,7 +241,9 @@ class MainApp(MDApp):
return self.root return self.root
# def boot(self,username):
# kommie = Komrade(username)
# if self.exists_locally_as_contact()
def load_store(self): def load_store(self):
@ -355,34 +310,14 @@ class MainApp(MDApp):
@property @property
def keys(self): def keys(self):
return self.api.keys return self.komrade.contacts()
async def get_post(self,post_id): async def get_post(self,post_id):
return await self.api.get_post(post_id) return self.komrade.read_post()
async def get_posts(self,uri=b'/inbox/world'):
return await self.persona.read_inbox(uri)
# if uri.count('/')<2: raise Exception('not a URI: '+uri) def get_posts(self,uri=b'/inbox/world'):
# if 'login' in uri: return self.komrade.posts()
# raise Exception('!!!! '+uri)
# self.log(f'app.get_posts(uri={uri} -> ...')
# data = await self.api.get_posts(uri)
# self.log(f'app.get_posts() got back from api.get_posts() a {type(data)}')
# newdata=[]
# for d in data:
# # self.log('data d:',d)
# if not 'val' in d: continue
# newdict = dict(d['val'].items())
# newdict['timestamp']=float(d['time'])
# newdict['to_name']=d['channel']
# newdata.append(newdict)
# # return index
# return newdata
async def get_channel_posts(self,channel,prefix='inbox'): async def get_channel_posts(self,channel,prefix='inbox'):
# am I allowed to? # am I allowed to?
@ -408,17 +343,17 @@ class MainApp(MDApp):
are finished are finished
''' '''
# self.other_task = asyncio.ensure_future(self.waste_time_freely()) # self.other_task = asyncio.ensure_future(self.waste_time_freely())
self.other_task = asyncio.ensure_future(self.api.connect_forever()) # self.other_task = asyncio.ensure_future(self.api.connect_forever())
async def run_wrapper(): async def run_wrapper():
# we don't actually need to set asyncio as the lib because it is # we don't actually need to set asyncio as the lib because it is
# the default, but it doesn't hurt to be explicit # the default, but it doesn't hurt to be explicit
await self.async_run() #async_lib='asyncio') await self.async_run() #async_lib='asyncio')
print('App done') print('App done')
self.other_task.cancel() # self.other_task.cancel()
return asyncio.gather(run_wrapper(), self.other_task)
# return asyncio.gather(run_wrapper(), self.other_task)
asyncio.run(run_wrapper())
@ -431,12 +366,21 @@ class MainApp(MDApp):
self.dialog.open() self.dialog.open()
#stop #stop
def stat(self,msg,komrade_name='Telephone',pause=False,**y):
logger.info(msg)
# self.open_msg_dialog(msg)
self.root.add_card({
'author':komrade_name,
'to_name':self.komrade.name if self.komrade else '?',
'content':str(msg)
})
def open_msg_dialog(self,msg): def open_msg_dialog(self,msg):
from screens.post.post import MessagePopup,ProgressPopup from screens.post.post import MessagePopup,ProgressPopup
if not hasattr(self,'msg_dialog') or not self.msg_dialog: if not hasattr(self,'msg_dialog') or not self.msg_dialog:
self.msg_dialog = MessagePopup() self.msg_dialog = MessagePopup()
self.msg_dialog.ids.msg_label.text=msg self.msg_dialog.ids.msg_label.text=msg
self.msg_dialog.open() self.msg_dialog.open()
def close_dialog(self): def close_dialog(self):
if hasattr(self,'dialog'): if hasattr(self,'dialog'):

@ -164,7 +164,7 @@ MyLayout:
background_palette: 'Red' background_palette: 'Red'
theme_text_color:'Custom' theme_text_color:'Custom'
background_hue: '500' background_hue: '500'
right_action_items: [['account-circle-outline', partial(root.change_screen, 'profile')],['card-text', partial(root.change_screen_from_uri, '/inbox/world')],['message-outline', partial(root.change_screen, 'messages')],['pencil-plus-outline', partial(root.change_screen, 'post')],['exit-run', partial(root.change_screen, 'login')]] right_action_items: [['account-circle-outline', partial(root.change_screen, 'profile')],['card-text', partial(root.change_screen, 'feed')],['message-outline', partial(root.change_screen, 'messages')],['pencil-plus-outline', partial(root.change_screen, 'post')],['exit-run', partial(root.change_screen, 'login')]]
#left_action_items: [[f"assets/fist2.png", partial(root.change_screen, 'feed')]] #left_action_items: [[f"assets/fist2.png", partial(root.change_screen, 'feed')]]
# ['bell-outline', partial(root.change_screen, 'login')] # ['bell-outline', partial(root.change_screen, 'login')]

@ -11,6 +11,7 @@ import asyncio
### Base screens ### Base screens
class BaseScreen(MDScreen): class BaseScreen(MDScreen):
@property @property
def root(self): def root(self):
return self.app.root return self.app.root
@ -28,6 +29,14 @@ class BaseScreen(MDScreen):
class ProtectedScreen(BaseScreen): pass class ProtectedScreen(BaseScreen): pass
# def on_pre_enter(self): # def on_pre_enter(self):
# if not self.channel in self.app.api.keys: # if not self.channel in self.app.api.keys:

@ -143,7 +143,7 @@
id: post_content id: post_content
text: '' text: ''
pos_hint: {'center_y':1} pos_hint: {'center_y':1}
font_size:'13sp' font_size:'24sp'
# font_style:'H5' # font_style:'H5'
#font_name: "Strengthen" #font_name: "Strengthen"
# height: '400' # height: '400'
@ -162,8 +162,8 @@
id: post id: post
orientation: "vertical" orientation: "vertical"
padding: "20dp" padding: "20dp"
size_hint: (None, None) size_hint: (0.75, None)
size:('500sp','800sp') # size:('800sp','800sp')
# adaptive_height: True # adaptive_height: True
pos_hint: {"center_x": .5, "center_y": .5} pos_hint: {"center_x": .5, "center_y": .5}
md_bg_color: rgb(*COLOR_CARD) md_bg_color: rgb(*COLOR_CARD)

@ -142,7 +142,7 @@ class PostCard(MDCard):
recip='@'+recip if recip and recip[0].isalpha() else recip recip='@'+recip if recip and recip[0].isalpha() else recip
self.author_label.text+='\n[size=14sp]to '+recip+'[/size]' self.author_label.text+='\n[size=14sp]to '+recip+'[/size]'
self.author_label.markup=True self.author_label.markup=True
self.author_label.font_size = '18sp' self.author_label.font_size = '24sp'
self.author_avatar = author_avatar = PostAuthorAvatar(source=f'assets/avatars/{self.author}.png') #self.img_src) self.author_avatar = author_avatar = PostAuthorAvatar(source=f'assets/avatars/{self.author}.png') #self.img_src)
self.author_section_layout.add_widget(author_avatar) self.author_section_layout.add_widget(author_avatar)
self.author_section_layout.add_widget(author_label) self.author_section_layout.add_widget(author_label)
@ -175,6 +175,8 @@ class PostCard(MDCard):
# self.log(image.image_ratio) # self.log(image.image_ratio)
self.post_content = PostContent(text=self.content) self.post_content = PostContent(text=self.content)
self.post_content.font_size = '24sp'
# post_layout = PostGridLayout() # post_layout = PostGridLayout()
#content = PostContent() #content = PostContent()
@ -241,27 +243,56 @@ class PostCard(MDCard):
class FeedScreen(BaseScreen): class FeedScreen(BaseScreen):
posts = ListProperty() posts = ListProperty()
def on_pre_enter(self): # def on_pre_enter(self):
super().on_pre_enter() # if not hasattr(self,'get_posts'): self.get_posts=self.app.komrade.posts
# super().on_pre_enter()
# for post in self.posts:
# self.ids.post_carousel.remove_widget(post)
async def go(): # i=0
# self.log('ids:' +str(self.ids.post_carousel.ids)) # lim=25
for post in self.posts: # self.app.komrade.get_updates()
self.ids.post_carousel.remove_widget(post) # posts=self.get_posts()
# for i,post in enumerate(reversed(posts)):
i=0 # if i>lim: break
lim=25 # data = {
posts=await self.app.get_posts(self.app.uri) # 'author':post.from_name,
for i,post in enumerate(reversed(posts)): # 'to_name':post.to_name,
# for i,post in enumerate(posts)): # 'content':post.msg.get('txt') if type(post.msg)==dict else str(post.msg)
#if ln.startswith('@') or ln.startswith('RT '): continue # }
#i+=1 # post_obj = PostCard(data)
if i>lim: break # self.posts.append(post_obj)
# self.ids.post_carousel.add_widget(post_obj)
#post = Post(title=f'Marx Zuckerberg', content=ln.strip())
#self.log('???') def on_pre_enter(self):
post_obj = PostCard(post) self.clear_deck()
self.posts.append(post_obj) # for i,x
self.ids.post_carousel.add_widget(post_obj)
asyncio.create_task(go())
####
#
@property
def cards(self):
if not hasattr(self,'_cards'): self._cards=[]
return self._cards
def clear_deck(self):
for card in self.cards:
self.ids.post_carousel.remove_widget(card)
def add_card(self,data):
card = PostCard(data)
if not hasattr(self,'_cards'): self._cards=[]
self._cards.append(card)
self.app.log('card!',data)
self.app.log('ids:',self.ids.keys(), type(self))
self.app.log('card obj?',card)
# self.ids.post_carousel.add_widget(card)
stop

@ -118,9 +118,44 @@
size_hint:None,None size_hint:None,None
pos_hint: {'center_x': .5}#, 'bottom':1} pos_hint: {'center_x': .5}#, 'bottom':1}
<PasswordPopup>:
id: passpopup
type: "custom"
size: ('300dp','300dp')
MDBoxLayout:
id: msg_popup_box_layout
size_hint:(None,None)
orientation: 'vertical'
cols:1
md_bg_color: rgb(*COLOR_CARD)
spacing:'0dp'
padding:'0dp'
pos_hint: {'center_x':0.5, 'center_y':0.5}
radius:[20,]
border_radius:20
canvas:
Color:
rgba: rgb(*COLOR_CARD_BORDER,a=0.5)
Line:
width: 1
rounded_rectangle: (self.x, self.y, self.width, self.height, 20, 20, 20, 20)
<RegisterButton>: <RegisterButton>:
text: "" text: ""
on_release: self.register() on_release: self.enter()
theme_text_color: "Custom"
text_color: rgb(*COLOR_TEXT)
md_bg_color: 0,0,0,1
# font_size:'24sp'
# size_hint:1,None
<LoginButton>:
text: ""
on_release: self.login()
theme_text_color: "Custom" theme_text_color: "Custom"
text_color: rgb(*COLOR_TEXT) text_color: rgb(*COLOR_TEXT)
md_bg_color: 0,0,0,1 md_bg_color: 0,0,0,1

@ -1,24 +1,36 @@
from screens.base import BaseScreen import os,sys; sys.path.append(os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__),'..')),'..')))
from kivymd.uix.boxlayout import MDBoxLayout from komrade import *
from kivymd.uix.textfield import MDTextField from screens.base import *
from kivymd.uix.button import MDRectangleFlatButton from kivymd.uix.boxlayout import *
from kivymd.uix.label import MDLabel from kivymd.uix.textfield import *
from kivymd.uix.card import MDSeparator from kivymd.uix.button import *
from kivy.uix.label import Label from kivymd.uix.label import *
from main import MyLabel,rgb,COLOR_TEXT,COLOR_ICON,COLOR_ACCENT,COLOR_CARD from kivymd.uix.card import *
from kivy.uix.label import *
from kivymd.uix.dialog import *
from main import *
from misc import * from misc import *
from kivy.app import App from kivy.app import *
import logging
logger = logging.getLogger(__name__)
class LoginBoxLayout(MDBoxLayout): pass class LoginBoxLayout(MDBoxLayout): pass
class LoginButtonLayout(MDBoxLayout): pass class LoginButtonLayout(MDBoxLayout): pass
class UsernameField(MDTextField): pass class UsernameField(MDTextField): pass
class PasswordField(MDTextField): pass class PasswordField(MDTextField): pass
class LoginButton(MDRectangleFlatButton): pass class LoginButton(MDRectangleFlatButton): pass
class RegisterButton(MDRectangleFlatButton): class RegisterButton(MDRectangleFlatButton,Logger):
def register(self): def enter(self):
un=self.parent.parent.parent.username_field.text un=self.parent.parent.parent.username_field.text
app=App.get_running_app() login_screen = self.parent.parent.parent
app.register(un)
login_screen.boot(un)
# logger.info('types',type(self.parent),type(self.parent.parent.parent))
# app=App.get_running_app()
# app.boot(un)
# app.change_screen_from_uri(f'/inbox/{un}') # app.change_screen_from_uri(f'/inbox/{un}')
pass pass
@ -28,6 +40,8 @@ class UsernameLayout(MDBoxLayout): pass
class UsernameLabel(MDLabel): pass class UsernameLabel(MDLabel): pass
class WelcomeLabel(MDLabel): pass class WelcomeLabel(MDLabel): pass
class PasswordPopup(MDDialog): pass
class LoginScreen(BaseScreen): class LoginScreen(BaseScreen):
#def on_pre_enter(self): #def on_pre_enter(self):
# global app # global app
@ -36,6 +50,8 @@ class LoginScreen(BaseScreen):
def on_pre_enter(self): def on_pre_enter(self):
#log(self.ids) #log(self.ids)
#log('hello?') #log('hello?')
self.dialog=None
self.pass_added=False
self.layout = LoginBoxLayout() self.layout = LoginBoxLayout()
self.label_title = WelcomeLabel() self.label_title = WelcomeLabel()
self.label_title.font_name='assets/font.otf' self.label_title.font_name='assets/font.otf'
@ -66,27 +82,27 @@ class LoginScreen(BaseScreen):
#log(self.username_field) #log(self.username_field)
# self.username_field.text='hello????' # self.username_field.text='hello????'
# self.layout_password = UsernameLayout() self.layout_password = UsernameLayout()
# self.label_password = UsernameLabel(text='password:') self.label_password = UsernameLabel(text='password:')
# self.label_password.font_name='assets/font.otf' self.label_password.font_name='assets/font.otf'
self.label_username.font_name='assets/font.otf' self.label_username.font_name='assets/font.otf'
# self.password_field = PasswordField() self.password_field = PasswordField()
# self.password_field.line_color_focus=rgb(*COLOR_TEXT) self.password_field.line_color_focus=rgb(*COLOR_TEXT)
# self.password_field.line_color_normal=rgb(*COLOR_TEXT,a=0.25) self.password_field.line_color_normal=rgb(*COLOR_TEXT,a=0.25)
# self.password_field.font_name='assets/font.otf' self.password_field.font_name='assets/font.otf'
# self.layout_password.add_widget(self.label_password) self.layout_password.add_widget(self.label_password)
# self.layout_password.add_widget(self.password_field) self.layout_password.add_widget(self.password_field)
# self.layout.add_widget(self.layout_password) self.layout.add_widget(self.layout_password)
self.layout_buttons = LoginButtonLayout() self.layout_buttons = LoginButtonLayout()
self.layout.add_widget(get_separator('20sp')) self.layout.add_widget(get_separator('20sp'))
self.layout.add_widget(self.layout_buttons) self.layout.add_widget(self.layout_buttons)
# self.login_button = LoginButton() self.login_button = LoginButton()
# self.login_button.font_name='assets/font.otf' self.login_button.font_name='assets/font.otf'
# self.layout_buttons.add_widget(self.login_button) # self.layout_buttons.add_widget(self.login_button)
self.register_button = RegisterButton() self.register_button = RegisterButton()
@ -100,9 +116,9 @@ class LoginScreen(BaseScreen):
self.layout.add_widget(self.login_status) self.layout.add_widget(self.login_status)
self.label_title.font_size='18sp' self.label_title.font_size='18sp'
# self.label_password.font_size='18sp' self.label_password.font_size='18sp'
self.label_username.font_size='20sp' self.label_username.font_size='20sp'
# self.login_button.font_size='12sp' self.login_button.font_size='12sp'
self.register_button.font_size='9sp' self.register_button.font_size='9sp'
self.register_button.text='enter' self.register_button.text='enter'
self.username_field.font_size='20sp' self.username_field.font_size='20sp'
@ -117,7 +133,59 @@ class LoginScreen(BaseScreen):
#pass #pass
def on_enter(self): # def on_enter(self):
un=self.app.get_username() # un=self.app.get_username()
if un: self.username_field.text = un # if un: self.username_field.text = un
def show_pass_opt(self):
if not self.pass_added:
self.layout.add_widget(self.layout_password,index=2)
self.pass_added=True
def show_pass_opt1(self,button_text='login'):
if not self.dialog:
self.dialog = PasswordPopup(
title="password:",
type="custom",
content_cls=MDTextField(password=True),
buttons=[
MDFlatButton(
text="login"
),
],
)
self.dialog.open()
def getpass_func(self,why_msg):
return self.password_field.text
def boot(self,un):
kommie = Komrade(un,getpass_func=self.getpass_func)
# self.show_pass_opt()
if kommie.exists_locally_as_account():
self.login_status.text='You should be able to log into this account.'
if kommie.privkey:
self.login_status.text=f'Welcome back, Komrade @{un}'
self.app.is_logged_in=True
self.app.username=kommie.name
self.app.komrade=kommie
self.remove_widget(self.layout)
self.root.change_screen('feed')
else:
self.login_status.text='Login failed...'
# self.layout.add_widget(self.layout_password)
elif kommie.exists_locally_as_contact():
self.login_status.text='Komrade exists as a contact of yours.'
else:
self.login_status.text='Komrade not known on this device. Registering...'
res = kommie.register(logfunc=self.app.stat)
if kommie.privkey:
self.login_status.text='Registered'
self.app.is_logged_in=True
self.app.username=kommie.name
self.app.komrade=kommie
self.remove_widget(self.layout)
self.app.change_screen('feed')
else:
self.login_status.text = 'Sign up failed...'

@ -4,8 +4,8 @@ from screens.post.post import *
class MessagesScreen(FeedScreen): class MessagesScreen(FeedScreen):
def on_pre_enter(self): def on_pre_enter(self):
if not self.app.username: return if not self.app.komrade: return
self.app.uri = '/inbox/'+self.app.username self.get_posts = self.app.komrade.messages
super().on_pre_enter() super().on_pre_enter()

@ -10,6 +10,8 @@ from pythemis.skeygen import GenerateSymmetricKey
from pythemis.scell import SCellSeal from pythemis.scell import SCellSeal
from pythemis.exception import ThemisError from pythemis.exception import ThemisError
import logging
logger=logging.getLogger(__name__)
class KomradeKey(ABC,Logger): class KomradeKey(ABC,Logger):
@ -65,12 +67,14 @@ class KomradeSymmetricKeyWithPassphrase(KomradeSymmetricKey):
def passhash(self): def passhash(self):
if not self._passhash: if not self._passhash:
try: try:
self._passhash = hasher(getpass(WHY_MSG)) self._passhash = hasher(self.getpass_func(WHY_MSG))
except (KeyboardInterrupt,EOFError) as e: except (KeyboardInterrupt,EOFError) as e:
exit('@Keymaker: Incorrect password. Goodbye.') exit('@Keymaker: Incorrect password. Goodbye.')
return self._passhash return self._passhash
def __init__(self,passphrase=None,passhash=None): def __init__(self,passphrase=None,passhash=None,getpass_func=None):
self.getpass_func = getpass_func if getpass_func else getpass
# logger.info('Pass key started with getpass func:',self.getpass_func)
if passhash: if passhash:
self._passhash = passhash self._passhash = passhash
elif passphrase: elif passphrase:
@ -229,13 +233,13 @@ KEYMAKER_DEFAULT_KEY_TYPES = {
def get_key_obj(keyname,data,key_types=KEYMAKER_DEFAULT_KEY_TYPES): def get_key_obj(keyname,data,key_types=KEYMAKER_DEFAULT_KEY_TYPES,getpass_func=None):
if keyname.endswith('_decr'): if keyname.endswith('_decr'):
# print('get_key_obj',keyname,data)#,key_types) # print('get_key_obj',keyname,data)#,key_types)
try: try:
data_s = data.decode() data_s = data.decode()
if data_s in {KEY_TYPE_SYMMETRIC_WITH_PASSPHRASE,KomradeSymmetricKeyWithPassphrase.__name__}: if data_s in {KEY_TYPE_SYMMETRIC_WITH_PASSPHRASE,KomradeSymmetricKeyWithPassphrase.__name__}:
return KomradeSymmetricKeyWithPassphrase() return KomradeSymmetricKeyWithPassphrase(getpass_func=getpass_func)
except UnicodeDecodeError: except UnicodeDecodeError:
return KomradeSymmetricKeyWithoutPassphrase(data) return KomradeSymmetricKeyWithoutPassphrase(data)
@ -256,7 +260,8 @@ class Keymaker(Logger):
keychain={}, keychain={},
path_crypt_keys=PATH_CRYPT_CA_KEYS, path_crypt_keys=PATH_CRYPT_CA_KEYS,
path_crypt_data=PATH_CRYPT_CA_DATA, path_crypt_data=PATH_CRYPT_CA_DATA,
callbacks={}): callbacks={},
getpass_func=None):
# init logger with callbacks # init logger with callbacks
super().__init__(callbacks=callbacks) super().__init__(callbacks=callbacks)
@ -268,6 +273,8 @@ class Keymaker(Logger):
self._keychain={**keychain} self._keychain={**keychain}
self.path_crypt_keys=path_crypt_keys self.path_crypt_keys=path_crypt_keys
self.path_crypt_data=path_crypt_data self.path_crypt_data=path_crypt_data
self.getpass_func=getpass_func
# logger.info('Keymaker booted with getpass_func',getpass_func)
# boot keychain # boot keychain
self._keychain = self.keychain() self._keychain = self.keychain()
@ -308,7 +315,7 @@ class Keymaker(Logger):
def load_keychain_from_bytes(self,keychain): def load_keychain_from_bytes(self,keychain):
for keyname,keyval in keychain.items(): for keyname,keyval in keychain.items():
keychain[keyname] = get_key_obj(keyname,keyval) keychain[keyname] = get_key_obj(keyname,keyval,getpass_func=self.getpass_func)
return keychain return keychain
def keychain(self,look_for=KEYMAKER_DEFAULT_ALL_KEY_NAMES): def keychain(self,look_for=KEYMAKER_DEFAULT_ALL_KEY_NAMES):
@ -328,7 +335,7 @@ class Keymaker(Logger):
if keyname in keys and keys[keyname]: continue if keyname in keys and keys[keyname]: continue
key = self.crypt_keys.get(uri,prefix=f'/{keyname}/') key = self.crypt_keys.get(uri,prefix=f'/{keyname}/')
# print('found in crypt:',key,'for',keyname) # print('found in crypt:',key,'for',keyname)
if key: keys[keyname]=get_key_obj(keyname,key) if key: keys[keyname]=get_key_obj(keyname,key,getpass_func=self.getpass_func)
# try to assemble # try to assemble
keys = self.assemble(self.assemble(keys)) keys = self.assemble(self.assemble(keys))
@ -506,12 +513,12 @@ class Keymaker(Logger):
encr_key = keychain.get(encr_key_name) encr_key = keychain.get(encr_key_name)
# self.log(f'about to decrypt {encr_key} with {decr_key} and {decr_key.cell}') # self.log(f'about to decrypt {encr_key} with {decr_key} and {decr_key.cell}')
unencr_key = decr_key.decrypt(encr_key.data) unencr_key = decr_key.decrypt(encr_key.data)
keychain[unencr_key_name] = get_key_obj(unencr_key_name,unencr_key) keychain[unencr_key_name] = get_key_obj(unencr_key_name,unencr_key,getpass_func=self.getpass_func)
else: else:
# unencr_key = keychain.get(unencr_key_name) # unencr_key = keychain.get(unencr_key_name)
# self.log(f'about to encrypt {unencr_key} with {decr_key}') # self.log(f'about to encrypt {unencr_key} with {decr_key}')
encr_key = decr_key.encrypt(unencr_key.data) encr_key = decr_key.encrypt(unencr_key.data)
keychain[encr_key_name] = get_key_obj(encr_key_name,encr_key) keychain[encr_key_name] = get_key_obj(encr_key_name,encr_key,getpass_func=self.getpass_func)
except ThemisError as e: except ThemisError as e:
#exit('Incorrect password.') #exit('Incorrect password.')
#self.log('error!!',e,decrypt,decr_key,encr_key,decr_key_name,encr_key_name) #self.log('error!!',e,decrypt,decr_key,encr_key,decr_key_name,encr_key_name)

@ -4,7 +4,8 @@ from komrade.backend import *
from komrade.backend.keymaker import * from komrade.backend.keymaker import *
from komrade.backend.messages import Message from komrade.backend.messages import Message
import logging
logger = logging.getLogger(__name__)
@ -13,8 +14,9 @@ from komrade.backend.messages import Message
class KomradeX(Caller): class KomradeX(Caller):
def __init__(self, name=None, pubkey=None, callbacks={}): def __init__(self, name=None, pubkey=None, callbacks={}, getpass_func=None):
super().__init__(name=name, callbacks=callbacks) # logger.info('booting KomradeX with getpass_func:',getpass_func)
super().__init__(name=name, callbacks=callbacks, getpass_func=getpass_func)
self.log(f'Starting up with callbacks: {self._callbacks}') self.log(f'Starting up with callbacks: {self._callbacks}')
self.boot(create=False) self.boot(create=False)
# special? # special?
@ -143,7 +145,7 @@ class KomradeX(Caller):
qr_str=self.qr_str(pubkey.data_b64) qr_str=self.qr_str(pubkey.data_b64)
logfunc(f'(1) You may store your public key both on your device hardware, as well as share it with anyone you wish:\n\n{pubkey.data_b64_s}\n\nIt will also be stored as a QR code on your device:\n{qr_str}',pause=True,clear=True) logfunc(f'(1) You may store your public key both on your device hardware, as well as share it with anyone you wish:\n\n{pubkey.data_b64_s}\n\nIt will also be stored as a QR code on your device:\n{qr_str}',pause=True,clear=True)
logfunc('You must also register your username and public key with Komrade @Operator on the remote server.\n\nShall Komrade @Telephone send them over?',pause=False,clear=False)#),dict_format(data,tab=2),pause=True) logfunc('You must also register your username and public key with Komrade @Operator on the remote server.\n\nShall Komrade @Telephone send them over?',pause=False,clear=False)#),dict_format(data,tab=2),pause=True)
ok_to_send = input(f'\n@{name}: [Y/n] ') ok_to_send = 'y' #input(f'\n@{name}: [Y/n] ')
if ok_to_send.strip().lower()=='n': if ok_to_send.strip().lower()=='n':
logfunc('Cancelling registration.') logfunc('Cancelling registration.')
return return
@ -181,6 +183,8 @@ class KomradeX(Caller):
## 3) Have passphrase? ## 3) Have passphrase?
if SHOW_STATUS and not passphrase: if SHOW_STATUS and not passphrase:
passphrase = self.cli.status_keymaker_part2(name,passphrase,pubkey,privkey,hasher,self) passphrase = self.cli.status_keymaker_part2(name,passphrase,pubkey,privkey,hasher,self)
elif not passphrase and self.getpass_func:
passphrase=self.getpass_func(WHY_MSG)
else: else:
if not passphrase: passphrase = DEBUG_DEFAULT_PASSPHRASE if not passphrase: passphrase = DEBUG_DEFAULT_PASSPHRASE
while not passphrase: while not passphrase:
@ -661,7 +665,11 @@ class KomradeX(Caller):
posts=[] posts=[]
for post_id in inbox: for post_id in inbox:
self.log('???',post_id,inbox_prefix) self.log('???',post_id,inbox_prefix)
res_post = self.read_post(post_id) try:
res_post = self.read_post(post_id)
except ThemisError as e:
self.log('!! ',e)
continue
self.log('got post:',res_post) self.log('got post:',res_post)
if res_post.get('success') and res_post.get('post'): if res_post.get('success') and res_post.get('post'):
post=res_post.get('post') post=res_post.get('post')

@ -86,7 +86,8 @@ class Operator(Keymaker):
keychain = {}, keychain = {},
path_crypt_keys=PATH_CRYPT_CA_KEYS, path_crypt_keys=PATH_CRYPT_CA_KEYS,
path_crypt_data=PATH_CRYPT_CA_DATA, path_crypt_data=PATH_CRYPT_CA_DATA,
callbacks={} callbacks={},
getpass_func=None
): ):
global PHONEBOOK global PHONEBOOK
@ -97,7 +98,8 @@ class Operator(Keymaker):
keychain=keychain, keychain=keychain,
path_crypt_keys=path_crypt_keys, path_crypt_keys=path_crypt_keys,
path_crypt_data=path_crypt_data, path_crypt_data=path_crypt_data,
callbacks=callbacks callbacks=callbacks,
getpass_func=getpass_func
) )

@ -4,8 +4,8 @@ KOMRADE_ONION = 'u7spnj3dmwumzoa4.onion'
KOMRADE_ONION2 = 'rwg4zcnpwshv4laq.onion' #'128.232.229.63' #'komrade.app' KOMRADE_ONION2 = 'rwg4zcnpwshv4laq.onion' #'128.232.229.63' #'komrade.app'
OPERATOR_API_URL = f'http://{KOMRADE_ONION}/op/' # OPERATOR_API_URL = f'http://{KOMRADE_ONION}/op/'
# OPERATOR_API_URL = f'http://{KOMRADE_URL}/op/' OPERATOR_API_URL = f'http://{KOMRADE_URL}/op/'
# paths # paths
@ -17,6 +17,7 @@ PATH_KOMRADE_DATA = os.path.join(PATH_KOMRADE,'.data')
PATH_CRYPT_OP_KEYS = os.path.join(PATH_KOMRADE_KEYS,'.op.db.keys.crypt') PATH_CRYPT_OP_KEYS = os.path.join(PATH_KOMRADE_KEYS,'.op.db.keys.crypt')
PATH_CRYPT_OP_DATA = os.path.join(PATH_KOMRADE_DATA,'.op.db.data.crypt') PATH_CRYPT_OP_DATA = os.path.join(PATH_KOMRADE_DATA,'.op.db.data.crypt')
# PATH_CRYPT_CA_KEYS = os.path.join(PATH_KOMRADE_KEYS,'.ca.db.keys.crypt') # PATH_CRYPT_CA_KEYS = os.path.join(PATH_KOMRADE_KEYS,'.ca.db.keys.crypt')
# PATH_CRYPT_CA_DATA = os.path.join(PATH_KOMRADE_DATA,'.ca.db.data.encr') # PATH_CRYPT_CA_DATA = os.path.join(PATH_KOMRADE_DATA,'.ca.db.data.encr')
PATH_CRYPT_CA_KEYS = PATH_CRYPT_OP_KEYS PATH_CRYPT_CA_KEYS = PATH_CRYPT_OP_KEYS
@ -26,6 +27,8 @@ PATH_QRCODES = os.path.join(PATH_KOMRADE,'contacts')
PATH_SECRETS = PATH_SUPER_SECRETS = os.path.join(PATH_USER_HOME,'.secrets') PATH_SECRETS = PATH_SUPER_SECRETS = os.path.join(PATH_USER_HOME,'.secrets')
PATH_SUPER_SECRET_OP_KEY = os.path.join(PATH_SUPER_SECRETS,'.komrade.op.key') PATH_SUPER_SECRET_OP_KEY = os.path.join(PATH_SUPER_SECRETS,'.komrade.op.key')
PATH_LOG_OUTPUT = os.path.join(PATH_KOMRADE,'logs') PATH_LOG_OUTPUT = os.path.join(PATH_KOMRADE,'logs')

@ -28,17 +28,17 @@ class CallbackHandler(Handler):
# log_entry, headers={"Content-type": "application/json"}).content # log_entry, headers={"Content-type": "application/json"}).content
def logger(): def logger(name=__name__):
import logging import logging
handler = logging.StreamHandler() handler = logging.StreamHandler()
formatter = logging.Formatter('[%(asctime)s]\n%(message)s\n') formatter = logging.Formatter('[%(asctime)s]\n%(message)s\n')
handler.setFormatter(formatter) handler.setFormatter(formatter)
logger = logging.getLogger('komrade') logger = logging.getLogger(name)
logger.addHandler(handler) logger.addHandler(handler)
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
return logger return logger
LOG = None LOG = logger().info
def log(*x,off=False): def log(*x,off=False):
global LOG global LOG

Loading…
Cancel
Save