Merge additional changes in fonfon/dev branch

- Remove duplicate fix for firstboot redirection
- Remove duplicate adding of actions_dir to cfg.py
- Capitalize global variable in module_loader.py
- Minor refactoring while adding app specific static directories
This commit is contained in:
Sunil Mohan Adapa 2014-08-17 20:33:58 +05:30
commit 7ff3742f73
6 changed files with 37 additions and 176 deletions

View File

@ -29,6 +29,8 @@ import cfg
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
LOADED_MODULES = []
def load_modules(): def load_modules():
""" """
@ -71,6 +73,7 @@ def load_modules():
for module_name in ordered_modules: for module_name in ordered_modules:
_initialize_module(modules[module_name]) _initialize_module(modules[module_name])
LOADED_MODULES.append(module_name)
def _insert_modules(module_name, module, remaining_modules, ordered_modules): def _insert_modules(module_name, module, remaining_modules, ordered_modules):

View File

@ -104,6 +104,21 @@ def setup_server():
'tools.staticdir.dir': '.'}} 'tools.staticdir.dir': '.'}}
cherrypy.tree.mount(None, django.conf.settings.STATIC_URL, config) cherrypy.tree.mount(None, django.conf.settings.STATIC_URL, config)
# TODO: our modules are mimicking django apps. It'd be better to convert
# our modules to Django apps instead of reinventing the wheel.
# (we'll still have to serve the static files with cherrypy though)
for module in module_loader.LOADED_MODULES:
static_dir = os.path.join(cfg.file_root, 'modules', module, 'static')
if not os.path.isdir(static_dir):
continue
config = {
'/': {'tools.staticdir.root': static_dir,
'tools.staticdir.on': True,
'tools.staticdir.dir': '.'}}
urlprefix = "%s%s" % (django.conf.settings.STATIC_URL, module)
cherrypy.tree.mount(None, urlprefix, config)
if not cfg.no_daemon: if not cfg.no_daemon:
Daemonizer(cherrypy.engine).subscribe() Daemonizer(cherrypy.engine).subscribe()

View File

@ -47,6 +47,8 @@
<!-- CSS from previous Plinth template, not sure what to keep yet --> <!-- CSS from previous Plinth template, not sure what to keep yet -->
{{ css|safe }} {{ css|safe }}
<!-- End Plinth CSS --> <!-- End Plinth CSS -->
{% block app_head %}<!-- placeholder for app/module-specific head files -->{% endblock %}
{% block page_head %}<!-- placeholder for page-specific head files -->{% endblock %}
</head> </head>
<body> <body>
<!--[if lt IE 7]><p class=chromeframe>Your browser is <em>ancient!</em> <a href="http://mozilla.org/firefox">Upgrade to a modern version of Firefox</a> to experience this site.</p><![endif]--> <!--[if lt IE 7]><p class=chromeframe>Your browser is <em>ancient!</em> <a href="http://mozilla.org/firefox">Upgrade to a modern version of Firefox</a> to experience this site.</p><![endif]-->
@ -169,5 +171,7 @@
{% block js_block %} {% block js_block %}
{{ js|safe }} {{ js|safe }}
{% endblock %} {% endblock %}
{% block app_js %}<!-- placeholder for app-specific js files -->{% endblock %}
{% block page_js %}<!-- placeholder for page-specific js files -->{% endblock %}
</body> </body>
</html> </html>

View File

@ -7,6 +7,11 @@ import shlex
import subprocess import subprocess
import unittest import unittest
import cfg
ROOT_DIR = os.path.split(os.path.abspath(os.path.split(__file__)[0]))[0]
cfg.actions_dir = os.path.join(ROOT_DIR, 'actions')
class TestPrivileged(unittest.TestCase): class TestPrivileged(unittest.TestCase):
"""Verify that privileged actions perform as expected. """Verify that privileged actions perform as expected.
@ -25,10 +30,9 @@ class TestPrivileged(unittest.TestCase):
os.remove("actions/echo") os.remove("actions/echo")
os.remove("actions/id") os.remove("actions/id")
def test_run_as_root(self): def notest_run_as_root(self):
"""1. Privileged actions run as root. """1. Privileged actions run as root. """
# TODO: it's not allowed to call a symlink in the actions dir anymore
"""
self.assertEqual( self.assertEqual(
"0", # user 0 is root "0", # user 0 is root
superuser_run("id", "-ur")[0].strip()) superuser_run("id", "-ur")[0].strip())
@ -75,45 +79,33 @@ class TestPrivileged(unittest.TestCase):
for option in options: for option in options:
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
output = run(action, option) output = run(action, option)
# if it somewhow doesn't error, we'd better not evaluate
# if it somewhow doesn't error, we'd better not evaluate the # the data.
# data.
self.assertFalse("2" in output[0]) self.assertFalse("2" in output[0])
def test_breakout_option_string(self): def test_breakout_option_string(self):
"""3D. Option strings can't be used to run other actions. """3D. Option strings can't be used to run other actions.
Verify that shell control characters aren't interpreted. Verify that shell control characters aren't interpreted.
""" """
action = "echo" action = "echo"
# counting is safer than actual badness. # counting is safer than actual badness.
options = "good; echo $((1+1))" options = "good; echo $((1+1))"
self.assertRaises(ValueError, run, action, options)
output = run(action, options)
self.assertFalse("2" in output)
def test_breakout_option_list(self): def test_breakout_option_list(self):
"""3D. Option lists can't be used to run other actions. """3D. Option lists can't be used to run other actions.
Verify that only a string of options is accepted and that we can't just Verify that only a string of options is accepted and that we can't just
tack additional shell control characters onto the list. tack additional shell control characters onto the list.
""" """
action = "echo" action = "echo"
# counting is safer than actual badness. # counting is safer than actual badness.
options = ["good", ";", "echo $((1+1))"] options = ["good", ";", "echo $((1+1))"]
output = run(action, options)
# we'd better not evaluate the data. # we'd better not evaluate the data.
self.assertFalse("2" in output) self.assertRaises(ValueError, run, action, options)
def test_multiple_options(self): def notest_multiple_options(self):
"""4. Multiple options can be provided as a list. """ 4. Multiple options can be provided as a list. """
# TODO: it's not allowed to call a symlink in the actions dir anymore
"""
self.assertEqual( self.assertEqual(
subprocess.check_output(shlex.split("id -ur")).strip(), subprocess.check_output(shlex.split("id -ur")).strip(),
run("id", ["-u" ,"-r"])[0].strip()) run("id", ["-u" ,"-r"])[0].strip())

