Merge branch 'master' into first-boot-create-user

Resolve conflicts in modules/installed/first_boot.py.
This commit is contained in:
Petter Reinholdtsen 2013-09-16 05:27:57 +02:00
commit f24d1fb94d
15 changed files with 83 additions and 37 deletions

View File

@ -4,6 +4,7 @@ CSS=$(wildcard *.css)
CSS=$(subst .tiny,,$(shell find themes -type f -name '*.css'))
COMPRESSED_CSS := $(patsubst %.css,%.tiny.css,$(CSS))
PWD=`pwd`
BUILDDIR=vendor
# hosting variables
SLEEP_TIME=300
@ -29,6 +30,8 @@ install: default
$(DESTDIR)/usr/share/doc/plinth $(DESTDIR)/usr/share/man/man1
cp -a static themes $(DESTDIR)$(DATADIR)/
cp -a *.py modules templates $(DESTDIR)$(PYDIR)/
mkdir -p $(DESTDIR)$(PYDIR)/exmachina
cp -a vendor/exmachina/exmachina.py $(DESTDIR)$(PYDIR)/exmachina/.
cp share/init.d/plinth $(DESTDIR)/etc/init.d
install plinth $(DESTDIR)/usr/bin/
mkdir -p $(DESTDIR)/var/lib/plinth/cherrypy_sessions $(DESTDIR)/var/log/plinth $(DESTDIR)/var/run

0
exmachina/__init__.py Normal file
View File

5
fabfile.py vendored
View File

@ -7,7 +7,10 @@
# plinth box
import os,sys, subprocess
import simplejson as json
try:
import simplejson as json
except ImportError:
import json
import fabric.api
from fabric.api import local, env, cd, put, get, task

View File

