コード例 #1
0
ファイル: first_boot.py プロジェクト: copyninja/Plinth
    def state1(self, message=None):
        """
        State 1 is when we have a box name and key.  In this state,
        our task is to provide a certificate and maybe to guide the
        user through installing it.  We automatically move to State 2,
        which is an HTTPS connection.

        TODO: HTTPS failure in State 2 should returns to state 1.
        """
        main = """<p>Here's a certificate.
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:
                db['state']=1
                            #TODO: switch to HTTPS
            raise cherrypy.InternalRedirect('/firstboot/state1')

        return self.fill_template(template="base", title=_("Installing the Certificate"), main=main,
        sidebar_right=_("""<strong>Getting Help</strong><p>We've done our best to make your FreedomBox easy to use.  If you have questions during setup, there are a few places to turn for help. TODO: add links to such help.</p>"""))
コード例 #2
0
def _apply_state0(request, old_state, new_state):
    """Apply changes in state 0 form"""
    success = True
    with sqlite_db(cfg.store_file, table="thisbox", autocommit=True) as \
            database:
        database['about'] = 'Information about this FreedomBox'

        if new_state['box_key']:
            database['box_key'] = new_state['box_key']
        elif not old_state['box_key']:
            database['box_key'] = generate_box_key()

        if old_state['hostname'] != new_state['hostname']:
            config.set_hostname(new_state['hostname'])

        error = add_user(new_state['username'], new_state['password'],
                         'First user, please change', '', True)
        if error:
            messages.error(request,
                           _('User account creation failed: %s') % error)
            success = False
        else:
            messages.success(request, _('User account created'))

    return success
コード例 #3
0
ファイル: first_boot.py プロジェクト: fbxat/Plinth
def _apply_state0(request, old_state, new_state):
    """Apply changes in state 0 form"""
    success = True
    with sqlite_db(cfg.store_file, table="thisbox", autocommit=True) as \
            database:
        database['about'] = 'Information about this FreedomBox'

        if new_state['box_key']:
            database['box_key'] = new_state['box_key']
        elif not old_state['box_key']:
            database['box_key'] = generate_box_key()

        if old_state['hostname'] != new_state['hostname']:
            config.set_hostname(new_state['hostname'])

        error = add_user(new_state['username'], new_state['password'],
                         'First user, please change', '', True)
        if error:
            messages.error(
                request, _('User account creation failed: %s') % error)
            success = False
        else:
            messages.success(request, _('User account created'))

    return success
コード例 #4
0
ファイル: first_boot.py プロジェクト: p1otr/Plinth
    def state1(self, message=None):
        """
        State 1 is when we have a box name and key.  In this state,
        our task is to provide a certificate and maybe to guide the
        user through installing it.  We automatically move to State 2,
        which is an HTTPS connection.

        TODO: HTTPS failure in State 2 should returns to state 1.
        """
        main = """<p>Here's a certificate.
TODO: explain all this cert stuff to the user.</p>
<p>TODO: add instrux for installing certificate.</p>
<p>After you have installed
"""
        if False:
            ## Update state to 2 and head there
            with sqlite_db(cfg.store_file, table="firstboot",
                           autocommit=True) as db:
                db['state'] = 1
                #TODO: switch to HTTPS
            raise cherrypy.InternalRedirect('/firstboot/state1')

        return self.fill_template(
            template="base",
            title=_("Installing the Certificate"),
            main=main,
            sidebar_right=
            _("""<strong>Getting Help</strong><p>We've done our best to make your FreedomBox easy to use.  If you have questions during setup, there are a few places to turn for help. TODO: add links to such help.</p>"""
              ))
コード例 #5
0
    def state1(self, message=None):
        """
        State 1 is when we have a box name and key.  In this state,
        our task is to provide a certificate and maybe to guide the
        user through installing it.  We automatically move to State 2,
        which is an HTTPS connection.

        TODO: HTTPS failure in State 2 should returns to state 1.
        """
        main = """
<p>Welcome screen not completely implemented yet.  Press <a
href="../router">continue</a> to see the rest of the web interface.</p>

<ul>
    <li>TODO: explain all this cert stuff to the user.</li>
    <li>TODO: add instrux for installing certificate.</li>
    <li>TODO: add steps for after you have installed certificate.</li>
<ul>
"""
        # 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

        # TODO: Update state to 2 and head there
        # with sqlite_db(cfg.store_file, table="firstboot", autocommit=True) as db:
        #     db['state']=1
        #     # TODO: switch to HTTPS
        # raise cherrypy.InternalRedirect('state1')

        return self.fill_template(
            template="base",
            title=_("Installing the Certificate"),
            main=main,
            sidebar_right=sidebar_right)
