diff --git a/Makefile b/Makefile index 4273b87d2..c9a6b4cdc 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/exmachina/__init__.py b/exmachina/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/fabfile.py b/fabfile.py index 4b4d25410..a9a95d09c 100644 --- a/fabfile.py +++ b/fabfile.py @@ -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 diff --git a/filedict.py b/filedict.py index 1e76d67da..d4f9a35ad 100644 --- a/filedict.py +++ b/filedict.py @@ -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 diff --git a/menu.py b/menu.py index 79f220537..90b0af896 100644 --- a/menu.py +++ b/menu.py @@ -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 diff --git a/modules/installed/first_boot.py b/modules/installed/first_boot.py index b55425981..45ab638bf 100644 --- a/modules/installed/first_boot.py +++ b/modules/installed/first_boot.py @@ -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 = '\n'+form.text - if not box_name: - box_name = cfg.box_name form.html("
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.
") - form.text_input('Name your FreedomBox', id="box_name", value=box_name) + form.text_input('Name your FreedomBox', id="hostname", value=hostname) form.html("Initial user and password. 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.
") 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.TODO: add instrux for installing certificate.
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 + """ +
Welcome screen not completely implemented yet. Press continue to +see the rest of the web interface.
" +""" + if False: ## Update state to 2 and head there with sqlite_db(cfg.store_file, table="firstboot", autocommit=True) as db: diff --git a/modules/installed/lib/user_store.py b/modules/installed/lib/user_store.py index 236b73a8f..52863498a 100644 --- a/modules/installed/lib/user_store.py +++ b/modules/installed/lib/user_store.py @@ -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 diff --git a/modules/installed/santiago/santiago.py b/modules/installed/santiago/santiago.py index 7cf11e538..6d179c50b 100644 --- a/modules/installed/santiago/santiago.py +++ b/modules/installed/santiago/santiago.py @@ -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 diff --git a/modules/installed/system/config.py b/modules/installed/system/config.py index b671fcc12..89d878a35 100644 --- a/modules/installed/system/config.py +++ b/modules/installed/system/config.py @@ -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 _(#"""Time Zone """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 '
' + _('Only members of the expert group are allowed to see and modify the system setup.') + '
' + 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 diff --git a/modules/installed/system/expert_mode.py b/modules/installed/system/expert_mode.py index da8dbc5aa..e69e08bcf 100644 --- a/modules/installed/system/expert_mode.py +++ b/modules/installed/system/expert_mode.py @@ -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 diff --git a/modules/installed/system/system.py b/modules/installed/system/system.py index 68a7a50ff..eba279a90 100644 --- a/modules/installed/system/system.py +++ b/modules/installed/system/system.py @@ -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 diff --git a/modules/installed/system/wan.py b/modules/installed/system/wan.py index 0817f62c4..394f67d6e 100644 --- a/modules/installed/system/wan.py +++ b/modules/installed/system/wan.py @@ -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 diff --git a/plinth.py b/plinth.py index b3ada9d71..e2bd80818 100755 --- a/plinth.py +++ b/plinth.py @@ -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( diff --git a/start.sh b/start.sh index 8e141fcf8..8b97c0bcd 100755 --- a/start.sh +++ b/start.sh @@ -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 diff --git a/test.sh b/test.sh index 4b6f701d4..535f6d408 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,5 @@ #! /bin/sh -PYTHONPATH=build/exmachina:$PYTHONPATH PYTHONPATH=modules/installed/lib:$PYTHONPATH PYTHONPATH=vendor:$PYTHONPATH