mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-24 07:06:41 +00:00
implement a very simple, wxpython based, config wizard
This implements a very small app using a wx ui to log a user in. it takes a username and password, and submits them to a backend on the web site (currently the allmydata test net webserver) to authenticate them. It returns the 'root_cap' uri of the user's virtual drive. Also the introducer.furl is retrieved. These are then written into the default noderoot basedir in their usual files (private/root_dir.cap and introducer.furl) a button is provided which will direct the user to the web site in the event that they need to register in order to have an account to use. once the user is successfully authenticated and the files are written, then on win32 the tahoe service will be started.
This commit is contained in:
parent
d87a80dca6
commit
dba59050a9
69
windows/amdicon.py
Normal file
69
windows/amdicon.py
Normal file
@ -0,0 +1,69 @@
|
||||
#----------------------------------------------------------------------
|
||||
# This file was generated by encode_icons.py
|
||||
#
|
||||
from wx import ImageFromStream, BitmapFromImage
|
||||
from wx import EmptyIcon
|
||||
import cStringIO
|
||||
|
||||
|
||||
def getData():
|
||||
return \
|
||||
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
|
||||
\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x04\
|
||||
\x1aIDATX\x85\xad\x97MLTW\x14\xc7\xff\xef\xbd\x997|\x8c\x86\xb1\x888\x0c\x06\
|
||||
\x17\x80\x03\xa1\x8a\t\xa9\x8d5a\xd3t\xd3\xa4\xed\xae+\xe3\xa6\xe9\x02v\x8d\
|
||||
\xdd\xb8\xd2%D\xb1\x06\x02]\xd9.\xba\xd0\xa4iBqaHHM\xcbnbGZeH\x8d\x16\xad\
|
||||
\xed\x14\x91\xe1c\x98\xb9\xf7\xbdw\xcf\xe9\x02\x9c\xf2\xf1\xde\x9b7\xc8\x99L\
|
||||
2\x99{\xce\xb9\xbfs\xee\xb9\xe7\xde\xabi\xba\x81\xa0\x12\x1eN2\xd9!\x90\x1d\
|
||||
\xc2\xdb\x87\x92\xa8\xab\x8abY\xe41\xb34\x0b=\xec\xc00mX}\x19-\xb0C\x00\xd0t\
|
||||
#\xd0\xd7\xb8\xde\xcd-\xa3\x1f\xf3\xcd\x99\t\xce\x895\xde*9\xb1\xc67g&\xb8e\
|
||||
\xec#\x0e}u\x8a\x83\xfa\xd4t#\x18\x80q\xed4_\xb8s\x85\xcbIN\xac\xf1\x85;W\
|
||||
\xd8\xb8v:0D\xf9\xc9\x87\xba\xf9\xfc\xc4eV;>S\xf3)\x9e\x9aO\xf1\xfdlf\xd7\
|
||||
\xd8\xf9\x89\xcbl\\\xef\x0e\x06\xe1W\x03\xa1\x1b\x1d|&\xf6.\xee~:T\xfao\xe2\
|
||||
\x8fi\\\xfci\x04\x7f\x15\x9e\x03:\x03\xa4!Q\xd3\x8c\xc1\xde>|\xd8z\xb6\xa4w\
|
||||
\xe6\xdb\xcf\x90\x113\xb0\xfbg\xfdk\xa2\\\xea\xc7\x9fL\xf1\x92\xbd\xc8K\xf6"\
|
||||
\x8f\xa4o\xb16\xd8\xc3\x91\xd1\xcem\xd1EF;Y\x1b\xec\xe1\x91\xf4\xad\x92\xee\
|
||||
\xf8\x93\xa9@K\xa1\xfb\xc1\xc5\xab\xe2\xe8ij\x83$\x81\x97\xc5W\xb8to\x0cf\
|
||||
\xb4\xb0\xab\xd2\xad\xbe\x8cfF\x0b\xb8to\x0c/\x8b\xaf I\xa0\xa7\xa9\r\xf1\
|
||||
\xea\xb8\xff\x0e\x00\xbc\x01B7:\xf8\x9dD\x12\x92\x05$\x0b|\xf7p\x12y\xe4<\
|
||||
\xb7\x99\xd5\x97\xd1\xf2\xc8\xe1\xc7\xc7\xd3%\x9bd\xfd1\x84\x87\x93\xbc\'\
|
||||
\x00\x008z \x06I\x02\x92\x04rb\x15\x9a\xa1|\xa3\xd1\x0c\x85\xf9\x95l\xc9\xa6\
|
||||
\xbd>\x01&\xff\x12\x08\xf9\r:\xec@\x92(\xfd\x0e"\x95\xda\x94\x01\xb0\xb78\
|
||||
\xb3\x03\x02Tf\xe3\t\xa0\xa4\t\x87\x1d\x08*\x02\x00\xea\xa3Qt\x1e\xec\x00\
|
||||
\xbe\xe9\xf0]\xd3\xfah\xb4d\xe3\xb0\x03%M_\x00\xd7>\xa0\r\x9e\xe2/\xce~\x82\
|
||||
\x0f\xdaO\x96\x8d\xa0\x9c\xdc\x9d{\x80\xab\xd3?\x80/\xa6]\x8b\xc15\x03-\x07\
|
||||
\xe3\xe8mm/\xa5\xf2M\xa4\xb7\xb5\x1d\xdf\xff\x16\xc7S\xa4]\xc7]\x01\xaa\xcd\
|
||||
\xf0\xbeL\xbe\xd5\x9f\x97\xb8\x020\x13\xc4>\x020Se\x00\x04\x82do\x80\xb9\xec\
|
||||
\x02&\x1feP\xb0,\xd4\x98&\xde\xef8\x81\xf6\xc6\x06O}B\xa5\x00L\xa5J\xde)\x0f\
|
||||
\x9e\xfd\x83\xaf\x7f\xfe\x05\xe1\xda"\xec\xfeY-<\x9c\xe4\xfb\x93\x7f\xe2\xf3\
|
||||
s\xef\xe1\xe4\xb1\xa3\xee\x00{\xca\x80\xcb\x12,;K\xb8\x9dJo;\x0f\xec\xfeY\
|
||||
\xcd\x1c9\xc1\xb7S\xbf\xe2\xad\x06\x0bu\xa1\x18\xc2\xba\xb9\xcb\xdf\x1e\x00$\
|
||||
\x14;X\xb0\xb3\xf8\xd7z\x81U\xb5\x02b\x85e\xa1\x83\xbf\xdc}\x18\xd9\x03\xd5<\
|
||||
\x99\x1b\x07\x81P\xa5W\xe3p\xf8\x08\x8eW\xb5\xe1\x88\x19\xaf\x1c\x80\x99\xf0\
|
||||
B>\xc3\xbc|\x0c\x8b,\x10\x14\x14\x13\x88\x15\x98j\\\x1d1i\x90,A\xacP\xa0u,\
|
||||
\xda\x0bx\xb8\x9e\xc6a\xb3\x11k\x8ew}\xb8\x1eFy\xb5\x86\xb9\xe2\xef(\xa8\xf5\
|
||||
\xcd\x83E\xc2\xa2\x8d\x13\xae\xb1Y\xc0\x18\xea\xda\xd6\r\x8d\xa1.\x8e5\xadl\
|
||||
\xeaHX$7\xecX\xe2\xb9x\x8aU\xb5R\x19\xc0\xeb~.Y\xc2\xe2\xff\x9dY$\xd1p|\t\
|
||||
\xb5Q\xa7\x04a\x0cuq\xa4V\xa2\xae\xe5\xefM\x1d\x01\x8b$\x1c\xb672\x06\xdf\
|
||||
\xce\xed]\x03\x16I((\x10+\x106\xd2\xafX\x81\x0cB]3!\xff\xa8\x11\x00\xc0\xac\
|
||||
\xe1@"\x0bG/\x80\xc9\x7f\xb2\xe0\x00\xbc\xd1\x07\x88is\xfd\xb7C\xd8\xac\xef\
|
||||
\xd2/\x17iE\x00\xbc3\x03L\xdb\xb2\xe1\x90wk\xdd\x17\x00\x02C\x92\x00\x816\
|
||||
\xa3W`\xe6=GY9\x00\x13,\x96\xbe\xa9%+\x04m\xa0\x9b\xc9\xaa\xec%\x16\x08\x80\
|
||||
\xc1P\xec}\xff\x8b\xd4\xad"q.\xf5F\x13\xbf\x16\xd7mHN\xf0\x07k\x10\xf1\xf3\
|
||||
\xe7\n\xa0\xa4\x89\xe2bl_&/.\xc6\xa0D\xc4s\xdc\xf3i\xa6\rt\xb3Q%\xa1\x87\xfc\
|
||||
\xaf\xe2~B\x8e\x01%M\xcf\xeb\x18\x00\xfc\x07\x9aY\xdf_&\xed\xfd\xe8\x00\x00\
|
||||
\x00\x00IEND\xaeB`\x82'
|
||||
|
||||
def getBitmap():
|
||||
return BitmapFromImage(getImage())
|
||||
|
||||
def getImage():
|
||||
stream = cStringIO.StringIO(getData())
|
||||
return ImageFromStream(stream)
|
||||
|
||||
def getIcon():
|
||||
icon = EmptyIcon()
|
||||
icon.CopyFromBitmap(getBitmap())
|
||||
return icon
|
||||
|
||||
|
@ -1,10 +1,22 @@
|
||||
|
||||
BACKEND_URL = 'https://www-test.allmydata.com/native_client2.php'
|
||||
REGISTER_PAGE = 'https://www-test.allmydata.com/register'
|
||||
WINSVC_NAME = 'Tahoe'
|
||||
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
import urllib2
|
||||
from urllib import urlencode
|
||||
import webbrowser
|
||||
import wx
|
||||
|
||||
from allmydata.util.assertutil import precondition
|
||||
from allmydata import uri
|
||||
|
||||
import amdicon
|
||||
|
||||
|
||||
class AuthError(Exception):
|
||||
pass
|
||||
|
||||
@ -12,6 +24,7 @@ def unicode_to_utf8(uobj):
|
||||
assert precondition(isinstance(uobj, unicode))
|
||||
return uobj.encode('utf-8')
|
||||
|
||||
|
||||
def post(url, args):
|
||||
argstr = urlencode(args)
|
||||
conn = urllib2.urlopen(url, argstr)
|
||||
@ -34,12 +47,166 @@ def get_root_cap(url, user, passwd):
|
||||
def get_introducer_furl(url):
|
||||
return post(url, { 'action': 'getintroducerfurl' })
|
||||
|
||||
def write_config_file(filename, contents):
|
||||
if sys.platform == 'win32':
|
||||
from allmydata.windows import registry
|
||||
basedir = registry.get_base_dir_path()
|
||||
else:
|
||||
basedir = os.path.expanduser('~/.tahoe')
|
||||
path = os.path.join(basedir, filename)
|
||||
dirname = os.path.dirname(path)
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
iff = file(path, 'wb')
|
||||
iff.write(contents)
|
||||
iff.close()
|
||||
|
||||
|
||||
def DisplayTraceback(message):
|
||||
xc = traceback.format_exception(*sys.exc_info())
|
||||
wx.MessageBox(u"%s\n (%s)"%(message,''.join(xc)), 'Error')
|
||||
|
||||
class ConfWizApp(wx.App):
|
||||
def __init__(self):
|
||||
wx.App.__init__(self, 0)
|
||||
|
||||
def OnInit(self):
|
||||
try:
|
||||
wx.InitAllImageHandlers()
|
||||
|
||||
self.frame = ConfWizFrame(self)
|
||||
self.frame.CenterOnScreen()
|
||||
self.SetTopWindow(self.frame)
|
||||
self.SetExitOnFrameDelete(True)
|
||||
self.frame.Show(True)
|
||||
|
||||
return True
|
||||
except:
|
||||
DisplayTraceback('config wizard init threw an exception')
|
||||
|
||||
class ConfWizFrame(wx.Frame):
|
||||
def __init__(self, app):
|
||||
title = 'Allmydata Tahoe Config Wizard'
|
||||
wx.Frame.__init__(self, None, -1, title)
|
||||
self.app = app
|
||||
self.SetSizeHints(100, 100, 600, 800)
|
||||
self.SetIcon(amdicon.getIcon())
|
||||
self.Bind(wx.EVT_CLOSE, self.close)
|
||||
|
||||
background = wx.Panel(self, -1)
|
||||
background.parent = self
|
||||
self.login_panel = LoginPanel(background)
|
||||
self.register_panel = RegisterPanel(background)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
background_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
background_sizer.Add(self.login_panel, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 26)
|
||||
background_sizer.Add(self.register_panel, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 26)
|
||||
background.SetSizer(background_sizer)
|
||||
sizer.Add(background, 0, wx.EXPAND | wx.ALL, 0)
|
||||
self.SetSizer(sizer)
|
||||
self.SetAutoLayout(True)
|
||||
self.Fit()
|
||||
self.Layout()
|
||||
|
||||
def close(self, event):
|
||||
sys.exit()
|
||||
|
||||
class LoginPanel(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent, -1)
|
||||
self.parent = parent
|
||||
|
||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.user_label = wx.StaticText(self, -1, 'Email')
|
||||
self.pass_label = wx.StaticText(self, -1, 'Password')
|
||||
self.user_field = wx.TextCtrl(self, -1, u'', size=(260,-1))
|
||||
self.pass_field = wx.TextCtrl(self, -1, u'', size=(260,-1), style=wx.TE_PASSWORD)
|
||||
self.login_button = wx.Button(self, -1, 'Sign In')
|
||||
self.warning_label = wx.StaticText(self, -1, '')
|
||||
self.warning_label.SetOwnForegroundColour(wx.RED)
|
||||
wx.EVT_CHAR(self.user_field, self.on_user_entry)
|
||||
wx.EVT_CHAR(self.pass_field, self.on_pass_entry)
|
||||
self.Bind(wx.EVT_BUTTON, self.on_login, self.login_button)
|
||||
login_sizer = wx.FlexGridSizer(3, 2, 5, 4)
|
||||
login_sizer.Add(self.user_label, 0, wx.ALIGN_RIGHT | wx.ALL, 2)
|
||||
login_sizer.Add(self.user_field, 0, wx.EXPAND | wx.ALL, 2)
|
||||
login_sizer.Add(self.pass_label, 0, wx.ALIGN_RIGHT | wx.ALL, 2)
|
||||
login_sizer.Add(self.pass_field, 0, wx.EXPAND | wx.ALL, 2)
|
||||
login_sizer.Add(wx.Size(2,2), 0, wx.ALIGN_RIGHT | wx.ALL, 2)
|
||||
login_sizer.Add(self.login_button, 0, wx.ALIGN_RIGHT | wx.ALL, 2)
|
||||
self.sizer.Add(login_sizer, 1, wx.EXPAND | wx.ALL, 2)
|
||||
#self.sizer.Add(self.warning_label, 0, wx.EXPAND | wx.ALL, 2)
|
||||
self.sizer.Add(self.warning_label, 0, wx.CENTER | wx.ALL, 2)
|
||||
self.SetSizer(self.sizer)
|
||||
self.SetAutoLayout(True)
|
||||
|
||||
def on_user_entry(self, event):
|
||||
if event.GetKeyCode() == wx.WXK_RETURN:
|
||||
self.pass_field.SetFocus()
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def on_pass_entry(self, event):
|
||||
if event.GetKeyCode() == wx.WXK_RETURN:
|
||||
self.on_login(event)
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def on_login(self, event):
|
||||
user = self.user_field.GetValue()
|
||||
passwd = self.pass_field.GetValue()
|
||||
self.warning_label.SetLabel('')
|
||||
|
||||
try:
|
||||
root_cap = get_root_cap(BACKEND_URL, user, passwd)
|
||||
write_config_file('private/root_dir.cap', root_cap+'\n')
|
||||
except AuthError:
|
||||
self.warning_label.SetLabel('Your email and/or password is incorrect')
|
||||
self.user_field.SetFocus()
|
||||
self.Layout()
|
||||
return
|
||||
|
||||
# fetch the introducer furl
|
||||
ifurl = get_introducer_furl(BACKEND_URL)
|
||||
write_config_file('introducer.furl', ifurl+'\n')
|
||||
|
||||
# start service etc.
|
||||
if sys.platform == 'win32':
|
||||
try:
|
||||
import win32service
|
||||
import win32serviceutil as wsu
|
||||
if wsu.QueryServiceStatus(WINSVC_NAME)[1] != win32service.SERVICE_RUNNING:
|
||||
wsu.StartService(WINSVC_NAME)
|
||||
except:
|
||||
DisplayTraceback('Failed to start windows service')
|
||||
|
||||
# exit
|
||||
self.parent.parent.Close()
|
||||
|
||||
class RegisterPanel(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent, -1)
|
||||
self.parent = parent
|
||||
|
||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
self.reg_label = wx.StaticText(self, -1, "Don't have an account?")
|
||||
self.reg_button = wx.Button(self, -1, 'Create Account')
|
||||
self.Bind(wx.EVT_BUTTON, self.on_reg_button, self.reg_button)
|
||||
reg_sizer = wx.FlexGridSizer(1, 2, 5, 4)
|
||||
reg_sizer.Add(self.reg_label, 0, wx.ALIGN_RIGHT | wx.ALL, 2)
|
||||
reg_sizer.Add(self.reg_button, 0, wx.ALIGN_RIGHT | wx.ALL, 2)
|
||||
self.sizer.Add(reg_sizer, 1, wx.EXPAND | wx.ALL, 2)
|
||||
self.SetSizer(self.sizer)
|
||||
self.SetAutoLayout(True)
|
||||
|
||||
def on_reg_button(self, event):
|
||||
webbrowser.open(REGISTER_PAGE)
|
||||
|
||||
def main():
|
||||
|
||||
URL = 'https://www-test.allmydata.com/native_client2.php'
|
||||
|
||||
print get_introducer_furl(URL)
|
||||
print get_root_cap(URL, u'user', u'pass')
|
||||
app = ConfWizApp()
|
||||
app.MainLoop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
Reference in New Issue
Block a user