コード例 #6
0
def get_state0():
    """Return the state for form state 0"""
    with sqlite_db(cfg.store_file, table="thisbox", autocommit=True) as \
            database:
        return {
            'hostname': config.get_hostname(),
            'box_key': database.get('box_key', None)
        }
コード例 #7
0
ファイル: plinth.py プロジェクト: copyninja/Plinth
 def index(self):
    ## TODO: firstboot hijacking root should probably be in the firstboot module with a hook in plinth.py
    with sqlite_db(cfg.store_file, table="firstboot") as db:
       if not 'state' in db:
          raise cherrypy.InternalRedirect('/firstboot')
       elif db['state'] < 5:
          cfg.log("First Boot state = %d" % db['state'])
          raise cherrypy.InternalRedirect('/firstboot/state%d' % db['state'])
    if cherrypy.session.get(cfg.session_key, None):
       raise cherrypy.InternalRedirect('/router')
    else:
       raise cherrypy.InternalRedirect('/help/about')
コード例 #8
0
 def index(self):
     ## TODO: firstboot hijacking root should probably be in the firstboot module with a hook in plinth.py
     with sqlite_db(cfg.store_file, table="firstboot") as db:
         if not 'state' in db:
             raise cherrypy.InternalRedirect('/firstboot')
         elif db['state'] < 5:
             cfg.log("First Boot state = %d" % db['state'])
             raise cherrypy.InternalRedirect('/firstboot/state%d' %
                                             db['state'])
     if cherrypy.session.get(cfg.session_key, None):
         raise cherrypy.InternalRedirect('/router')
     else:
         raise cherrypy.InternalRedirect('/help/about')
コード例 #9
0
    def process_request(self, request):
        # TODO: there should be a better way to tell if we're at the
        # firstboot module
        if "firstboot" not in request.path:
            with sqlite_db(cfg.store_file, table='firstboot') as database:
                first_boot_url = reverse('first_boot:index')
                if 'state' not in database:
                    # Permanent redirect causes the browser to cache the
                    # redirect, preventing the user from navigating to /plinth
                    # until the browser is restarted.
                    return HttpResponseRedirect(first_boot_url)

                elif database['state'] < 5:
                    LOGGER.info('First boot state - %d', database['state'])
                    return HttpResponseRedirect(
                        reverse('first_boot:state%d' % database['state']))
コード例 #10
0
ファイル: middleware.py プロジェクト: fbxat/Plinth
    def process_request(self, request):
        # TODO: there should be a better way to tell if we're at the
        # firstboot module
        if "firstboot" not in request.path:
            with sqlite_db(cfg.store_file, table='firstboot') as database:
                first_boot_url = reverse('first_boot:index')
                if 'state' not in database:
                    # Permanent redirect causes the browser to cache the
                    # redirect, preventing the user from navigating to /plinth
                    # until the browser is restarted.
                    return HttpResponseRedirect(first_boot_url)

                elif database['state'] < 5:
                    LOGGER.info('First boot state - %d', database['state'])
                    return HttpResponseRedirect(reverse('first_boot:state%d' %
                                                        database['state']))
コード例 #11
0
 def index(self):
    ## TODO: firstboot hijacking root should probably be in the firstboot module with a hook in plinth.py
    with sqlite_db(cfg.store_file, table="firstboot") as db:
       if not 'state' in db:
          # if we created a new user db, make sure it can't be read by everyone
          userdb_fname = '{}.sqlite3'.format(cfg.user_db)
          os.chmod(userdb_fname, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP)
          # cherrypy.InternalRedirect throws a 301, causing the
          # browser to cache the redirect, preventing the user from
          # navigating to /plinth until the browser is restarted.
          raise cherrypy.HTTPRedirect('firstboot', 307)
       elif db['state'] < 5:
          cfg.log("First Boot state = %d" % db['state'])
          raise cherrypy.InternalRedirect('firstboot/state%d' % db['state'])
    if cherrypy.session.get(cfg.session_key, None):
       raise cherrypy.InternalRedirect('router')
    else:
       raise cherrypy.InternalRedirect('help/about')
