Permalink
Browse files

Merge branch 'nimbus-upstream-rest' of git://github.com/clemesha-ooi/…

…nimbus into rest
  • Loading branch information...
2 parents 212a757 + cd2b2a8 commit 04818a7ea8727d14d8d97848bf60db47dcb6fe54 @labisso labisso committed Feb 23, 2010
Showing with 482 additions and 25 deletions.
  1. +1 −0 .gitignore
  2. 0 web/lib/java/nimbusweb.empty.marker
  3. 0 web/lib/python/cherrypy/nimbusweb.empty.marker
  4. +3 −0 web/nimbusweb.conf
  5. +4 −1 web/src/python/nimbusrest/connection.py
  6. +4 −1 web/src/python/nimbusrest/error.py
  7. +28 −0 web/src/python/nimbusrest/tests.py
  8. +2 −1 web/src/python/nimbusweb/portal/nimbus/adminops.py
  9. +8 −1 web/src/python/nimbusweb/portal/nimbus/models.py
  10. +41 −0 web/src/python/nimbusweb/portal/nimbus/remote.py
  11. +45 −16 web/src/python/nimbusweb/portal/nimbus/tests.py
  12. +2 −0 web/src/python/nimbusweb/portal/settings.py
  13. +27 −1 web/src/python/nimbusweb/portal/static/base.css
  14. +1 −0 web/src/python/nimbusweb/portal/templates/404.html
  15. +1 −0 web/src/python/nimbusweb/portal/templates/500.html
  16. +2 −1 web/src/python/nimbusweb/portal/templates/base.html
  17. +13 −0 web/src/python/nimbusweb/portal/templates/usercreate/index.html
  18. +12 −0 web/src/python/nimbusweb/portal/templates/usercreate/method.html
  19. +8 −0 web/src/python/nimbusweb/portal/templates/usercreate/success.html
  20. +1 −0 web/src/python/nimbusweb/portal/urls.py
  21. +19 −0 web/src/python/nimbusweb/portal/usercreate/README
  22. 0 web/{lib/python/django/nimbusweb.empty.marker → src/python/nimbusweb/portal/usercreate/__init__.py}
  23. +81 −0 web/src/python/nimbusweb/portal/usercreate/create.py
  24. +16 −0 web/src/python/nimbusweb/portal/usercreate/forms.py
  25. +7 −0 web/src/python/nimbusweb/portal/usercreate/urls.py
  26. +16 −0 web/src/python/nimbusweb/portal/usercreate/util.py
  27. +107 −0 web/src/python/nimbusweb/portal/usercreate/views.py
  28. +4 −1 web/src/python/nimbusweb/setup/newconf.py
  29. +3 −2 web/src/python/nimbusweb/setup/setup.py
  30. +26 −0 web/src/python/run-tests.sh
