mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-25 23:51:07 +00:00
fc91837f69
this changes the confwiz so that hitting the 'create account' button, rather than opening a webbrowser to the register page, instead provides a simple account creation ui directly, along with changes to the backend (native_client.php) to support that. also added a 'connecting...' message so the user sees a response when they hit login or create account, since the getBasedir call can sometimes take up to ~5min (which is unacceptable for a user product, but this at least somewhat ameliorates the issue of the ui locking up and not giving the user any feedback while it's happening)
406 lines
14 KiB
Python
406 lines
14 KiB
Python
|
|
BACKEND_URL = 'https://www-test.allmydata.com/native_client.php'
|
|
#REGISTER_PAGE = 'https://www-test.allmydata.com/register'
|
|
TAHOESVC_NAME = 'Tahoe'
|
|
WINFUSESVC_NAME = 'Allmydata Tahoe SMB'
|
|
|
|
import os
|
|
import sys
|
|
#import time
|
|
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
|
|
|
|
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)
|
|
return conn.read()
|
|
|
|
def get_root_cap(url, user, passwd):
|
|
args = {
|
|
'action': 'authenticate',
|
|
'email': unicode_to_utf8(user),
|
|
'passwd': unicode_to_utf8(passwd),
|
|
}
|
|
root_cap = post(url, args)
|
|
if root_cap == '0':
|
|
raise AuthError()
|
|
elif not uri.is_uri(root_cap):
|
|
raise ValueError('%r is not a URI' % (root_cap,))
|
|
else:
|
|
return root_cap
|
|
|
|
def create_account(url, user, passwd, subscribe):
|
|
args = {
|
|
'action': 'create_account',
|
|
'email': unicode_to_utf8(user),
|
|
'passwd': unicode_to_utf8(passwd),
|
|
'subscribe': subscribe and 'true' or 'false',
|
|
}
|
|
result_code = post(url, args)
|
|
return result_code
|
|
|
|
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.login_frame = LoginFrame(self)
|
|
self.login_frame.CenterOnScreen()
|
|
self.SetTopWindow(self.login_frame)
|
|
self.SetExitOnFrameDelete(True)
|
|
self.login_frame.Show(True)
|
|
|
|
return True
|
|
except:
|
|
DisplayTraceback('config wizard init threw an exception')
|
|
|
|
def swap_to_register_frame(self):
|
|
try:
|
|
self.login_frame.Show(False)
|
|
self.regiser_frame = RegisterFrame(self)
|
|
self.regiser_frame.CenterOnScreen()
|
|
self.SetTopWindow(self.regiser_frame)
|
|
self.SetExitOnFrameDelete(True)
|
|
self.regiser_frame.Show(True)
|
|
except:
|
|
DisplayTraceback('config wizard threw an exception')
|
|
|
|
class LoginFrame(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.reg_btn_panel = RegisterButtonPanel(background, app)
|
|
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.reg_btn_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 RegisterFrame(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.register_panel = RegisterPanel(background)
|
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
|
background_sizer = wx.BoxSizer(wx.VERTICAL)
|
|
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.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('Connecting...')
|
|
self.Layout()
|
|
wx.Yield()
|
|
|
|
if passwd == '':
|
|
self.warning_label.SetLabel('You must enter a password')
|
|
self.pass_field.SetFocus()
|
|
self.Layout()
|
|
return
|
|
|
|
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':
|
|
self.start_windows_service(TAHOESVC_NAME)
|
|
self.start_windows_service(WINFUSESVC_NAME)
|
|
|
|
# exit
|
|
self.parent.parent.Close()
|
|
|
|
def start_windows_service(self, svc_name):
|
|
try:
|
|
import win32service
|
|
import win32serviceutil as wsu
|
|
if wsu.QueryServiceStatus(svc_name)[1] != win32service.SERVICE_RUNNING:
|
|
wsu.StartService(svc_name)
|
|
except:
|
|
DisplayTraceback('Failed to start windows service "%s"' % (svc_name,))
|
|
|
|
class RegisterButtonPanel(wx.Panel):
|
|
def __init__(self, parent, app):
|
|
wx.Panel.__init__(self, parent, -1)
|
|
self.parent = parent
|
|
self.app = app
|
|
|
|
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)
|
|
self.app.swap_to_register_frame()
|
|
|
|
class RegisterPanel(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.conf_label = wx.StaticText(self, -1, 'Confirm 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.conf_field = wx.TextCtrl(self, -1, u'', size=(260,-1), style=wx.TE_PASSWORD)
|
|
self.create_account_button = wx.Button(self, -1, 'Create Account')
|
|
self.subscribe_box = wx.CheckBox(self, -1, 'Sign up for our Newsletter')
|
|
self.subscribe_box.SetValue(True)
|
|
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)
|
|
wx.EVT_CHAR(self.conf_field, self.on_conf_entry)
|
|
self.Bind(wx.EVT_BUTTON, self.on_create_account, self.create_account_button)
|
|
login_sizer = wx.FlexGridSizer(4, 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(self.conf_label, 0, wx.ALIGN_RIGHT | wx.ALL, 2)
|
|
login_sizer.Add(self.conf_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.create_account_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.CENTER | wx.ALL, 2)
|
|
self.sizer.Add(self.subscribe_box, 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.conf_field.SetFocus()
|
|
else:
|
|
event.Skip()
|
|
|
|
def on_conf_entry(self, event):
|
|
if event.GetKeyCode() == wx.WXK_RETURN:
|
|
self.on_create_account(event)
|
|
else:
|
|
event.Skip()
|
|
|
|
def on_create_account(self, event):
|
|
user = self.user_field.GetValue()
|
|
passwd = self.pass_field.GetValue()
|
|
pconf = self.conf_field.GetValue()
|
|
subscribe = self.subscribe_box.IsChecked()
|
|
self.warning_label.SetLabel('Connecting...')
|
|
self.Layout()
|
|
wx.Yield()
|
|
|
|
if passwd == '':
|
|
self.warning_label.SetLabel('You must enter a password')
|
|
self.pass_field.SetFocus()
|
|
self.Layout()
|
|
return
|
|
|
|
if passwd != pconf:
|
|
self.warning_label.SetLabel("Passwords don't match")
|
|
self.pass_field.SetValue('')
|
|
self.conf_field.SetValue('')
|
|
self.pass_field.SetFocus()
|
|
self.Layout()
|
|
return
|
|
|
|
#print 'calling create_account', time.asctime()
|
|
result_code = create_account(BACKEND_URL, user, passwd, subscribe)
|
|
|
|
if result_code == 'account_exists':
|
|
# try and log into it; if valid, use it anyway
|
|
try:
|
|
#print 'calling get_root_cap (ae)', time.asctime()
|
|
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('That email address is already registered')
|
|
self.user_field.SetFocus()
|
|
self.Layout()
|
|
return
|
|
elif result_code == 'error':
|
|
self.warning_label.SetLabel('an error occurred')
|
|
self.user_field.SetFocus()
|
|
self.Layout()
|
|
return
|
|
elif result_code == 'ok':
|
|
#print 'calling get_root_cap (ok)', time.asctime()
|
|
root_cap = get_root_cap(BACKEND_URL, user, passwd)
|
|
write_config_file('private/root_dir.cap', root_cap+'\n')
|
|
else:
|
|
self.warning_label.SetLabel('an unexpected error occurred ("%s")' % (result_code,))
|
|
self.user_field.SetFocus()
|
|
self.Layout()
|
|
return
|
|
|
|
# fetch the introducer furl
|
|
#print 'calling get_introducer_furl', time.asctime()
|
|
ifurl = get_introducer_furl(BACKEND_URL)
|
|
write_config_file('introducer.furl', ifurl+'\n')
|
|
|
|
# start service etc.
|
|
if sys.platform == 'win32':
|
|
self.start_windows_service(TAHOESVC_NAME)
|
|
self.start_windows_service(WINFUSESVC_NAME)
|
|
|
|
# exit
|
|
self.parent.parent.Close()
|
|
|
|
def start_windows_service(self, svc_name):
|
|
try:
|
|
import win32service
|
|
import win32serviceutil as wsu
|
|
if wsu.QueryServiceStatus(svc_name)[1] != win32service.SERVICE_RUNNING:
|
|
wsu.StartService(svc_name)
|
|
except:
|
|
DisplayTraceback('Failed to start windows service "%s"' % (svc_name,))
|
|
|
|
|
|
def main():
|
|
app = ConfWizApp()
|
|
app.MainLoop()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|