コード例 #12
0
    def state0(self, message="", hostname="", box_key="", submitted=False, username="", password="", **kwargs):
        """
        In this state, we do time config over HTTP, name the box and
        server key selection.

        All the parameters are form inputs.  They get passed in when
        the form is submitted.  This method checks the inputs and if
        they validate, uses them to take action.  If they do not
        validate, it displays the form to give the user a chance to
        input correct values.  It might display an error message (in
        the message parameter).

        message is an optional string that we can display to the
        user. It's a good place to put error messages.
        """

        # FIXME: reject connection attempt if db["state"] >= 5.

        ## Until LDAP is in place, we'll put the box name and key in the cfg.store_file
        ## 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 hostname:
                if '' == config.valid_hostname(hostname):
                    config.set_hostname(hostname)
                else:
                    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
                else:
                    message += _("Invalid key!")
            elif 'box_key' in db and db['box_key']:
                box_key = _("We already have a key for this box on file.") # TODO: Think this through and handle more gracefully.  Seriously.
            elif submitted and not box_key:
                box_key = self.generate_box_key()
                db['box_key'] = box_key
            if username and password:
                error = add_user(username, password, 'First user - please change', '', True)
                if error:
                    message += _("User account creation failed: %s") % error
                    validuser = False
                else:
                    validuser = True
            else:
                validuser = False

        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
            raise cherrypy.InternalRedirect('state1')

        main = "<p>Welcome.  It looks like this FreedomBox isn't set up yet.  We'll need to ask you a just few questions to get started.</p>"
        form = Form(title="Welcome to Your FreedomBox!",
                        action="", # stay at firstboot
                        name="whats_my_name",
                        message=message)
        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="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:'******'Password:'******'password')
        form.html("<p>%(box_name)s uses cryptographic keys so it can prove its identity when talking to you.  %(box_name)s can make a key for itself, but if one already exists (from a prior FreedomBox, for example), you can paste it below.  This key should not be the same as your key because you are not your FreedomBox!</p>" % {'box_name':cfg.box_name})
        form.text_box("If you want, paste your box's key here.", id="box_key", value=box_key)
        form.hidden(name="submitted", value="True")
        form.submit("Box it up!")

        main += form.render()
        return self.fill_template(
            template="base",
            title=_("First Boot!"),
            main=main,
            sidebar_right=sidebar_right)
コード例 #13
0
ファイル: first_boot.py プロジェクト: p1otr/Plinth
    def state0(self, message="", box_name="", box_key="", submitted=False):
        """
        In this state, we do time config over HTTP, name the box and
        server key selection.

        All the parameters are form inputs.  They get passed in when
        the form is submitted.  This method checks the inputs and if
        they validate, uses them to take action.  If they do not
        validate, it displays the form to give the user a chance to
        input correct values.  It might display an error message (in
        the message parameter).

        message is an optional string that we can display to the
        user. It's a good place to put error messages.
        """

        ## Until LDAP is in place, we'll put the box name and key in the cfg.store_file
        ## 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
                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

            if box_key:
                if self.valid_box_key_p(box_key):
                    db['box_key'] = box_key
                else:
                    message += _("Invalid key!")
            elif 'box_key' in db and db['box_key']:
                box_key = _(
                    "We already have a key for this box on file."
                )  #TODO: Think this through and handle more gracefully
            elif submitted and not box_key:
                box_key = self.generate_box_key()
                db['box_key'] = box_key

        if box_name and box_key and self.valid_box_name_p(
                box_name) and self.valid_box_key_p(box_key):
            ## Update state to 1 and head there
            with sqlite_db(cfg.store_file, table="firstboot",
                           autocommit=True) as db:
                db['state'] = 1
            raise cherrypy.InternalRedirect('/firstboot/state1')

        main = "<p>Welcome.  It looks like this FreedomBox isn't set up yet.  We'll need to ask you a just few questions to get started.</p>"
        form = Form(title="Welcome to Your FreedomBox!",
                    action="/firstboot",
                    name="whats_my_name",
                    message=message)
        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.html(
            "<p>%(box_name)s uses cryptographic keys so it can prove its identity when talking to you.  %(box_name)s can make a key for itself, but if one already exists (from a prior FreedomBox, for example), you can paste it below.  This key should not be the same as your key because you are not your FreedomBox!</p>"
            % {'box_name': cfg.box_name})
        form.text_box("If you want, paste your box's key here.",
                      id="box_key",
                      value=box_key)
        form.hidden(name="submitted", value="True")
        form.submit("Box it up!")

        main += form.render()
        return self.fill_template(
            template="base",
            title=_("First Boot!"),
            main=main,
            sidebar_right=
            _("""<strong>Getting Help</strong><p>We've done our best to make your FreedomBox easy to use.  If you have questions during setup, there are a few places to turn for help. TODO: add links to such help.</p>"""
              ))
