r5479 - trunk/cumin/python/cumin
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-09-26 20:56:34 +0000 (Wed, 26 Sep 2012)
New Revision: 5479
Modified:
trunk/cumin/python/cumin/widgets.py
Log:
Missed a line during patch merge
Modified: trunk/cumin/python/cumin/widgets.py
===================================================================
--- trunk/cumin/python/cumin/widgets.py 2012-09-26 19:16:23 UTC (rev 5478)
+++ trunk/cumin/python/cumin/widgets.py 2012-09-26 20:56:34 UTC (rev 5479)
@@ -1376,6 +1376,7 @@
# notice instead of using the standard templates. Test for presence
# on the main page already to avoid any possibility of an infinite
# redirect loop.
+ cls, value, traceback = sys.exc_info()
mainpage = self.lookup_mainpage(session)
if session.request_environment["REQUEST_URI"] != mainpage:
if cls is RosemaryNotFound:
11 years, 7 months
r5478 - trunk/wooly/python/wooly
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-09-26 19:16:23 +0000 (Wed, 26 Sep 2012)
New Revision: 5478
Modified:
trunk/wooly/python/wooly/server.py
Log:
Reject LF characters in response headers
BZ831244
Modified: trunk/wooly/python/wooly/server.py
===================================================================
--- trunk/wooly/python/wooly/server.py 2012-09-26 19:14:21 UTC (rev 5477)
+++ trunk/wooly/python/wooly/server.py 2012-09-26 19:16:23 UTC (rev 5478)
@@ -170,6 +170,14 @@
for header in session.marshal_cookies(secure_cookies):
headers.append(("Set-Cookie", header))
+ # Make sure that we have no headers containing LF characters
+ # which could be a result of a response splitting attempt.
+ for header in headers:
+ if "\n" in header[1]:
+ log.error("Response header contains LF (#), %s:%s" % \
+ (header[0], header[1].replace("\n", "#")))
+ raise Exception("Unexpected LF in response header")
+
return status, headers, content
def adapt_request_to_session(self, env, session):
11 years, 7 months
r5477 - in trunk: cumin/python/cumin wooly/python/wooly
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-09-26 19:14:21 +0000 (Wed, 26 Sep 2012)
New Revision: 5477
Modified:
trunk/cumin/python/cumin/widgets.py
trunk/wooly/python/wooly/__init__.py
trunk/wooly/python/wooly/server.py
Log:
Filter redirects
BZ831235
Modified: trunk/cumin/python/cumin/widgets.py
===================================================================
--- trunk/cumin/python/cumin/widgets.py 2012-09-26 19:02:12 UTC (rev 5476)
+++ trunk/cumin/python/cumin/widgets.py 2012-09-26 19:14:21 UTC (rev 5477)
@@ -1376,14 +1376,7 @@
# notice instead of using the standard templates. Test for presence
# on the main page already to avoid any possibility of an infinite
# redirect loop.
- cls, value, traceback = sys.exc_info()
- if self.app.authorizator.is_enforcing():
- mainpage = self.app.authorizator.find_mainpage(session)
- if not mainpage.startswith("/"):
- mainpage = "/" + mainpage
- else:
- mainpage = "/index.html"
-
+ mainpage = self.lookup_mainpage(session)
if session.request_environment["REQUEST_URI"] != mainpage:
if cls is RosemaryNotFound:
session.add_notice(Notice(
Modified: trunk/wooly/python/wooly/__init__.py
===================================================================
--- trunk/wooly/python/wooly/__init__.py 2012-09-26 19:02:12 UTC (rev 5476)
+++ trunk/wooly/python/wooly/__init__.py 2012-09-26 19:14:21 UTC (rev 5477)
@@ -3,6 +3,8 @@
from template import *
from util import *
from traceback import print_exception
+import urlparse
+
log = logging.getLogger("wooly")
strings = StringCatalog(__file__)
@@ -536,6 +538,38 @@
return rend
+ def validate_redirect(self, session, url, env):
+
+ def netloc(env):
+ if 'HTTP_HOST' in env:
+ return env['HTTP_HOST']
+ return env['SERVER_NAME']
+
+ # Only allow redirects to our own pages
+ if type(url) in (str, unicode):
+ res = urlparse.urlparse(url)
+ # Path will be an index into our dictionary of pages
+ p = res.path
+ if p.startswith("/"):
+ p = p[1:]
+
+ if not p in self.app.pages_by_name or \
+ (res.scheme and res.scheme != env['wsgi.url_scheme']) or \
+ (res.netloc and res.netloc != netloc(env)):
+ session.add_notice(Notice("Invalid redirect, " \
+ "returning to main page"))
+ url = self.lookup_mainpage(session)
+ else:
+ url = self.lookup_mainpage(session)
+ return url
+
+ def lookup_mainpage(self, session):
+ if self.app.authorizator.is_enforcing():
+ mainpage = self.app.authorizator.find_mainpage(session)
+ else:
+ mainpage = "index.html"
+ return mainpage
+
def redirect_on_exception(self, session):
return None
Modified: trunk/wooly/python/wooly/server.py
===================================================================
--- trunk/wooly/python/wooly/server.py 2012-09-26 19:02:12 UTC (rev 5476)
+++ trunk/wooly/python/wooly/server.py 2012-09-26 19:14:21 UTC (rev 5477)
@@ -127,13 +127,16 @@
status = "200 OK"
except PageRedirect:
status = "303 See Other"
- headers.append(("Location", page.redirect.get(session)))
+ url = page.validate_redirect(session,
+ page.redirect.get(session), env)
+ headers.append(("Location", url))
except UpdateRedirect, e:
# This will optionally allow a failed ajax update to
# process a location change. Javascript code in the
# update handler will look for the header.
status = "200 OK"
- headers.append(("Location", e.url))
+ headers.append(("Location",
+ page.validate_redirect(session, e.url, env)))
except:
url = page.redirect_on_exception(session)
if url:
11 years, 7 months
r5476 - trunk/cumin/python/cumin/grid
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-09-26 19:02:12 +0000 (Wed, 26 Sep 2012)
New Revision: 5476
Modified:
trunk/cumin/python/cumin/grid/job.py
Log:
Extra checks for edits on readonly job attributes
BZ837037
Modified: trunk/cumin/python/cumin/grid/job.py
===================================================================
--- trunk/cumin/python/cumin/grid/job.py 2012-09-26 12:06:17 UTC (rev 5475)
+++ trunk/cumin/python/cumin/grid/job.py 2012-09-26 19:02:12 UTC (rev 5476)
@@ -873,25 +873,15 @@
self.update_enabled = False
- def do_get_items(self, session):
- ads = self.ads.get(session)
-
- if len(ads):
- # we just returned from a submit
- # Don't think this code is ever called, since process_cancel
- # below clears self.ads and is called at the end of process_submit.
- # Never saw the debugger hit a breakpoint here... tmckay 7/22/2011
- cls = self.app.model.job_meta_data
- return [self.gen_item(x, ads[x]["value"], cls, path=self.ads.path,
- dtype=ads[x]["type"], error=ads[x],
- orig=ads[x]["orig"]) for x in ads]
-
+ def do_get_items(self, session, setpath=True):
items, error = super(JobAdsEditor, self).do_get_items(session)
if error:
items = []
- for item in items:
- item["path"] = self.ads.path
+ # Avoid an extra pass if we don't need it
+ if setpath:
+ for item in items:
+ item["path"] = self.ads.path
return items, error
def process_cancel(self, session):
@@ -930,7 +920,7 @@
ads = self.ads.get(session)
just_ads = dict()
- for field in ads:
+ for field in ads:
ads[field]["error"] = None
try:
fval = ads[field]["value"]
@@ -990,6 +980,26 @@
if fval != orig:
just_ads[unicode(field)] = fval
+ # Use the full job add data to find out which
+ # ads are writable. This info is not available
+ # in the POST request data.
+ if just_ads:
+ items, error = self.do_get_items(session, setpath=False)
+ if error:
+ msg = (hasattr(error, "args") and \
+ len(error.args) > 0 and error.args[0]) or ""
+ if not msg:
+ msg = "Unable to get Job information at this time"
+ session.add_notice(Notice("Job edit failed: %s" % msg))
+ just_ads = []
+ else:
+ writables = dict()
+ for item in items:
+ n = item["name"]
+ if n in just_ads:
+ p = "property" in item and item["property"] or None
+ writables[n] = not p or p.writable
+
# Process all cases, including errors, becase we
# want to see a banner for errors we detect.
id = self.frame.id.get(session)
@@ -999,6 +1009,8 @@
task = self.frame.set_ad_task
for field in just_ads:
+ if not writables[field]:
+ ads[field]["error"] = "Attribute is not writable"
task.invoke(session, scheduler, job_id, field,
str(just_ads[field]), ads[field]["error"],
submission)
11 years, 7 months
r5475 - in trunk: cumin/python/cumin cumin/python/cumin/account wooly/python/wooly
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-09-26 12:06:17 +0000 (Wed, 26 Sep 2012)
New Revision: 5475
Modified:
trunk/cumin/python/cumin/account/widgets.py
trunk/cumin/python/cumin/widgets.py
trunk/wooly/python/wooly/__init__.py
trunk/wooly/python/wooly/forms.py
trunk/wooly/python/wooly/server.py
Log:
Embed a unique id in forms for validation
BZ832124
Modified: trunk/cumin/python/cumin/account/widgets.py
===================================================================
--- trunk/cumin/python/cumin/account/widgets.py 2012-09-26 11:57:06 UTC (rev 5474)
+++ trunk/cumin/python/cumin/account/widgets.py 2012-09-26 12:06:17 UTC (rev 5475)
@@ -84,6 +84,7 @@
if self.logout.get(session):
try:
del session.client_session.attributes["login_session"]
+ session.client_session.reset_csrf()
except KeyError:
pass
Modified: trunk/cumin/python/cumin/widgets.py
===================================================================
--- trunk/cumin/python/cumin/widgets.py 2012-09-26 11:57:06 UTC (rev 5474)
+++ trunk/cumin/python/cumin/widgets.py 2012-09-26 12:06:17 UTC (rev 5475)
@@ -1372,10 +1372,10 @@
return False
def redirect_on_exception(self, session):
- # If we have an exception from a missing object, redirect to the
- # main page with a notice instead of using the not_found_tmpl below.
- # Test for presence on the main page already to avoid any possibility
- # of an infinite redirect loop.
+ # If we have certain exceptions, redirect to the main page with a
+ # notice instead of using the standard templates. Test for presence
+ # on the main page already to avoid any possibility of an infinite
+ # redirect loop.
cls, value, traceback = sys.exc_info()
if self.app.authorizator.is_enforcing():
mainpage = self.app.authorizator.find_mainpage(session)
@@ -1384,12 +1384,17 @@
else:
mainpage = "/index.html"
- if cls is RosemaryNotFound and \
- session.request_environment["REQUEST_URI"] != mainpage:
- session.add_notice(Notice(
- "An object being displayed became unavailable"))
- return mainpage
+ if session.request_environment["REQUEST_URI"] != mainpage:
+ if cls is RosemaryNotFound:
+ session.add_notice(Notice(
+ "An object being displayed became unavailable"))
+ elif cls is CSRFException:
+ session.add_notice(Notice("An invalid form was submitted"))
+ else:
+ mainpage = None
+ return mainpage
+
def render_error(self, session):
cls, value, traceback = sys.exc_info()
Modified: trunk/wooly/python/wooly/__init__.py
===================================================================
--- trunk/wooly/python/wooly/__init__.py 2012-09-26 11:57:06 UTC (rev 5474)
+++ trunk/wooly/python/wooly/__init__.py 2012-09-26 12:06:17 UTC (rev 5475)
@@ -6,6 +6,9 @@
log = logging.getLogger("wooly")
strings = StringCatalog(__file__)
+class CSRFException(Exception):
+ pass
+
# XXX make this more definitely WidgetAttribute
class Attribute(object):
def __init__(self, app, name):
@@ -475,6 +478,7 @@
def init_parameter(self, param):
assert not self.sealed
assert isinstance(param, Parameter)
+ assert param.path != Session.csrf_tag_name
self.page_parameters.append(param)
self.page_parameters_by_path[param.path] = param
@@ -696,6 +700,8 @@
class Session(object):
http_date_gmt = "%a, %d %b %Y %H:%M:%S GMT"
+ csrf_tag_name = "csrf"
+
def __init__(self, page):
assert isinstance(page, Page)
@@ -713,6 +719,16 @@
self.messages = list()
+ # This will be the value of the csrf tag if
+ # it was passed in the request
+ self.csrf_value = None
+ self.post = False
+
+ def check_csrf(self):
+ if self.client_session.get_csrf() != self.csrf_value:
+ log.info("Possible CSRF attempt using %s" % self)
+ raise CSRFException("Possible CSRF attempt")
+
def branch(self):
session = Session(self.page)
session.trunk = self
@@ -792,7 +808,7 @@
vars.append("%s=%s" % (key, svalue))
return separator.join(vars)
-
+
def gather_values(self):
if self.trunk is None:
return self.values_by_path
@@ -844,6 +860,8 @@
if param:
param.add(self, param.unmarshal(value), key)
+ elif key == self.csrf_tag_name:
+ self.csrf_value = value
def marshal_cookies(self, secure_cookies):
"""
Modified: trunk/wooly/python/wooly/forms.py
===================================================================
--- trunk/wooly/python/wooly/forms.py 2012-09-26 11:57:06 UTC (rev 5474)
+++ trunk/wooly/python/wooly/forms.py 2012-09-26 12:06:17 UTC (rev 5475)
@@ -18,7 +18,7 @@
def validate(self, session):
log.debug("Validating %s", self)
-
+
def render_hidden_inputs(self, session, *args):
writer = Writer()
@@ -45,6 +45,12 @@
svalue = param.marshal(value)
self.write_hidden_input(key, svalue, writer)
+ # Generate this explicitly. This value is never set in the
+ # session except during processing of a POST
+ self.write_hidden_input(session.csrf_tag_name,
+ session.client_session.get_csrf(),
+ writer)
+
return writer.to_string()
def write_hidden_input(self, name, value, writer):
Modified: trunk/wooly/python/wooly/server.py
===================================================================
--- trunk/wooly/python/wooly/server.py 2012-09-26 11:57:06 UTC (rev 5474)
+++ trunk/wooly/python/wooly/server.py 2012-09-26 12:06:17 UTC (rev 5475)
@@ -121,6 +121,8 @@
if last_modified is None or last_requested is None \
or last_modified > last_requested:
try:
+ if session.post:
+ session.check_csrf()
content = page.service(session)
status = "200 OK"
except PageRedirect:
@@ -170,7 +172,8 @@
def adapt_request_to_session(self, env, session):
session.unmarshal_url_vars(env["QUERY_STRING"])
- if env["REQUEST_METHOD"] == "POST":
+ session.post = env["REQUEST_METHOD"] == "POST"
+ if session.post:
content_type = env["CONTENT_TYPE"]
if content_type == "application/x-www-form-urlencoded":
@@ -305,6 +308,8 @@
class ClientSession(object):
def __init__(self):
self.id = unique_id()
+ self.reset_csrf()
+
self.created = datetime.now()
self.visited = None
@@ -313,6 +318,12 @@
def check_owner(self, owner):
user = self.attributes["login_session"].user.name
return owner == user
+
+ def get_csrf(self):
+ return self.csrf
+
+ def reset_csrf(self):
+ self.csrf = unique_id()
def __repr__(self):
args = (self.__class__.__name__, self.id, self.created)
11 years, 7 months
r5474 - in trunk: cumin/python/cumin cumin/python/cumin/account wooly/python/wooly
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-09-26 11:57:06 +0000 (Wed, 26 Sep 2012)
New Revision: 5474
Modified:
trunk/cumin/python/cumin/account/widgets.py
trunk/cumin/python/cumin/widgets.py
trunk/wooly/python/wooly/server.py
Log:
Session id regeneration fix
BZ840123
Modified: trunk/cumin/python/cumin/account/widgets.py
===================================================================
--- trunk/cumin/python/cumin/account/widgets.py 2012-09-26 11:52:54 UTC (rev 5473)
+++ trunk/cumin/python/cumin/account/widgets.py 2012-09-26 11:57:06 UTC (rev 5474)
@@ -147,7 +147,12 @@
if user is None:
user = name
login = LoginSession(self.app, user, roles)
- session.client_session.attributes["login_session"] = login
+
+ # We want to generate a new session id and record the
+ # login while keeping the rest of the session data.
+ # This is to protect against session fixation attacks.
+ self.app.server.reset_client_session_id(session, login)
+
url = self.page.origin.get(session)
self.page.redirect.set(session, url)
else:
Modified: trunk/cumin/python/cumin/widgets.py
===================================================================
--- trunk/cumin/python/cumin/widgets.py 2012-09-26 11:52:54 UTC (rev 5473)
+++ trunk/cumin/python/cumin/widgets.py 2012-09-26 11:57:06 UTC (rev 5474)
@@ -1363,7 +1363,11 @@
if user is None:
user = username
login = LoginSession(self.app, user, roles)
- session.client_session.attributes["login_session"] = login
+
+ # We want to generate a new session id and record the
+ # login while keeping the rest of the session data.
+ # This is to protect against session fixation attacks.
+ self.app.server.reset_client_session_id(session, login)
return True
return False
Modified: trunk/wooly/python/wooly/server.py
===================================================================
--- trunk/wooly/python/wooly/server.py 2012-09-26 11:52:54 UTC (rev 5473)
+++ trunk/wooly/python/wooly/server.py 2012-09-26 11:57:06 UTC (rev 5474)
@@ -200,12 +200,30 @@
self.client_sessions_by_id[csession.id] = csession
session.set_cookie("session", csession.id)
- log.debug("Created %s", csession)
-
csession.visited = datetime.now()
-
return csession
+ def reset_client_session_id(self, session, login):
+
+ # Take the client session out of the dict.
+ # We're going to insert a new one. Running threads that
+ # have a reference will continue to execute...
+ try:
+ del self.client_sessions_by_id[session.client_session.id]
+ except KeyError:
+ pass
+
+ nclient = ClientSession()
+ # we've already got copy.copy from wooly.util
+ nclient.attributes = copy(session.client_session.attributes)
+ nclient.attributes["login_session"] = login
+ nclient.visited = datetime.now()
+ self.client_sessions_by_id[nclient.id] = nclient
+
+ # ...and reset the cookie for the broswer
+ session.client_session = nclient
+ session.set_cookie("session", session.client_session.id)
+
def __repr__(self):
return "%s(%s,%i)" % (self.__class__.__name__, self.host, self.port)
@@ -320,7 +338,11 @@
for session in self.server.client_sessions_by_id.values():
if session.visited is not None and session.visited < when:
- del self.server.client_sessions_by_id[session.id]
- count += 1
+ try:
+ del self.server.client_sessions_by_id[session.id]
+ count += 1
+ except KeyError:
+ pass
+
log.info("Expired %i client sessions", count)
11 years, 7 months
r5473 - in trunk: cumin/python/cumin rosemary/python/rosemary
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-09-26 11:52:54 +0000 (Wed, 26 Sep 2012)
New Revision: 5473
Modified:
trunk/cumin/python/cumin/admin.py
trunk/cumin/python/cumin/model.py
trunk/rosemary/python/rosemary/model.py
trunk/rosemary/python/rosemary/sqlfilter.py
Log:
Properly quote values in constructed SQL queries
BZ840112
Modified: trunk/cumin/python/cumin/admin.py
===================================================================
--- trunk/cumin/python/cumin/admin.py 2012-09-26 11:45:28 UTC (rev 5472)
+++ trunk/cumin/python/cumin/admin.py 2012-09-26 11:52:54 UTC (rev 5473)
@@ -155,7 +155,8 @@
mapping_cls.user.sql_column)
#TODO: one column ?
cols = [ role_cls.name.sql_column ]
- filt = SqlComparisonFilter(user_cls._id.sql_column, user._id, '=')
+ filt = SqlComparisonFilter(user_cls._id.sql_column, user._id,
+ gen_cursor = self.app.database.get_read_cursor)
query.add_filter(filt)
sql = query.emit(cols)
cursor.execute(sql)
Modified: trunk/cumin/python/cumin/model.py
===================================================================
--- trunk/cumin/python/cumin/model.py 2012-09-26 11:45:28 UTC (rev 5472)
+++ trunk/cumin/python/cumin/model.py 2012-09-26 11:52:54 UTC (rev 5473)
@@ -321,7 +321,8 @@
def __init__(self, app, cls, sig, session, extra_filters=None):
super(SamplesSqlAdapter, self).__init__(app, cls.sql_samples_table)
- filters = cls.get_sample_filters_by_signature(sig)
+ filters = cls.get_sample_filters_by_signature(sig,
+ self.app.database.get_read_cursor)
for f in filters:
self.query.add_filter(f)
Modified: trunk/rosemary/python/rosemary/model.py
===================================================================
--- trunk/rosemary/python/rosemary/model.py 2012-09-26 11:45:28 UTC (rev 5472)
+++ trunk/rosemary/python/rosemary/model.py 2012-09-26 11:52:54 UTC (rev 5473)
@@ -629,8 +629,9 @@
self.sql_samples_insert.execute(cursor, obj.__dict__, columns=columns)
- def get_sample_filters_by_signature(self, sig):
- # by default, there are no sample_filters, if you need them, please override this
+ def get_sample_filters_by_signature(self, sig, gen_cursor):
+ # by default, there are no sample_filters, if you need them,
+ # please override this
return []
def delete_object(self, cursor, obj):
@@ -751,16 +752,18 @@
agent_id = agent_id.replace("|", ":")
return self.get_object_by_qmf_id(cursor, agent_id, obj_id)
- def get_sample_filters_by_signature(self, signature):
+ def get_sample_filters_by_signature(self, signature, gen_cursor):
agent_id, obj_id = signature
agent_id = agent_id.replace("|", ":")
filters = []
col = self.sql_samples_table._qmf_agent_id
- filters.append(SqlComparisonFilter(col, "'%s'" % agent_id))
+ filters.append(SqlComparisonFilter(col, agent_id,
+ gen_cursor=gen_cursor))
col = self.sql_samples_table._qmf_object_id
- filters.append(SqlComparisonFilter(col, "'%s'" % obj_id))
+ filters.append(SqlComparisonFilter(col, obj_id,
+ gen_cursor=gen_cursor))
return filters
Modified: trunk/rosemary/python/rosemary/sqlfilter.py
===================================================================
--- trunk/rosemary/python/rosemary/sqlfilter.py 2012-09-26 11:45:28 UTC (rev 5472)
+++ trunk/rosemary/python/rosemary/sqlfilter.py 2012-09-26 11:52:54 UTC (rev 5473)
@@ -6,18 +6,68 @@
pass
class SqlComparisonFilter(SqlFilter):
- def __init__(self, this, that, operator="="):
+ '''
+ Emit a comparison filter for a SQL query.
+
+ The filter will be of the form 'this op that'.
+
+ If a cursor generation callback is provided and
+ 'mogrify' indicates that any of the three arguments
+ may need special quoting, the psycopg2.cursor.mogrify()
+ routine will be used to produce a filter with
+ correctly quoted values.
+
+ If 'gen_cursor' is None or 'mogrify' does not specify
+ any values to be quoted, simple concatenation will be done.
+
+ gen_cursor -- callback to retreive a pyscopg2
+ cursor, invoked as gen_cursor()
+
+ mogrify -- which values need to be quoted. This is an
+ ordered tuple of booleans corresponding to 'this', 'operator',
+ and 'that'. The default is False, False, True since 'this'
+ and 'operator' typically come directly from code but 'that'
+ may originate outside of the program.
+ '''
+ def __init__(self, this, that,
+ operator="=",
+ gen_cursor=None,
+ mogrify=(False,False,True)):
+
super(SqlComparisonFilter, self).__init__()
assert isinstance(operator, str)
+ assert len(mogrify) == 3
self.this = getattr(this, "identifier", this)
self.that = getattr(that, "identifier", that)
self.operator = operator
+ self.gen_cursor = gen_cursor
+ self.mogrify = mogrify
+
+ def _mogrify(self):
+ pattern = []
+ vals = []
+ for elem in zip((self.this, self.operator, self.that), self.mogrify):
+ if elem[1]:
+ # We want to mogrify this
+ pattern.append("%s")
+ vals.append(elem[0])
+ else:
+ # make this a literal
+ pattern.append(elem[0])
+ pattern = " ".join(pattern)
+ cursor = self.gen_cursor()
+ return cursor.mogrify(pattern, vals)
def emit(self):
- return "%s %s %s" % (self.this, self.operator, self.that)
+ if self.gen_cursor and True in self.mogrify:
+ return self._mogrify()
+ return "%s %s %s" % (self.this,
+ self.operator,
+ self.that)
+
class SqlValueFilter(SqlComparisonFilter):
def __init__(self, this, operator="="):
that = "%%(%s)s" % this.name
11 years, 7 months
r5472 - trunk/wooly/python/wooly
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-09-26 11:45:28 +0000 (Wed, 26 Sep 2012)
New Revision: 5472
Modified:
trunk/wooly/python/wooly/__init__.py
Log:
Escape text in error trace display
BZ840133
Modified: trunk/wooly/python/wooly/__init__.py
===================================================================
--- trunk/wooly/python/wooly/__init__.py 2012-09-26 11:43:19 UTC (rev 5471)
+++ trunk/wooly/python/wooly/__init__.py 2012-09-26 11:45:28 UTC (rev 5472)
@@ -600,7 +600,7 @@
self.print_url_vars(env["QUERY_STRING"], writer)
self.print_environment(env, writer)
- return "<pre><![CDATA[%s]]></pre>" % writer.to_string()
+ return "<pre>%s</pre>" % xml_escape(writer.to_string())
def print_messages(self, writer):
writer.write("Messages:\n\n")
11 years, 7 months
r5471 - in trunk: cumin/bin cumin/python/cumin wooly/python/wooly
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-09-26 11:43:19 +0000 (Wed, 26 Sep 2012)
New Revision: 5471
Modified:
trunk/cumin/bin/cumin-web
trunk/cumin/python/cumin/config.py
trunk/cumin/python/cumin/main.py
trunk/cumin/python/cumin/server.py
trunk/wooly/python/wooly/__init__.py
trunk/wooly/python/wooly/server.py
Log:
Use secure cookies when SSL is enabled
BZ831203
Modified: trunk/cumin/bin/cumin-web
===================================================================
--- trunk/cumin/bin/cumin-web 2012-09-18 19:52:58 UTC (rev 5470)
+++ trunk/cumin/bin/cumin-web 2012-09-26 11:43:19 UTC (rev 5471)
@@ -202,6 +202,7 @@
cumin = Cumin(config.get_home(), broker_uris, opts.database,
opts.host, opts.port,
opts.server_cert, opts.server_key,
+ values.force_secure_cookies,
values.persona, authmech)
# If the mech_list was set explicitly, honor it.
Modified: trunk/cumin/python/cumin/config.py
===================================================================
--- trunk/cumin/python/cumin/config.py 2012-09-18 19:52:58 UTC (rev 5470)
+++ trunk/cumin/python/cumin/config.py 2012-09-26 11:43:19 UTC (rev 5471)
@@ -178,6 +178,9 @@
param = ConfigParameter(self, "authorize", bool)
param.default = False
+ param = ConfigParameter(self, "force-secure-cookies", bool)
+ param.default = False
+
# param = ConfigParameter(self, "auth-proxy", bool)
# param.default = False
Modified: trunk/cumin/python/cumin/main.py
===================================================================
--- trunk/cumin/python/cumin/main.py 2012-09-18 19:52:58 UTC (rev 5470)
+++ trunk/cumin/python/cumin/main.py 2012-09-26 11:43:19 UTC (rev 5471)
@@ -35,12 +35,16 @@
def __init__(self, home, broker_uris, database_dsn,
host="localhost", port=45672,
server_cert="", server_key="",
+ force_secure_cookies=False,
persona="default",
authmech=[]):
super(Cumin, self).__init__()
self.home = home
self.authmech = authmech
+ # For use behind a proxy, when Cumin does not
+ # have ssl enabled but the proxy does.
+ self.force_secure_cookies = force_secure_cookies
# Settings for LDAP authentication
self.ldap_timeout = None
Modified: trunk/cumin/python/cumin/server.py
===================================================================
--- trunk/cumin/python/cumin/server.py 2012-09-18 19:52:58 UTC (rev 5470)
+++ trunk/cumin/python/cumin/server.py 2012-09-26 11:43:19 UTC (rev 5471)
@@ -8,6 +8,12 @@
# Elements of WebServer will look for the cert/key fields
self.server_cert = server_cert
self.server_key = server_key
+
+ # If ssl is enabled successfully, this flag will be set
+ # to true.
+ self.ssl_enabled = False
+ self.force_secure_cookies = app.force_secure_cookies
+
super(CuminServer, self).__init__(app, host, port)
def authorized(self, session):
Modified: trunk/wooly/python/wooly/__init__.py
===================================================================
--- trunk/wooly/python/wooly/__init__.py 2012-09-18 19:52:58 UTC (rev 5470)
+++ trunk/wooly/python/wooly/__init__.py 2012-09-26 11:43:19 UTC (rev 5471)
@@ -845,7 +845,7 @@
if param:
param.add(self, param.unmarshal(value), key)
- def marshal_cookies(self):
+ def marshal_cookies(self, secure_cookies):
"""
Produce a list of strings representing cookies newly set on
this session.
@@ -867,6 +867,9 @@
when = expires.strftime(self.http_date_gmt)
crumbs.append("expires=%s" % when)
+ if secure_cookies:
+ crumbs.append("secure")
+
headers.append("; ".join(crumbs))
return headers
Modified: trunk/wooly/python/wooly/server.py
===================================================================
--- trunk/wooly/python/wooly/server.py 2012-09-18 19:52:58 UTC (rev 5470)
+++ trunk/wooly/python/wooly/server.py 2012-09-26 11:43:19 UTC (rev 5471)
@@ -161,7 +161,8 @@
if cache:
headers.append(("Cache-Control", cache))
- for header in session.marshal_cookies():
+ secure_cookies = self.ssl_enabled or self.force_secure_cookies
+ for header in session.marshal_cookies(secure_cookies):
headers.append(("Set-Cookie", header))
return status, headers, content
@@ -249,6 +250,7 @@
log.warn("Webserver: SSL was requested, but imports failed "
"for SSL implementations. Running with http only.")
else:
+ self.server.ssl_enabled = True
self.wsgi_server.ssl_adapter = ssl_adapter
self.wsgi_server.environ["wsgi.version"] = (1, 1)
11 years, 7 months
r5470 - trunk/wooly/python/wooly
by croberts@fedoraproject.org
Author: croberts
Date: 2012-09-18 19:52:58 +0000 (Tue, 18 Sep 2012)
New Revision: 5470
Modified:
trunk/wooly/python/wooly/util.py
Log:
Addressing BZ 809006 by tweaking our xml_escape routine to first unescape the given string (in case it was already escaped...or contained some escaped characters) and then perform the usual xml_escape sequence.
Modified: trunk/wooly/python/wooly/util.py
===================================================================
--- trunk/wooly/python/wooly/util.py 2012-09-14 18:42:21 UTC (rev 5469)
+++ trunk/wooly/python/wooly/util.py 2012-09-18 19:52:58 UTC (rev 5470)
@@ -24,9 +24,10 @@
def xml_escape(string, entities=None):
if type(string) in (str, unicode):
+ unescaped = unescape_entity(string)
if entities is None:
entities = quote_entities
- return escape(string, entities)
+ return escape(unescaped, entities)
return string
def unique_id():
11 years, 8 months