@ -5,7 +5,10 @@ Author: Erez Shinan
Date : 31-May-2009
"""
import simplejson as json ## jlv replaced pickle with json
try:
import simplejson as json ## jlv replaced pickle with json
except ImportError:
import json
import UserDict
##import cPickle as pickle

View File

@ -1,5 +1,8 @@
import simplejson as json
from urlparse import urlparse
try:
import simplejson as json
except ImportError:
import json
import cherrypy
import cfg

View File

@ -7,6 +7,7 @@ from forms import Form
import util as u
from withsqlite.withsqlite import sqlite_db
import cfg
import config
from model import User
class FirstBoot(PagePlugin):
@ -19,18 +20,13 @@ class FirstBoot(PagePlugin):
return self.state0(*args, **kwargs)
## TODO: flesh out these tests values
def valid_box_name_p(self, name):
name = name.strip()
if re.search("\W", name):
return False
return True
def valid_box_key_p(self, key):
return True
def generate_box_key(self):
return "fake key"
@cherrypy.expose
def state0(self, message="", box_name="", box_key="", username="", md5_password="", submitted=False, **kwargs):
def state0(self, message="", hostname="", box_key="", submitted=False, username="", md5_password="", **kwargs):
"""
In this state, we do time config over HTTP, name the box and
server key selection.
@ -50,15 +46,13 @@ class FirstBoot(PagePlugin):
## Must resist the sick temptation to write an LDAP interface to the sqlite file
with sqlite_db(cfg.store_file, table="thisbox", autocommit=True) as db:
db['about'] = "This table is for information about this FreedomBox"
if box_name:
if self.valid_box_name_p(box_name):
db['box_name'] = box_name
if hostname:
if '' == config.valid_hostname(hostname):
config.set_hostname(hostname)
else:
message += _("Invalid box name.")
elif 'box_name' in db and db['box_name']:
box_name = db['box_name']
#TODO: set /etc/hostname to box name via ex machina
message += _("Invalid box name: %s") % config.valid_hostname(hostname)
else:
hostname = config.get_hostname()
if box_key:
if self.valid_box_key_p(box_key):
db['box_key'] = box_key
@ -83,8 +77,7 @@ class FirstBoot(PagePlugin):
else:
validuser = False
if box_name and box_key and self.valid_box_name_p(box_name) and self.valid_box_key_p(box_key) and validuser:
if hostname and box_key and '' == config.valid_hostname(hostname) and self.valid_box_key_p(box_key) and validuser:
## Update state to 1 and head there
with sqlite_db(cfg.store_file, table="firstboot", autocommit=True) as db:
db['state']=1
@ -97,10 +90,8 @@ class FirstBoot(PagePlugin):
name="whats_my_name",
message=message)
form.text = '<script type="text/javascript" src="/static/js/md5.js"></script>\n'+form.text
if not box_name:
box_name = cfg.box_name
form.html("<p>For convenience, your FreedomBox needs a name. It should be something short that doesn't contain spaces or punctuation. 'Willard' would be a good name. 'Freestyle McFreedomBox!!!' would not.</p>")
form.text_input('Name your FreedomBox', id="box_name", value=box_name)
form.text_input('Name your FreedomBox', id="hostname", value=hostname)
form.html("<p><strong>Initial user and password.</strong> Access to this web interface is protected by knowing a username and password. Provide one here to register the initial privileged user. The password can be changed and other users added later.</p>")
form.text_input('Username:', id="username", value=username)
form.text_input('Password:', id="password", type='password')
@ -129,6 +120,15 @@ TODO: explain all this cert stuff to the user.</p>
<p>TODO: add instrux for installing certificate.</p>
<p>After you have installed
"""
# TODO complete first_boot handling
# Make sure the user is not stuck on a dead end for now.
with sqlite_db(cfg.store_file, table="firstboot", autocommit=True) as db:
db['state']=5
main = main + """
<p>Welcome screen not completely implemented yet. Press <a href="/router">continue</a> to
see the rest of the web interface.</p>"
"""
if False:
## Update state to 2 and head there
with sqlite_db(cfg.store_file, table="firstboot", autocommit=True) as db:

View File

@ -1,5 +1,8 @@
import os
import simplejson as json
try:
import simplejson as json
except ImportError:
import json
import cherrypy
import cfg
from model import User
@ -10,13 +13,27 @@ class UserStore(UserStoreModule, sqlite_db):
def __init__(self):
self.data_dir = cfg.users_dir
self.db_file = cfg.user_db
sqlite_db.__init__(self, self.db_file, autocommit=True)
sqlite_db.__init__(self, self.db_file, autocommit=True, check_same_thread=False)
self.__enter__()
def close(self):
self.__exit__(None,None,None)
def current(self, name=False):
"""Return current user, if there is one, else None.
If name = True, return the username instead of the user."""
try:
username = cherrypy.session.get(cfg.session_key)
if name:
return username
else:
return self.get(username)
except AttributeError:
return None
def expert(self, username=None):
if not username:
username = self.current(name=True)
groups = self.attr(username,"groups")
if not groups:
return False

View File

@ -7,7 +7,10 @@ haven't figured that one all the way through yet.
import os, sys
import cherrypy
import simplejson as json
try:
import simplejson as json
except ImportError:
import json
from gettext import gettext as _
from plugin_mount import PagePlugin
from modules.auth import require

View File

@ -1,7 +1,10 @@
import os, subprocess
from socket import gethostname
import cherrypy
import simplejson as json
try:
import simplejson as json
except ImportError:
import json
from gettext import gettext as _
from filedict import FileDict
from modules.auth import require
@ -40,6 +43,9 @@ def valid_hostname(name):
return message
def get_hostname():
return gethostname()
def set_hostname(hostname):
"Sets machine hostname to hostname"
cfg.log.info("Writing '%s' to /etc/hostname with exmachina" % hostname)
@ -53,7 +59,7 @@ def set_hostname(hostname):
if platform.linux_distribution()[0]=="Ubuntu" :
cfg.exmachina.service.start("hostname")
else:
cfg.exmachina.initd.restart("hostname.sh") # is hostname.sh debian-only?
cfg.exmachina.initd.start("hostname.sh") # is hostname.sh debian-only?
except OSError, e:
raise cherrypy.HTTPError(500, "Hostname restart failed: %s" % e)
@ -62,10 +68,6 @@ class general(FormPlugin, PagePlugin):
order = 30
def help(self, *args, **kwargs):
## only expert users are going to get deep enough to see any timestamps
if not cfg.users.expert():
return ''
return _(#"""<strong>Time Zone</strong>
"""<p>Set your timezone to get accurate
timestamps. %(product)s will use this information to set your
@ -73,6 +75,9 @@ class general(FormPlugin, PagePlugin):
""" % {'product':cfg.product_name, 'box':cfg.box_name})
def main(self, message='', **kwargs):
if not cfg.users.expert():
return '<p>' + _('Only members of the expert group are allowed to see and modify the system setup.') + '</p>'
sys_store = filedict_con(cfg.store_file, 'sys')
hostname = cfg.exmachina.augeas.get("/files/etc/hostname/*")
# this layer of persisting configuration in sys_store could/should be

View File

@ -1,6 +1,9 @@
import os
import cherrypy
import simplejson as json
try:
import simplejson as json
except ImportError:
import json
from gettext import gettext as _
from filedict import FileDict
from modules.auth import require

View File

@ -1,6 +1,9 @@
import os
import cherrypy
import simplejson as json
try:
import simplejson as json
except ImportError:
import json
from gettext import gettext as _
from filedict import FileDict
from auth import require

View File

@ -1,6 +1,9 @@
import os
import cherrypy
import simplejson as json
try:
import simplejson as json
except ImportError:
import json
from gettext import gettext as _
from filedict import FileDict
from modules.auth import require

View File

@ -114,9 +114,10 @@ def setup():
pass
try:
from exmachina import ExMachinaClient
from vendor.exmachina.exmachina import ExMachinaClient
except ImportError:
cfg.exmachina = None
print "unable to import exmachina client library, but continuing anyways..."
else:
try:
cfg.exmachina = ExMachinaClient(

View File

@ -5,6 +5,6 @@
export PYTHONPATH
sudo killall exmachina.py
sudo /usr/share/pyshared/exmachina/exmachina.py -v &
sudo vendor/exmachina/exmachina.py -v &
python plinth.py
sudo killall exmachina.py

View File

@ -1,6 +1,5 @@
#! /bin/sh
PYTHONPATH=build/exmachina:$PYTHONPATH
PYTHONPATH=modules/installed/lib:$PYTHONPATH
PYTHONPATH=vendor:$PYTHONPATH