コード例 #14
0
def _read_state():
    """Read the current state from database"""
    with sqlite_db(cfg.store_file, table='firstboot',
                   autocommit=True) as database:
        return database['state']
コード例 #15
0
ファイル: first_boot.py プロジェクト: p1otr/Plinth
    def state0(self, message="", box_name="", box_key="", submitted=False):
        """
        In this state, we do time config over HTTP, name the box and
        server key selection.

        All the parameters are form inputs.  They get passed in when
        the form is submitted.  This method checks the inputs and if
        they validate, uses them to take action.  If they do not
        validate, it displays the form to give the user a chance to
        input correct values.  It might display an error message (in
        the message parameter).

        message is an optional string that we can display to the
        user. It's a good place to put error messages.
        """

        ## Until LDAP is in place, we'll put the box name and key in the cfg.store_file
        ## 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
                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

            if box_key: 
                if self.valid_box_key_p(box_key):
                    db['box_key'] = box_key
                else:
                    message += _("Invalid key!")
            elif 'box_key' in db and db['box_key']:
                box_key = _("We already have a key for this box on file.") #TODO: Think this through and handle more gracefully
            elif submitted and not box_key:
                box_key = self.generate_box_key()
                db['box_key'] = box_key


        if box_name and box_key and self.valid_box_name_p(box_name) and self.valid_box_key_p(box_key):
            ## Update state to 1 and head there
            with sqlite_db(cfg.store_file, table="firstboot", autocommit=True) as db:
                db['state']=1
            raise cherrypy.InternalRedirect('/firstboot/state1')

        main = "<p>Welcome.  It looks like this FreedomBox isn't set up yet.  We'll need to ask you a just few questions to get started.</p>"
        form = Form(title="Welcome to Your FreedomBox!", 
                        action="/firstboot", 
                        name="whats_my_name",
                        message=message)
        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.html("<p>%(box_name)s uses cryptographic keys so it can prove its identity when talking to you.  %(box_name)s can make a key for itself, but if one already exists (from a prior FreedomBox, for example), you can paste it below.  This key should not be the same as your key because you are not your FreedomBox!</p>" % {'box_name':cfg.box_name})
        form.text_box("If you want, paste your box's key here.", id="box_key", value=box_key)
        form.hidden(name="submitted", value="True")
        form.submit("Box it up!")

        main += form.render()
        return self.fill_template(template="base", title=_("First Boot!"), main=main,
        sidebar_right=_("""<strong>Getting Help</strong><p>We've done our best to make your FreedomBox easy to use.  If you have questions during setup, there are a few places to turn for help. TODO: add links to such help.</p>"""))
コード例 #16
0
ファイル: first_boot.py プロジェクト: fbxat/Plinth
def _write_state(state):
    """Write state to database"""
    with sqlite_db(cfg.store_file, table='firstboot',
                   autocommit=True) as database:
        database['state'] = state
コード例 #17
0
ファイル: first_boot.py プロジェクト: fbxat/Plinth
def _read_state():
    """Read the current state from database"""
    with sqlite_db(cfg.store_file, table='firstboot',
                   autocommit=True) as database:
        return database['state']
コード例 #18
0
def _write_state(state):
    """Write state to database"""
    with sqlite_db(cfg.store_file, table='firstboot',
                   autocommit=True) as database:
        database['state'] = state
コード例 #19
0
ファイル: first_boot.py プロジェクト: fbxat/Plinth
def get_state0():
    """Return the state for form state 0"""
    with sqlite_db(cfg.store_file, table="thisbox", autocommit=True) as \
            database:
        return {'hostname': config.get_hostname(),
                'box_key': database.get('box_key', None)}