View File

@ -1,67 +0,0 @@
#! /usr/bin/env python
# -*- mode: python; mode: auto-fill; fill-column: 80 -*-
import auth
from logger import Logger
import cfg
import unittest
import cherrypy
import plugin_mount
import os
cfg.log = Logger()
cherrypy.log.access_file = None
class Auth(unittest.TestCase):
"""Test check_credentials function of auth to confirm it works as expected"""
def setUp(self):
cfg.user_db = os.path.join(cfg.file_root, "tests/testdata/users");
cfg.users = plugin_mount.UserStoreModule.get_plugins()[0]
def tearDown(self):
for user in cfg.users.get_all():
cfg.users.remove(user[0])
cfg.users.close()
def test_add_user(self):
self.assertIsNone(auth.add_user("test_user", "password"))
self.assertIsNotNone(auth.add_user(None, "password"))
self.assertIsNotNone(auth.add_user("test_user", None))
self.assertIsNotNone(auth.add_user("test_user", "password"))
def test_password_check(self):
auth.add_user("test_user", "password")
# check_credentials returns None if there is no error,
# or returns error string
self.assertIsNone(auth.check_credentials("test_user", "password"))
self.assertIsNotNone(auth.check_credentials("test_user", "wrong"))
def test_nonexistent_user(self):
self.assertIsNotNone(auth.check_credentials("test_user", "password"))
def test_password_too_long(self):
password = "x" * 4097
self.assertIsNotNone(auth.add_user("test_user", password))
self.assertIsNotNone(auth.check_credentials("test_user", password))
def test_salt_is_random(self):
auth.add_user("test_user1", "password")
auth.add_user("test_user2", "password")
self.assertNotEqual(
cfg.users["test_user1"]["salt"],
cfg.users["test_user2"]["salt"]
)
def test_hash_is_random(self):
auth.add_user("test_user1", "password")
auth.add_user("test_user2", "password")
self.assertNotEqual(
cfg.users["test_user1"]["passphrase"],
cfg.users["test_user2"]["passphrase"]
)
if __name__ == "__main__":
unittest.main()

View File

@ -1,86 +0,0 @@
#! /usr/bin/env python
# -*- mode: python; mode: auto-fill; fill-column: 80 -*-
from logger import Logger
import cfg
import unittest
import cherrypy
import plugin_mount
import os
from model import User
cfg.log = Logger()
cherrypy.log.access_file = None
class UserStore(unittest.TestCase):
"""Test each function of user_store to confirm they work as expected"""
def setUp(self):
cfg.user_db = os.path.join(cfg.file_root, "tests/testdata/users");
self.userstore = plugin_mount.UserStoreModule.get_plugins()[0]
def tearDown(self):
for user in self.userstore.get_all():
self.userstore.remove(user[0])
self.userstore.close()
def test_user_does_not_exist(self):
self.assertEqual(self.userstore.exists("notausername"),False)
def test_user_does_exist(self):
self.add_user("isausername", False)
self.assertEqual(self.userstore.exists("isausername"),True)
def test_add_user(self):
self.assertEqual(len(self.userstore.items()),0)
self.add_user("test_user", False)
self.assertEqual(len(self.userstore.items()),1)
def test_user_is_in_expert_group(self):
self.add_user("test_user", True)
self.assertEqual(self.userstore.expert("test_user"),True)
def test_user_is_not_in_expert_group(self):
self.add_user("test_user", False)
self.assertEqual(self.userstore.expert("test_user"),False)
def test_user_removal(self):
self.assertEqual(len(self.userstore.items()),0)
self.add_user("test_user", False)
self.assertEqual(len(self.userstore.items()),1)
self.userstore.remove("test_user")
self.assertEqual(len(self.userstore.items()),0)
def test_get_user_email_attribute(self):
self.add_user("test_user", False,"test@home")
self.assertEqual(self.userstore.attr("test_user","email"),"test@home")
def test_get_user(self):
test_user = self.add_user("test_user", False)
self.assertEqual(self.userstore.get("test_user"),test_user)
def test_get_all_users(self):
self.add_user("test_user1", False)
self.add_user("test_user2", False)
self.assertEqual(len(self.userstore.get_all()),2)
def add_user(self, test_username, add_to_expert_group, email=''):
test_user = self.create_user(test_username, email)
if add_to_expert_group:
test_user = self.add_user_to_expert_group(test_user)
self.userstore.set(test_username,test_user)
return test_user
def create_user(self, username, email=''):
test_user = User()
test_user["username"] = username
test_user["email"] = email
return test_user
def add_user_to_expert_group(self, user):
user["groups"] = ["expert"]
return user
if __name__ == "__main__":
unittest.main()