[rhmessaging-commits] rhmessaging commits: r2511 - in mgmt/trunk/cumin/python: wooly and 1 other directory.
rhmessaging-commits at lists.jboss.org
rhmessaging-commits at lists.jboss.org
Sun Sep 21 13:35:34 EDT 2008
Author: justi9
Date: 2008-09-21 13:35:33 -0400 (Sun, 21 Sep 2008)
New Revision: 2511
Added:
mgmt/trunk/cumin/python/cumin/user.py
mgmt/trunk/cumin/python/cumin/user.strings
Modified:
mgmt/trunk/cumin/python/cumin/__init__.py
mgmt/trunk/cumin/python/cumin/page.py
mgmt/trunk/cumin/python/cumin/test.py
mgmt/trunk/cumin/python/cumin/widgets.strings
mgmt/trunk/cumin/python/wooly/__init__.py
mgmt/trunk/cumin/python/wooly/__init__.strings
mgmt/trunk/cumin/python/wooly/devel.py
mgmt/trunk/cumin/python/wooly/forms.py
mgmt/trunk/cumin/python/wooly/forms.strings
mgmt/trunk/cumin/python/wooly/server.py
Log:
Add support for reading cookies and setting response headers to wooly
Session.
Introduce UserSessions.
Stop using http auth for login. Instead use a dedicated login UI to
create user sessions. Revise auth check to work with user sessions.
Change wooly.Session to take a Page in its constructor. Change sites
that mutate Session.page to instead create a new Session.
Remove get_page from Application, and instead use the pages dict
directly.
Rename FormInputErrorSet to FormErrorSet to reflect its more general
utility.
Add a PasswordInput and PasswordField.
Provide an html string for Page.
Modified: mgmt/trunk/cumin/python/cumin/__init__.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/__init__.py 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/cumin/__init__.py 2008-09-21 17:35:33 UTC (rev 2511)
@@ -9,16 +9,18 @@
from mint import *
from time import sleep
from threading import Thread, Event
-from base64 import decodestring
-from crypt import crypt
+from urllib import quote
from model import CuminModel, ModelPage
from demo import DemoData
from page import CuminPage
from stat import StatChartPage
from action import ActionPage
+from user import LoginPage
from util import Config
+from wooly import Session
+
log = logging.getLogger("cumin")
class Cumin(Application):
@@ -40,14 +42,33 @@
self.add_page(self.main_page)
self.set_default_page(self.main_page)
- self.add_page(CssPage(self, "cumin.css"))
- self.add_page(JavascriptPage(self, "cumin.js"))
- self.add_page(ResourcePage(self, "resource"))
self.add_page(DevelPage(self, "devel.html"))
self.add_page(ModelPage(self, "model.xml"))
self.add_page(ActionPage(self, "actions.html"))
self.add_page(StatChartPage(self, "stats.png"))
+ unprotected = set()
+
+ self.login_page = LoginPage(self, "login.html")
+ self.add_page(self.login_page)
+ unprotected.add(self.login_page)
+
+ page = CssPage(self, "cumin.css")
+ self.add_page(page)
+ unprotected.add(page)
+
+ page = JavascriptPage(self, "cumin.js")
+ self.add_page(page)
+ unprotected.add(page)
+
+ page = ResourcePage(self, "resource")
+ self.add_page(page)
+ unprotected.add(page)
+
+ self.unprotected_pages = unprotected
+
+ self.user_sessions_by_id = dict()
+
def check(self):
if not os.path.isdir(self.home):
raise Exception \
@@ -109,38 +130,32 @@
class CuminServer(WebServer):
def authorized(self, session):
- name = session.credentials.get("name")
- password = session.credentials.get("password")
+ auth = False
+ page = session.page
- if name:
- try:
- user = Subject.selectBy(name=name)[0]
- except IndexError:
- return False
+ if page in self.app.unprotected_pages:
+ return True
- if user:
- crypted = user.password
+ id = session.cookies.get("session")
- if crypted and crypt(password, crypted) == crypted:
- lch = user.lastChallenged
-
- if lch:
- timeout = timedelta(seconds=3600)
- now = datetime.now()
+ if id is not None:
+ usess = self.app.user_sessions_by_id.get(id)
- if now - lch < timeout:
- lout = user.lastLoggedOut
+ if usess is not None:
+ timeout = timedelta(seconds=3600)
+ now = datetime.now()
- if lout is None or lout < lch:
- return True
- else:
- user.lastChallenged = datetime.now()
- user.syncUpdate()
- return True
+ if now > usess.created and now < usess.created + timeout:
+ setattr(session, "user_session", usess)
- user.lastChallenged = datetime.now()
- user.syncUpdate()
+ return True
+ lpage = self.app.login_page
+ lsess = Session(lpage)
+ lpage.origin.set(lsess, session.marshal())
+
+ page.set_redirect_url(session, lsess.marshal())
+
return False
class CuminConfig(Config):
@@ -219,7 +234,7 @@
formatter = logging.Formatter("%(name)-12s - %(message)s")
log.setLevel(level)
- mlog.setLevel(level)
+ #mlog.setLevel(level)
handler = logging.StreamHandler()
handler.setLevel(level)
Modified: mgmt/trunk/cumin/python/cumin/page.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/page.py 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/cumin/page.py 2008-09-21 17:35:33 UTC (rev 2511)
@@ -16,6 +16,7 @@
# We have a wooly.widgets.Link and a mint.Link; we want the former
from wooly.widgets import Link
+from wooly import Session
strings = StringCatalog(__file__)
@@ -101,13 +102,19 @@
return "Main"
def render_user_name(self, session):
- return session.credentials.get("name")
+ if hasattr(session, "user_session"):
+ return session.user_session.subject.name
def render_logout_href(self, session):
- branch = session.branch()
- self.__logout.set(branch, True)
- return branch.marshal()
+ page = self.app.login_page
+ lsess = Session(page)
+
+ page.logout.set(lsess, True)
+ page.origin.set(lsess, session.marshal())
+
+ return lsess.marshal()
+
def render_frames(self, session):
writer = Writer()
Modified: mgmt/trunk/cumin/python/cumin/test.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/test.py 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/cumin/test.py 2008-09-21 17:35:33 UTC (rev 2511)
@@ -88,8 +88,7 @@
if page is None:
page = self.app.main_page
- s = wooly.Session(self.app)
- s.set_page(page)
+ s = wooly.Session(page)
return page, s
@@ -99,8 +98,8 @@
if redirect is None:
raise Exception("Expected redirect")
- p, s = self.page_and_session()
- s.unmarshal(redirect)
+ s = wooly.Session.unmarshal(p.app, redirect)
+ p = s.page
p.process(s)
p.render(s)
Added: mgmt/trunk/cumin/python/cumin/user.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/user.py (rev 0)
+++ mgmt/trunk/cumin/python/cumin/user.py 2008-09-21 17:35:33 UTC (rev 2511)
@@ -0,0 +1,122 @@
+from wooly import *
+from wooly.widgets import *
+from wooly.resources import *
+from time import sleep
+from threading import Thread, Event
+from random import randint
+from datetime import datetime
+from crypt import crypt
+from uuid import uuid4
+
+from widgets import *
+from util import *
+
+from wooly import Session
+
+strings = StringCatalog(__file__)
+
+log = logging.getLogger("cumin.user")
+
+class UserSession(object):
+ def __init__(self, app, subject):
+ self.app = app
+ self.subject = subject
+ self.id = str(uuid4())
+ self.created = datetime.now()
+
+ self.app.user_sessions_by_id[self.id] = self
+
+ def delete(self):
+ del self.app.user_sessions_by_id[self.id]
+
+class UserSessionDeleteThread(Thread):
+ pass # every minute cycle through and delete expired sessions
+
+class LoginPage(Page):
+ def __init__(self, app, name):
+ super(LoginPage, self).__init__(app, name)
+
+ self.logout = BooleanParameter(app, "logout")
+ self.add_parameter(self.logout)
+
+ self.origin = self.Origin(app, "origin")
+ self.add_parameter(self.origin)
+
+ form = LoginForm(app, "form")
+ self.add_child(form)
+
+ def do_process(self, session):
+ if self.logout.get(session):
+ #id = session.get_cookie("session")
+ session.expire_cookie("session")
+
+ super(LoginPage, self).do_process(session)
+
+ def render_title(self, session):
+ return "Log In"
+
+ class Origin(Parameter):
+ def get_default(self, session):
+ return Session(self.app.main_page).marshal()
+
+class LoginForm(FieldForm):
+ def __init__(self, app, name):
+ super(LoginForm, self).__init__(app, name)
+
+ self.__login_invalid = Attribute(app, "login_invalid")
+ self.add_attribute(self.__login_invalid)
+
+ self.__name = self.Name(app, "name", self)
+ self.add_field(self.__name)
+ self.__name.get_input().set_size(20)
+
+ self.__password = self.Password(app, "password", self)
+ self.add_field(self.__password)
+ self.__password.get_input().set_size(20)
+
+ self.__submit = self.Submit(app, "submit", self)
+ self.add_child(self.__submit)
+
+ def do_process(self, session):
+ if self.__submit.get(session):
+ name = self.__name.get(session)
+ password = self.__password.get(session)
+
+ errors = self.validate(session)
+
+ if not errors:
+ try:
+ user = Subject.selectBy(name=name)[0]
+ except IndexError:
+ self.__login_invalid.set(session, True)
+ return
+
+ crypted = user.password
+
+ if crypted and crypt(password, crypted) == crypted:
+ # You're in!
+
+ usess = UserSession(self.app, user)
+ session.set_cookie("session", usess.id)
+
+ url = self.page.origin.get(session)
+
+ self.page.set_redirect_url(session, url)
+ else:
+ self.__login_invalid.set(session, True)
+
+ def render_login_invalid(self, session):
+ if self.__login_invalid.get(session):
+ return self.get_string("login_invalid")
+
+ class Name(StringField):
+ def render_title(self, session):
+ return "User Name"
+
+ class Password(PasswordField):
+ def render_title(self, session):
+ return "Password"
+
+ class Submit(FormButton):
+ def render_content(self, session):
+ return "Submit"
Added: mgmt/trunk/cumin/python/cumin/user.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/user.strings (rev 0)
+++ mgmt/trunk/cumin/python/cumin/user.strings 2008-09-21 17:35:33 UTC (rev 2511)
@@ -0,0 +1,80 @@
+[LoginPage.css]
+body.LoginPage {
+ background: #f7f7f7;
+ padding: 4em;
+}
+
+[LoginPage.html]
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+ <head>
+ <title>{title}</title>
+ <link rel="stylesheet" type="text/css" href="cumin.css"/>
+ <link rel="shortcut icon" href="resource?name=favicon.ico" type="image/x-icon"/>
+ <script src="resource?name=wooly.js" type="text/javascript"> </script>
+ <script src="cumin.js" type="text/javascript"> </script>
+ </head>
+ <body class="LoginPage">
+ {form}
+ </body>
+</html>
+
+[LoginForm.css]
+form.LoginForm {
+ background: #fff;
+ width: 16em;
+ margin: 0 auto;
+ border: 1px solid #ddd;
+ -moz-border-radius: 0.5em;
+ -webkit-border-radius: 0.5em;
+ padding: 2em;
+}
+
+form.LoginForm > h1 {
+ margin: 0 0 1em 0;
+}
+
+form.LoginForm h1 img {
+ vertical-align: -60%;
+ margin: 0 0.25em 0 0;
+}
+
+form.LoginForm input {
+ width: 12em;
+}
+
+form.LoginForm > div.buttons {
+ margin: 1.5em 0 0 0;
+}
+
+form.LoginForm p.login_invalid {
+ color: red;
+}
+
+[LoginForm.html]
+<form id="{id}" class="LoginForm" method="post" action="?">
+ <h1><img src="resource?name=mrg-36.png"/> MRG Management</h1>
+
+ <p>Enter your user name and password to log in.</p>
+
+ <p>If you do not have an account or have trouble logging in, contact
+ the <a href="{operator_email}">site operator</a>.</p>
+
+ {login_invalid}
+
+ {fields}
+
+ <div class="buttons">{submit}</div>
+
+ <div>{hidden_inputs}</div>
+</form>
+<script type="text/javascript">
+<![CDATA[
+ wooly.doc().elembyid("{id}").node.elements[0].focus();
+]]>
+</script>
+
+[LoginForm.login_invalid]
+<p class="login_invalid">The user name and password you
+entered do not match any account.</p>
Modified: mgmt/trunk/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/widgets.strings 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/cumin/widgets.strings 2008-09-21 17:35:33 UTC (rev 2511)
@@ -49,7 +49,7 @@
</script>
[CuminConfirmForm.html]
-<form id="{id}" class="mform" method="post" action="?">
+<form id="{id}" method="post" action="?">
<div class="head">
<h1>{title}</h1>
</div>
Modified: mgmt/trunk/cumin/python/wooly/__init__.py
===================================================================
--- mgmt/trunk/cumin/python/wooly/__init__.py 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/wooly/__init__.py 2008-09-21 17:35:33 UTC (rev 2511)
@@ -5,6 +5,7 @@
from time import clock
from datetime import datetime
from urlparse import urlsplit
+from time import gmtime
from resources import ResourceFinder, StringCatalog
@@ -374,6 +375,7 @@
return self.app.get_widget(path)
from parameters import DictParameter
+
class Application(object):
def __init__(self):
self.pages = dict()
@@ -408,13 +410,8 @@
page.init()
- def get_page(self, name):
- #print "Looking for", name, "in", self.pages
-
- return self.pages.get(name, self.default_page)
-
def set_default_page(self, page):
- self.default_page = page
+ self.pages[""] = page
def add_widget(self, widget):
if self.widget_index:
@@ -472,13 +469,22 @@
return "%s(default_page=%s)" % (self.__class__.__name__, self.default_page)
class Session(object):
- def __init__(self, app, trunk=None):
- self.app = app
- self.trunk = trunk
- self.page = None
+ http_date_gmt = "%a, %d %b %Y %H:%M:%S GMT"
+
+ def __init__(self, page, response_headers=None):
+ assert isinstance(page, Page)
+
+ self.app = page.app
+ self.page = page
+ self.trunk = None
self.values = dict()
- self.credentials = dict()
self.origin = None
+ self.cookies = dict()
+
+ if response_headers is None:
+ self.response_headers = list()
+ else:
+ self.response_headers = response_headers
if self.app.debug:
self.debug = self.Debug(self)
@@ -500,21 +506,27 @@
self.render_stack[0].write(out)
def branch(self):
- return Session(self.app, self)
+ session = Session(self.page)
+ session.trunk = self
+ session.response_headers = list(self.response_headers)
+ return session
- def get_page(self):
- if self.page:
- page = self.page
- elif self.trunk:
- page = self.trunk.get_page()
- else:
- page = None
+ def add_header(self, name, value):
+ self.response_headers.append((name, value))
- return page
+ def set_cookie(self, name, value, expires=None):
+ crumbs = list()
+ crumbs.append("%s=%s" % (name, value))
- def set_page(self, page):
- self.page = page
+ if expires:
+ when = expires.strftime(self.http_date_gmt)
+ crumbs.append("expires=%s" % when)
+ self.add_header("Set-Cookie", "; ".join(crumbs))
+
+ def expire_cookie(self, name):
+ self.set_cookie(name, "", datetime(*gmtime(1)[0:6]))
+
# This is the biggest hotspot in cumin-bench profiling
def get(self, key):
if key in self.values:
@@ -539,7 +551,7 @@
del self.values[key]
def marshal(self):
- page = self.marshal_page()
+ page = self.page.name
vars = self.marshal_url_vars()
if vars:
@@ -552,11 +564,8 @@
return url
- def marshal_page(self):
- return self.get_page().name
-
def marshal_url_vars(self, separator=";"):
- params = self.get_page().get_saved_parameters(self)
+ params = self.page.get_saved_parameters(self)
vars = list()
for param in params:
@@ -590,21 +599,29 @@
return separator.join(vars)
- def unmarshal(self, string):
+ def unmarshal(cls, app, string):
elems = string.split("?")
- self.unmarshal_page(elems[0])
+ try:
+ name = elems[0]
+ if name.startswith("/"):
+ name = name[1:]
+
+ page = app.pages[name]
+ except KeyError:
+ raise Exception("Page '%s' not found" % name)
+
+ session = Session(page)
+
try:
- self.unmarshal_url_vars(elems[1])
+ session.unmarshal_url_vars(elems[1])
except IndexError:
pass
- def unmarshal_page(self, string):
- if string.startswith("/"):
- string = string[1:]
+ return session
- self.set_page(self.app.get_page(string))
+ unmarshal = classmethod(unmarshal)
def unmarshal_url_vars(self, string, separator=";"):
vars = string.split(separator)
@@ -615,7 +632,7 @@
key = unquote(skey)
value = unquote_plus(svalue)
- param = self.app.get_parameter(self.get_page(), key)
+ param = self.app.get_parameter(self.page, key)
if param:
if param.is_dictionary:
@@ -625,6 +642,17 @@
except ValueError:
pass
+ def unmarshal_cookies(self, string):
+ if string is not None:
+ cookies = dict()
+ crumbs = string.split(";")
+
+ for crumb in crumbs:
+ name, value = crumb.split("=", 1)
+ cookies[name.strip()] = value.strip()
+
+ self.cookies = cookies
+
def set_origin(self, origin):
self.origin = self.fix_origin(origin)
@@ -766,7 +794,7 @@
if type(frag) is str:
writer.write(frag)
elif callable(frag):
- #print "tc", elem, args
+ #print "tc", frag, args
result = frag(self.__object, session, *args)
Modified: mgmt/trunk/cumin/python/wooly/__init__.strings
===================================================================
--- mgmt/trunk/cumin/python/wooly/__init__.strings 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/wooly/__init__.strings 2008-09-21 17:35:33 UTC (rev 2511)
@@ -1,2 +1,14 @@
[Widget.html]
{content}
+
+[Page.html]
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+ <head>
+ <title>{title}</title>
+ </head>
+ <body>
+ {content}
+ </body>
+</html>
Modified: mgmt/trunk/cumin/python/wooly/devel.py
===================================================================
--- mgmt/trunk/cumin/python/wooly/devel.py 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/wooly/devel.py 2008-09-21 17:35:33 UTC (rev 2511)
@@ -24,11 +24,10 @@
print count, url,
start = clock()
-
- session = Session(self.app)
- session.unmarshal(url)
- page = session.get_page()
+ session = Session.unmarshal(self.app, url)
+
+ page = session.page
page.process(session)
html = page.render(session)
Modified: mgmt/trunk/cumin/python/wooly/forms.py
===================================================================
--- mgmt/trunk/cumin/python/wooly/forms.py 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/wooly/forms.py 2008-09-21 17:35:33 UTC (rev 2511)
@@ -39,7 +39,7 @@
if not self.origin.get(session):
self.origin.set(session, session.get_origin())
- params = set(session.get_page().get_saved_parameters(session))
+ params = set(session.page.get_saved_parameters(session))
params.difference_update(self.form_params)
for param in params:
@@ -66,6 +66,42 @@
writer.write("<input type='hidden' name='%s' value='%s'/>" \
% (name, value))
+class FormError(object):
+ def __init__(self, message=None):
+ self.message = message
+
+ def get_message(self, session):
+ return self.message
+
+class FormErrorSet(ItemSet):
+ def __init__(self, app, name):
+ super(FormErrorSet, self).__init__(app, name)
+
+ self.__errors = self.Errors(app, "errors")
+ self.add_attribute(self.__errors)
+
+ def add(self, session, error):
+ assert isinstance(error, FormError)
+
+ self.__errors.get(session).append(error)
+
+ def get(self, session):
+ return self.__errors.get(session)
+
+ def get_items(self, session, *args):
+ return self.get(session)
+
+# def do_render(self, session, *args):
+# if self.get(session):
+# super(FormErrorSet, self).do_render(session, *args)
+
+ def render_item_content(self, session, item):
+ return item.get_message(session)
+
+ class Errors(Attribute):
+ def get_default(self, session):
+ return list()
+
class FormInput(Widget):
def __init__(self, app, name, form):
super(FormInput, self).__init__(app, name)
@@ -113,23 +149,14 @@
def render_disabled_attr(self, session, *args):
return self.disabled and "disabled=\"disabled\"" or None
-class FormError(object):
- def __init__(self, message=None):
- self.message = message
-
- def get_message(self, session):
- return self.message
-
class MissingValueError(FormError):
def get_message(self, session):
return "This value is required"
class EmptyInputError(FormError):
def __init__(self):
- message = "This value is required"
+ super(EmptyInputError, self).__init__("This value is required")
- super(EmptyInputError, self).__init__(message)
-
class ScalarInput(FormInput):
def __init__(self, app, name, form):
super(ScalarInput, self).__init__(app, name, form)
@@ -151,6 +178,9 @@
self.set_size(30)
+class PasswordInput(StringInput):
+ pass
+
class IntegerInput(ScalarInput):
def __init__(self, app, name, form):
super(IntegerInput, self).__init__(app, name, form)
@@ -260,7 +290,7 @@
self.__form = form
self.__param = None
- self.__errors = FormFieldErrors(app, "errors")
+ self.__errors = FormErrorSet(app, "errors")
self.add_child(self.__errors)
def get_parameter(self):
@@ -282,7 +312,7 @@
return self.__param.set(session, value)
def validate(self, session):
- errors = self.__errors.attr.get(session)
+ errors = self.__errors.get(session)
self.do_validate(session, errors)
@@ -291,27 +321,6 @@
def do_validate(self, session, errors):
pass
- def render_errors(self, session, *args):
- if self.__errors.attr.get(session):
- return self.__errors.render(session)
-
-class FormFieldErrors(ItemSet):
- def __init__(self, app, name):
- super(FormFieldErrors, self).__init__(app, name)
-
- self.attr = self.Errors(app, "attr")
- self.add_attribute(self.attr)
-
- def get_items(self, session, *args):
- return self.attr.get(session)
-
- def render_item_content(self, session, item):
- return item.get_message(session)
-
- class Errors(Attribute):
- def get_default(self, session):
- return list()
-
class ScalarField(FormField):
def __init__(self, app, name, form):
super(ScalarField, self).__init__(app, name, form)
@@ -326,6 +335,7 @@
self.set_parameter(input.get_parameter())
self.__input = input
+
return input
def render_inputs(self, session, *args):
@@ -339,11 +349,19 @@
self.add_child(input)
self.set_input(input)
+class PasswordField(ScalarField):
+ def __init__(self, app, name, form):
+ super(PasswordField, self).__init__(app, name, form)
+
+ input = PasswordInput(app, "input", form)
+ self.add_child(input)
+ self.set_input(input)
+
class IntegerField(ScalarField):
def __init__(self, app, name, form):
super(IntegerInputField, self).__init__(app, name, form)
- input = Integer(app, "input", form)
+ input = IntegerInput(app, "input", form)
self.add_child(input)
self.set_input(input)
Modified: mgmt/trunk/cumin/python/wooly/forms.strings
===================================================================
--- mgmt/trunk/cumin/python/wooly/forms.strings 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/wooly/forms.strings 2008-09-21 17:35:33 UTC (rev 2511)
@@ -1,3 +1,15 @@
+[FormErrorSet.css]
+ul.errors {
+ color: red;
+ font-weight: bold;
+}
+
+[FormErrorSet.html]
+<ul class="errors">{items}</ul>
+
+[FormErrorSet.item_html]
+<li>{item_content}</li>
+
[FormButton.html]
<button class="{class}" id="{id}" type="submit" name="{name}" value="{value}" tabindex="{tab_index}" {disabled_attr}>{content}</button>
@@ -4,6 +16,9 @@
[ScalarInput.html]
<input type="text" name="{name}" value="{value}" tabindex="{tab_index}" {disabled_attr} size="{size}"/>
+[PasswordInput.html]
+<input type="password" name="{name}" value="{value}" tabindex="{tab_index}" {disabled_attr} size="{size}"/>
+
[CheckboxInput.html]
<input type="checkbox" name="{name}" value="{value}" tabindex="{tab_index}" {checked_attr} {disabled_attr}/>
@@ -63,12 +78,6 @@
<div class="inputs">{inputs}</div>
</div>
-[FormFieldErrors.html]
-<ul class="errors">{items}</ul>
-
-[FormFieldErrors.item_html]
-<li>{item_content}</li>
-
[RadioFieldOption.html]
<div>
<input type="radio" name="{name}" id="{id}" value="{value}"
Modified: mgmt/trunk/cumin/python/wooly/server.py
===================================================================
--- mgmt/trunk/cumin/python/wooly/server.py 2008-09-21 01:29:04 UTC (rev 2510)
+++ mgmt/trunk/cumin/python/wooly/server.py 2008-09-21 17:35:33 UTC (rev 2511)
@@ -9,6 +9,7 @@
class WebServer(object):
http_date = "%a, %d %b %Y %H:%M:%S %Z"
+ http_date_gmt = "%a, %d %b %Y %H:%M:%S GMT"
def __init__(self, app, addr, port):
self.app = app
@@ -31,24 +32,22 @@
def stop(self):
self.__server.stop()
+ def authorized(self, session):
+ return False
+
def service(self, env, respond):
- session = Session(self.app)
- session.unmarshal_page(env["PATH_INFO"])
- session.unmarshal_url_vars(env["QUERY_STRING"])
- if "HTTP_REFERER" in env:
- session.set_origin(env["HTTP_REFERER"])
+ headers = list()
- if "HTTP_AUTHORIZATION" in env:
- auth = env["HTTP_AUTHORIZATION"].split(" ")[1]
- name, password = decodestring(auth).split(":", 1)
- session.credentials["name"] = name
- session.credentials["password"] = password
+ name = env["PATH_INFO"][1:]
- if not self.authorized(session):
- headers = [("WWW-Authenticate", "Basic realm=\"MRG Management\"")]
- respond("401 Unauthorized", headers)
- return ()
+ try:
+ page = self.app.pages[name]
+ except KeyError:
+ return self.not_found(respond, headers)
+ session = Session(page, headers)
+ session.unmarshal_url_vars(env["QUERY_STRING"])
+
if env["REQUEST_METHOD"] == "POST":
if env["CONTENT_TYPE"] == "application/x-www-form-urlencoded":
length = int(env["CONTENT_LENGTH"])
@@ -60,19 +59,32 @@
if vars:
session.unmarshal_url_vars(vars, "&")
- page = session.get_page()
+ try:
+ session.unmarshal_cookies(env["HTTP_COOKIE"])
+ except KeyError:
+ pass
+ if "HTTP_REFERER" in env:
+ # XXX set this on page instead
+ session.set_origin(env["HTTP_REFERER"])
+
+ if not self.authorized(session):
+ url = page.get_redirect_url(session)
+
+ if url:
+ return self.redirect(respond, headers, url)
+ else:
+ return self.unauthorized(respond, headers)
+
try:
page.process(session)
except:
- return self.error(session, respond)
+ return self.error(respond, session)
- redirect = page.get_redirect_url(session)
+ url = page.get_redirect_url(session)
- if redirect:
- respond("303 See Other", (("Location", redirect),
- ("Content-Length", "0")))
- return ()
+ if url:
+ return self.redirect(respond, headers, url)
ims = env.get("HTTP_IF_MODIFIED_SINCE")
modified = page.get_last_modified(session).replace(microsecond=0)
@@ -81,19 +93,10 @@
since = datetime(*strptime(str(ims), self.http_date)[0:6])
if modified <= since:
- respond("304 Not Modified", (("Content-Length", "0"),))
- return ()
+ return self.not_modified(respond, headers)
- try:
- response = page.render(session)
- except:
- return self.error(session, respond)
-
- headers = list()
- headers.append(("Content-Length", str(len(response))))
-
if modified:
- ts = modified.strftime("%a, %d %b %Y %H:%M:%S GMT")
+ ts = modified.strftime(self.http_date_gmt)
headers.append(("Last-Modified", ts))
type = page.get_content_type(session)
@@ -106,18 +109,53 @@
if cache:
headers.append(("Cache-Control", cache))
+ try:
+ response = page.render(session)
+ except:
+ return self.error(respond, session)
+
+ headers.append(("Content-Length", str(len(response))))
+
respond("200 OK", headers)
page.save_session(session)
- return response
+ return (response,)
- def authorized(self, session):
- return False
+ def message(self, respond, headers, message):
+ headers.append(("Content-Length", str(len(message))))
+ headers.append(("Content-Type", "text/plain"))
- def error(self, session, respond):
- respond("500 Error", [("Content-Type", "text/plain")])
+ respond(message, headers)
+ return (message,)
+
+ def not_found(self, respond, headers):
+ return self.message(respond, headers, "404 Not Found")
+
+ def unauthorized(self, respond, headers):
+ return self.message(respond, headers, "401 Unauthorized")
+
+ def redirect(self, respond, headers, url):
+ headers.append(("Location", url))
+ headers.append(("Content-Length", "0"))
+
+ respond("303 See Other", headers)
+
+ return ()
+
+ def not_modified(self, respond, headers):
+ headers.append(("Content-Length", "0"))
+
+ respond("304 Not Modified", headers)
+
+ return ()
+
+ def error(self, respond, session):
+ session.add_header("Content-Type", "text/plain")
+
+ respond("500 Error", session.response_headers)
+
if session.debug:
writer = Writer()
writer.write("APPLICATION ERROR\n")
More information about the rhmessaging-commits
mailing list