View
1 .gitignore
@@ -2,6 +2,7 @@
*.iml
*.ipr
*.iws
+*.swp
build/
dist/
autocontainer/downloads/
View
0 web/lib/java/nimbusweb.empty.marker
No changes.
View
0 web/lib/python/cherrypy/nimbusweb.empty.marker
No changes.
View
3 web/nimbusweb.conf
@@ -12,6 +12,9 @@
ssl.cert: var/sslcert.pem
ssl.key: var/sslkey.pem
+# CA dir
+
+ca.dir: var/ca
# Port to run the standalone webserver on.
View
5 web/src/python/nimbusrest/connection.py
@@ -16,7 +16,10 @@
from urlparse import urljoin
import httplib2
-import json
+try:
+ import json
+except ImportError:
+ import simplejson as json
from nimbusrest.error import NimbusServerError, NotFoundError, ConflictError
View
5 web/src/python/nimbusrest/error.py
@@ -16,7 +16,10 @@
Nimbus exception types. Subclassed for specific errors
"""
-import json
+try:
+ import json
+except ImportError:
+ import simplejson as json
class NimbusClientError(Exception):
"""
View
28 web/src/python/nimbusrest/tests.py
@@ -0,0 +1,28 @@
+import unittest
+from nimbusrest.admin.connection import AdminConnection
+
+
+class FakeUser(object):
+ id = 1
+ dn = "test_dn"
+
+class TestNimbusRestClient(unittest.TestCase):
+
+ def setUp(self):
+ self.user = FakeUser()
+ self.uri = "https://localhost:4443/admin"
+ self.key = "testadmin"
+ self.secret = "secret"
+ self.conn = AdminConnection(self.uri, self.key, self.secret)
+
+ def test_add_user_has_key_secret(self):
+ resp = self.conn.add_user(self.user)
+ self.assertEquals(resp.dn, "test_dn")
+ user_id = resp.user_id
+ access_key = self.conn.generate_user_access_key(user_id)
+ self.assertTrue(hasattr(access_key, "secret"))
+ self.assertEquals(access_key.key, user_id)
+
+
+if __name__ == '__main__':
+ unittest.main()
View
3 web/src/python/nimbusweb/portal/nimbus/adminops.py
@@ -151,7 +151,8 @@ def _newuser(newuserform, request_files):
# were successfully used which does not make sense, they should only be
# filled in to help the user re-enter content when there is an error.
return (None, noerror_flash_msg, None)
-
+
+
def ok_token_attempt(ipaddress, maxcount):
"""Return False if this IP has submitted too many tokens"""
try:
View
9 web/src/python/nimbusweb/portal/nimbus/models.py
@@ -1,5 +1,7 @@
+import sys
from django.db import models
from django.contrib.auth.models import User, UserManager
+import remote
class TokenFailure(models.Model):
ip = models.IPAddressField(primary_key=True)
@@ -25,9 +27,14 @@ class UserProfile(models.Model):
certkey_time = models.DateTimeField(auto_now=False, null=True)
query_id = models.TextField(null=True)
query_secret = models.TextField(null=True)
+ nimbus_userid = models.TextField(null=True)
-# register userprofile with the django auth system
+
def user_post_save(sender, instance, **kwargs):
profile, new = UserProfile.objects.get_or_create(user=instance)
models.signals.post_save.connect(user_post_save, User)
+def user_post_delete(sender, instance, **kwargs):
+ profile = UserProfile.objects.get_or_create(user=instance)
+ profile.delete()
+models.signals.post_delete.connect(user_post_delete, User)
View
41 web/src/python/nimbusweb/portal/nimbus/remote.py
@@ -0,0 +1,41 @@
+import sys
+from django.conf import settings
+from nimbusrest.admin.connection import AdminConnection
+import models
+
+
+def nimbus_user_create_remote(user_instance, nimbus_key=None, nimbus_secret=None):
+ """Use the Nimbus API to register a new Nimbus User.
+
+ `user_instance` is a `Django User` instance.
+ """
+ service_uri = getattr(settings, "NIMBUS_SERVICE_URI", None)
+ conn = AdminConnection(service_uri, nimbus_key, nimbus_secret)
+ nimbus_user = conn.add_user(user_instance)
+ return nimbus_user
+
+def nimbus_user_create(sender, instance, **kwargs):
+ """Django User model `post_save` function.
+
+ Save response data from a successful `Nimbus User`
+ creation attempt, or, in the case of failure, remove
+ the recently created `Django User` and send failure
+ message back to User create Form.
+
+ Notes:
+ - Only attempt to create Nimbus User on Django User creation.
+ """
+ if kwargs.get('created') and instance.id != 1:
+ remote_user_creator = kwargs.get("remote_user_creator")
+ if remote_user_creator is None:
+ remote_user_creator = nimbus_user_create_remote
+ try:
+ nimbus_user = remote_user_creator(instance)
+ except:
+ #Nimbus User failed to be created, delete Django User
+ instance.delete() #XXX how to handle this?
+ raise Exception(sys.exc_info())
+ up, created = models.UserProfile.objects.get_or_create(user=instance)
+ up.nimbus_userid = nimbus_user.user_id
+ up.save()
+ return True
View
61 web/src/python/nimbusweb/portal/nimbus/tests.py
@@ -1,23 +1,52 @@
-"""
-This file demonstrates two different styles of tests (one doctest and one
-unittest). These will both pass when you run "manage.py test".
+import unittest
+from django.test import TestCase
-Replace these with more appropriate tests for your application.
-"""
+from django.contrib.auth.models import User
+from django.conf import settings
-from django.test import TestCase
+#from nimbusrest.admin import User as NimbusUser
+import remote
-class SimpleTest(TestCase):
- def test_basic_addition(self):
- """
- Tests that 1 + 1 always equals 2.
+class FakeNimbusUser(object):
+ user_id = "test_nimbus_userid"
+
+class CreateNimbusUserTest(unittest.TestCase):
+
+ def setUp(self):
+ self.django_user = User.objects.create_user("test_username", "test@email.com", "test_password")
+ self.nimbus_user = FakeNimbusUser()
+ self.fail = False
+ self.passthrough = lambda x:x
+
+ def _fake_remote_user_creator(self, user_instance):
+ """Creator real request, fake response and failure states.
+
+ Get necessary data from `user_instance` to form a correct
+ request to create a remote Nimbus User.
"""
- self.failUnlessEqual(1 + 1, 2)
+ if not self.fail:
+ return self.nimbus_user
+ else:
+ raise Exception("fake error in '_fake_remote_user_creator'")
-__test__ = {"doctest": """
-Another way to test that 1 + 1 is equal to 2.
+ def test_create_user(self):
+ """
+ """
+ created = remote.nimbus_user_create(self.passthrough, self.django_user, created=True,
+ remote_user_creator=self._fake_remote_user_creator)
+ user = User.objects.get(username="test_username")
+ self.assertEquals(user.username, "test_username")
+ self.django_user.delete()
->>> 1 + 1 == 2
-True
-"""}
+ def test_create_user_failed(self):
+ #test that User rollback is successful.
+ self.fail = True
+ try:
+ created = remote.nimbus_user_create(self.passthrough, self.django_user, created=True,
+ remote_user_creator=self._fake_remote_user_creator)
+ except:
+ pass
+ user = User.objects.filter(username="test_username")
+ #make sure the User does not exist
+ self.assertEquals(len(user), 0)
View
2 web/src/python/nimbusweb/portal/settings.py
@@ -5,6 +5,7 @@
import sys
here = lambda x: os.path.join(os.path.abspath(os.path.dirname(__file__)), x)
+WEBDIR = here("../../../../")
# ------------------------------------------------------------------------------
@@ -65,6 +66,7 @@
'django.contrib.sites',
'cpserver',
'nimbusweb.portal.nimbus',
+ 'nimbusweb.portal.usercreate',
)
AUTH_PROFILE_MODULE = 'nimbus.UserProfile'
View
28 web/src/python/nimbusweb/portal/static/base.css
@@ -211,4 +211,30 @@ div.lrow span.finput {
float: right;
width: 250px;
text-align: left;
-}
+}
+
+ul#createmethods {
+ text-align:center;
+}
+ul#createmethods li {
+ list-style:none;
+ margin:25px 200px;
+ padding:4px 0px;
+ background-color:#f5f5f5;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ -moz-box-shadow:0 0 6px #888;
+ -webkit-box-shadow:0 0 8px #888;
+
+}
+ul#createmethods p {
+ margin:2px;
+}
+p.method {
+ color:#000;
+ font-size:125%;
+}
+p.details {
+ color:#8f8f8f;
+ font-size:75%;
+}
View
1 web/src/python/nimbusweb/portal/templates/404.html
@@ -0,0 +1 @@
+<p><center><b>Not Found (404)</b></center></p>
View
1 web/src/python/nimbusweb/portal/templates/500.html
@@ -0,0 +1 @@
+<p><center><b>Internal Error (500)</b></center></p>
View
3 web/src/python/nimbusweb/portal/templates/base.html
@@ -17,6 +17,7 @@
<!--[if IE 6]>
<link rel="stylesheet" type="text/css" href="/static/ie6.0.3.css" media="screen, projection" />
<![endif]-->
+ {% block extrahead %}{% endblock %}
</head>
<body id="home">
@@ -46,7 +47,7 @@
</footer>
<!-- JS link will go here -->
-
+ {% block extrafooter %}{% endblock %}
</body>
</html>
View
13 web/src/python/nimbusweb/portal/templates/usercreate/index.html
@@ -0,0 +1,13 @@
+
+{% extends "base.html" %}
+ {% block title %}Create a new User{% endblock %}
+{% block content %}
+ <h1>Create a new User.</h1>
+ <h3>Please choose one of the following methods:</h3>
+ <ul id="createmethods">
+ {% for path, method, details in createmethods %}
+ <li><a href="{{ path }}"><p class="method">{{ method }}</p><p class="details">{{ details }}</p></a></li>
+ {% endfor %}
+ </ul>
+
+{% endblock %}
View
12 web/src/python/nimbusweb/portal/templates/usercreate/method.html
@@ -0,0 +1,12 @@
+
+{% extends "base.html" %}
+ {% block title %}Create a new User{% endblock %}
+{% block content %}
+ <a href="../">&laquo;&nbsp;Back to User create options</a>
+ <h3>{{ methodinfo }}</h3>
+ <form enctype="multipart/form-data" method="post" action="">
+ {{ form.as_p }}
+ <input type="submit" value="Create User">
+ </form>
+
+{% endblock %}
View
8 web/src/python/nimbusweb/portal/templates/usercreate/success.html
@@ -0,0 +1,8 @@
+{% extends "base.html" %}
+ {% block title %}New User successfully created{% endblock %}
+{% block content %}
+
+ <h3>New User successfully created</h3>
+ <p>Email the following registration link to the new User: <pre>{{ url }}{{ token }}</pre></p>
+
+{% endblock %}
View
1 web/src/python/nimbusweb/portal/urls.py
@@ -11,6 +11,7 @@
(r'^$', "nimbusweb.portal.welcome.views.index"),
(r'^admin/', include(admin.site.urls)),
(r'^nimbus/', include("nimbusweb.portal.nimbus.urls")),
+ (r'^usercreate/', include("nimbusweb.portal.usercreate.urls")),
)
_media_url = settings.MEDIA_URL
View
19 web/src/python/nimbusweb/portal/usercreate/README
@@ -0,0 +1,19 @@
+Django app soley for handling Nimbus/Django User creation scenarios.
+====================================================================
+
+User Create Scenarios:
+----------------------
+ 1. "Provide User's Cert and Key files".
+ - details: Upload them, extract DN for cert, do nimbus rest call to create user.
+
+ 2. "Provide User's DN"
+ - details: "The User has a trusted certificate, I have the User's DN"
+
+ 3. "Auto-create a new certificate"
+ - details: "The embedded CA will be used to create a new certificate"
+
+
+
+Success of any of the 3 steps should end in a unique url,
+to be emailed to the User, so they can log in a verify/add
+the rest of the needed info.
View
0 web/lib/python/django/nimbusweb.empty.marker → ...n/nimbusweb/portal/usercreate/__init__.py
File renamed without changes.
View
81 web/src/python/nimbusweb/portal/usercreate/create.py
@@ -0,0 +1,81 @@
+import os
+import sys
+import string
+from datetime import datetime
+from random import Random
+
+from django.contrib.auth.models import User
+from django.db import IntegrityError
+from django.conf import settings
+
+from dateutil.relativedelta import *
+from nimbusrest.admin.connection import AdminConnection
+
+
+def create_user(dn, cert, key, username, email, firstname, lastname):
+ """
+ Returns (error_text, new_user, success_token)
+ """
+ password = _generate_initial_password()
+ try:
+ user = User.objects.create_user(username, email, password)
+ except IntegrityError:
+ return ("Username is taken already", user, None)
+ user.first_name = firstname
+ user.last_name = lastname
+ user.save()
+
+ user.dn = dn #XXX hack
+ nimbus_user = nimbus_user_create_remote(user)
+ access_key_obj = nimbus_user.generate_access_key()
+ query_id, query_secret = access_key_obj.key, access_key_obj.secret
+ print "[create_user] nimbus_user => ", nimbus_user
+ token = _generate_login_key()
+ _insert_user_profile_data(user, token=token, cert=cert, key=key, query_id=query_id, query_secret=query_secret)
+ return (None, user, token)
+
+
+def _insert_user_profile_data(user, token=None, cert=None, key=None, query_id=None, query_secret=None):
+ """
+ 'user' is a Django User instance.
+ """
+ profile = user.get_profile()
+ profile.initial_login_key = token
+ profile.cert = cert
+ profile.certkey = key
+ profile.query_id = query_id
+ profile.query_secret = query_secret
+ now = datetime.now()
+ expire_hours = int(settings.NIMBUS_TOKEN_EXPIRE_HOURS)
+ profile.login_key_expires = now + relativedelta(hours=+expire_hours)
+ profile.save()
+ return profile
+
+
+def nimbus_user_create_remote(user_instance):
+ """Use the Nimbus API to register a new Nimbus User.
+
+ `user_instance` is a `Django User` instance.
+ """
+ nimbus_key = getattr(settings, "NIMBUS_KEY", "testadmin")
+ nimbus_secret = getattr(settings, "NIMBUS_SECRET", "secret")
+ service_uri = getattr(settings, "NIMBUS_SERVICE_URI", "https://localhost:4443/admin")
+ conn = AdminConnection(service_uri, nimbus_key, nimbus_secret)
+ nimbus_user = conn.add_user(user_instance)
+ return nimbus_user
+
+
+def _generate_initial_password():
+ okchars = string.letters + string.digits + "!@%^_&*+-"
+ okchars += okchars
+ password = ''.join( Random().sample(okchars, 50))
+ # double check what we're getting from foreign function
+ if len(password) < 50:
+ raise Exception("Could not create initial password") #XXX
+ return password
+
+def _generate_login_key():
+ okchars = string.letters + string.digits + "_-"
+ okchars += okchars
+ token = ''.join(Random().sample(okchars, 80)).replace(" ", "_")
+ return token
View
16 web/src/python/nimbusweb/portal/usercreate/forms.py
@@ -0,0 +1,16 @@
+from django import forms
+
+class NewUserForm(forms.Form):
+ username = forms.CharField()
+ firstname = forms.CharField()
+ lastname = forms.CharField()
+ email = forms.EmailField()
+
+class CertForm(NewUserForm):
+ cert = forms.FileField()
+
+class DNForm(NewUserForm):
+ DN = forms.CharField()
+
+class AutoCreateForm(NewUserForm):
+ pass
View
7 web/src/python/nimbusweb/portal/usercreate/urls.py
@@ -0,0 +1,7 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('nimbusweb.portal.usercreate.views',
+ (r'^$', 'index'),
+ (r'^(?P<method>.*)/$', 'method'),
+ (r'^success$', 'success'),
+)
View
16 web/src/python/nimbusweb/portal/usercreate/util.py
@@ -0,0 +1,16 @@
+from django.conf import settings
+from nimbusweb.setup.ezpz_ca import EzPzCA
+
+def extract_dn(cert):
+ ezpz = EzPzCA(settings.NIMBUS_CADIR, settings.WEBDIR)
+ DN = ezpz.get_cert_dn(cert)
+ return DN
+
+def autocreate_cert(cn):
+ """Create a cert using local CA functionality.
+
+ The 'cn' (common name) is the 'username' of the new User.
+ """
+ ezpz = EzPzCA(settings.NIMBUS_CADIR, settings.WEBDIR)
+ (DN, cert, key) = ezpz.create_cert(cn)
+ return (DN, cert, key)
View
107 web/src/python/nimbusweb/portal/usercreate/views.py
@@ -0,0 +1,107 @@
+import sys
+
+from django.shortcuts import render_to_response
+from django.contrib.auth.decorators import login_required
+from django.http import Http404, HttpResponseRedirect
+from django.conf import settings
+
+from util import extract_dn, autocreate_cert
+from create import create_user
+from forms import CertForm, DNForm, AutoCreateForm
+
+USER_CREATE_METHODS = (
+ ("cert", "Provide User's Cert file", "The DN is extracted from given Cert file, then used to create a new User."),
+ ("dn", "Provide User's DN", "The provided DN will be used to create a new User."),
+ ("autocreate", "Auto-create a Certificate and User", "A new certicate will be created, then used to create a new User.")
+)
+
+@login_required
+def index(request):
+ return render_to_response('usercreate/index.html', {"createmethods":USER_CREATE_METHODS})
+
+@login_required
+def method(request, method):
+ if method not in ["cert", "dn", "autocreate"]:
+ raise Http404
+
+ dn, cert, key = None, None, None
+ if method == "cert":
+ methodinfo = USER_CREATE_METHODS[0][1]
+ if request.method == "POST":
+ form = CertForm(request.POST, request.FILES)
+ if form.is_valid():
+ certdata = form.cleaned_data["cert"]
+ cert = certdata.read()
+ dn = extract_dn(cert)
+ print "[from 'cert'] dn => ", dn
+ else:
+ form = CertForm()
+
+ if method == "dn":
+ methodinfo = USER_CREATE_METHODS[1][1]
+ if request.method == "POST":
+ form = DNForm(request.POST)
+ if form.is_valid():
+ dn = form.cleaned_data["DN"]
+ else:
+ form = DNForm()
+
+ if method == "autocreate":
+ methodinfo = USER_CREATE_METHODS[2][1]
+ if request.method == "POST":
+ #No form data needed, correct?
+ form = AutoCreateForm(request.POST)
+ if form.is_valid():
+ cn = form.cleaned_data["username"] #username is used as the CN (common name)
+ print "[autocreate] cn => ", cn
+ try:
+ (dn, cert, key) = autocreate_cert(cn)
+ except:
+ exception_type = sys.exc_type
+ try:
+ exceptname = exception_type.__name__
+ except AttributeError:
+ exceptname = exception_type
+ name = str(exceptname)
+ err = str(sys.exc_value)
+ errmsg = "Problem creating User: '%s: %s'" % (name, err)
+ raise Exception(errmsg)
+ else:
+ form = AutoCreateForm()
+
+ if dn is not None:
+ try:
+ username = form.cleaned_data["username"]
+ firstname = form.cleaned_data["firstname"]
+ lastname = form.cleaned_data["lastname"]
+ email = form.cleaned_data["email"]
+ (error, new_user, token) = create_user(dn, cert, key, username, email, firstname, lastname)
+ if error:
+ raise Exception(error)
+ return HttpResponseRedirect("/usercreate/success?token="+token)
+ except:
+ new_user.delete() #roll back newly create User and UserProfile
+ exception_type = sys.exc_type
+ try:
+ exceptname = exception_type.__name__
+ except AttributeError:
+ exceptname = exception_type
+ name = str(exceptname)
+ err = str(sys.exc_value)
+ errmsg = "Problem creating User: '%s: %s'" % (name, err)
+ raise Exception(errmsg)
+
+ return render_to_response('usercreate/method.html', {"form":form, "method":method, "methodinfo":methodinfo})
+
+
+@login_required
+def success(request):
+ token = request.GET.get("token")
+ baseurl = getattr(settings, "NIMBUS_PRINT_URL", "http://.../nimbus/")
+ basepath = getattr(settings, "NIMBUS_PRINT_PATH", "register/token/")
+ url = baseurl+basepath
+ return render_to_response('usercreate/success.html', {"url":url, "token":token})
+
+
+
+
View
5 web/src/python/nimbusweb/setup/newconf.py
@@ -3,7 +3,7 @@
from setuperrors import *
import string
-def run(basedir, timezone, accountprompt, log, debug, insecuremode, printurl, expire_hours):
+def run(basedir, timezone, accountprompt, log, debug, insecuremode, printurl, expire_hours, cadir):
log.debug("Installing new configurations to django and cherrypy")
if not accountprompt:
@@ -34,6 +34,9 @@ def run(basedir, timezone, accountprompt, log, debug, insecuremode, printurl, ex
lines.append("TIME_ZONE = '%s'" % timezone)
lines.append("NIMBUS_ACCOUNT_PROMPT = '%s'" % accountprompt)
+
+ cadir_path = pathutil.pathjoin(basedir, cadir)
+ lines.append("NIMBUS_CADIR = '%s'" % cadir_path)
if debug:
lines.append("DEBUG = True")
View
5 web/src/python/nimbusweb/setup/setup.py
@@ -307,6 +307,7 @@ def main(argv=None):
certconf = config_from_key(config, "ssl.cert")
keyconf = config_from_key(config, "ssl.key")
+ cadir = config_from_key(config, "ca.dir")
timezone = config_from_key(config, "timezone")
port = config_from_key(config, "webserver.port")
printurl = config_from_key(config, "print.url")
@@ -330,7 +331,7 @@ def main(argv=None):
checkssl.run(basedir, certconf, keyconf, log)
if opts.newconf:
- newconf.run(basedir, timezone, accountprompt, log, printdebugoutput, insecuremode, printurl, expire_hours)
+ newconf.run(basedir, timezone, accountprompt, log, printdebugoutput, insecuremode, printurl, expire_hours, cadir)
if opts.printport:
if not port:
@@ -400,4 +401,4 @@ def main(argv=None):
print >>sys.stderr, errmsg
traceback.print_tb(sys.exc_info()[2])
sys.exit(97)
-
+
View
26 web/src/python/run-tests.sh
@@ -0,0 +1,26 @@
+# Usage:
+#
+# $ ./run-tests.sh django-app-name-to-test
+#
+# If you do not specify an app name, all test will run.
+# TODO: let '--verbosity' be passed in as an argument.
+#
+PYTHON_EXE="/usr/bin/env python"
+
+NIMBUS_WEBDIR_REL="`dirname $0`/../.."
+NIMBUS_WEBDIR=`cd $NIMBUS_WEBDIR_REL; pwd`
+
+NIMBUS_WEBCONF="$NIMBUS_WEBDIR/nimbusweb.conf"
+if [ ! -f "$NIMBUS_WEBCONF" ]; then
+ echo ""
+ echo "Cannot find conf file, exiting. (expected at '$NIMBUS_WEBCONF')"
+ exit 1
+fi
+
+NIMBUS_PYLIB="$NIMBUS_WEBDIR/lib/python"
+NIMBUS_PYSRC="$NIMBUS_WEBDIR/src/python"
+
+PYTHONPATH="$NIMBUS_PYSRC:$NIMBUS_PYLIB:$PYTHONPATH"
+export PYTHONPATH
+
+$PYTHON_EXE $NIMBUS_PYSRC/nimbusweb/portal/manage.py test --verbosity=2 $1

0 comments on commit 04818a7

Please sign in to comment.