Author: tmckay
Date: 2013-12-20 16:43:39 +0000 (Fri, 20 Dec 2013)
New Revision: 5791
Modified:
branches/statusquo/cumin/python/cumin/grid/limit.py
branches/statusquo/cumin/python/cumin/grid/tags.py
branches/statusquo/cumin/python/cumin/model.py
branches/statusquo/cumin/python/cumin/objectselector.py
branches/statusquo/wooly/python/wooly/__init__.py
branches/statusquo/wooly/python/wooly/forms.py
branches/statusquo/wooly/python/wooly/server.py
Log:
Add a unified patch for
BZ1017425
BZ1017427
Modified: branches/statusquo/cumin/python/cumin/grid/limit.py
===================================================================
--- branches/statusquo/cumin/python/cumin/grid/limit.py 2013-12-20 16:40:19 UTC (rev
5790)
+++ branches/statusquo/cumin/python/cumin/grid/limit.py 2013-12-20 16:43:39 UTC (rev
5791)
@@ -1,3 +1,4 @@
+from cumin.util import xml_escape
from cumin.formats import fmt_link
from cumin.objectframe import ObjectFrame, ObjectFrameTask, \
ObjectFrameTaskForm
@@ -18,11 +19,18 @@
log = logging.getLogger("cumin.limit")
LIMIT_FLOAT_VALUE_FOR_UNLIMITED = 1000000.0
+def _limit_max(limit_max):
+ try:
+ limit_max = float(limit_max)
+ if limit_max >= LIMIT_FLOAT_VALUE_FOR_UNLIMITED:
+ limit_max = "Unlimited"
+ except:
+ limit_max = 0
+ return limit_max
+
class LimitAdapter(ObjectQmfAdapter):
def get_negotiator(self, session):
- cls = self.app.model.com_redhat_grid.Negotiator
- negotiator = self.app.model.find_youngest(cls, session.cursor)
- return negotiator
+ return self.app.model.get_negotiator(session)
def get_count(self, values):
data = self.do_get_data(values)
@@ -72,7 +80,6 @@
negotiator = self.parent.adapter.get_negotiator(session)
self.frame.limit.id.set(session, negotiator._id)
self.frame.limit.set_limit.form.limit_name.set(session, limit_name)
- self.frame.limit.set_limit.form.limit_max.set(session, limit_max)
return limit_name
class UsageColumn(ObjectTableColumn):
@@ -90,12 +97,7 @@
def render_cell_content(self, session, data):
value = None
limit_max = super(LimitTable.MaxColumn, self).render_cell_content(session,
data)
- try:
- limit_max = float(limit_max)
- if limit_max >= LIMIT_FLOAT_VALUE_FOR_UNLIMITED:
- limit_max = "Unlimited"
- except:
- limit_max = 0
+ limit_max = _limit_max(limit_max)
# if we are exporting csv, we don't want to return a link, so we check
here
if session.page == self.app.export_page:
@@ -146,7 +148,6 @@
def do_enter(self, session, osession):
self.form.limit_name.set(session, self.form.limit_name.get(osession))
- self.form.limit_max.set(session, self.form.limit_max.get(osession))
def do_invoke(self, invoc, negotiator, limit_name, limit_max):
@@ -186,12 +187,35 @@
self.limit_max = self.LimitMax(app, "max")
self.limit_max.required = True
self.add_field(self.limit_max)
-
+
+ def do_process(self, session):
+ super(NegotiatorLimitForm, self).do_process(session)
+ neg = self.app.model.get_negotiator(session)
+ limits = self.app.model.get_negotiator_limits(neg)
+ try:
+ my_limit = limits.data[self.limit_name.get(session)]['MAX']
+ except:
+ my_limit = 0
+ self.limit_max.set(session, _limit_max(my_limit))
+
+ def _validate_limit_name(self, session):
+ value = self.limit_name.get(session)
+ message = None
+ if value:
+ neg = self.app.model.get_negotiator(session)
+ limits = self.app.model.get_negotiator_limits(neg)
+ if value not in limits.data:
+ message = "Limit '%s' does not exist, press Cancel" %
value
+
+ if message:
+ self.errors.add(session, FormError(message))
+
def process_submit(self, session):
new_max_value = self.limit_max.input.get(session)
unlimited_check_value = self.limit_max.checkbox.param.get(session)
self.limit_max.validate(session)
+ self._validate_limit_name(session)
if not self.errors.get(session):
if new_max_value.lower() in ("unlimited", "na",
"n/a") or float(new_max_value) >= LIMIT_FLOAT_VALUE_FOR_UNLIMITED:
self.limit_max.set(session, LIMIT_FLOAT_VALUE_FOR_UNLIMITED)
@@ -225,10 +249,10 @@
return writer.to_string()
def render_field_value(self,session):
- return self.input.get(session)
+ return xml_escape(self.input.get(session))
def render_field_name(self,session):
- return self.input.param.path
+ return xml_escape(self.input.param.path)
def render_is_readonly(self, session):
retval = ""
@@ -260,8 +284,8 @@
return "Limit name"
class DisabledInput(StringInput):
- # used to override html and css
- pass
+ def validate_on_unmarshal(self, param, value, session):
+ return True
class LimitMax(StringFieldWithCheckbox):
def render_title(self, session):
Modified: branches/statusquo/cumin/python/cumin/grid/tags.py
===================================================================
--- branches/statusquo/cumin/python/cumin/grid/tags.py 2013-12-20 16:40:19 UTC (rev 5790)
+++ branches/statusquo/cumin/python/cumin/grid/tags.py 2013-12-20 16:43:39 UTC (rev 5791)
@@ -578,6 +578,10 @@
def render_form_class(self, session):
return " ".join((super(RemoveTags, self).render_form_class(session),
"mform"))
+
+class DisabledInput(StringInput):
+ def validate_on_unmarshal(self, param, value, session):
+ return True
class EditNodeTagsForm(ObjectFrameTaskForm):
'''
@@ -679,7 +683,7 @@
def __init__(self, app, name):
super(EditNodeTagsForm.NodeName, self).__init__(app, name)
- self.input = self.DisabledInput(app, "input")
+ self.input = DisabledInput(app, "input")
self.replace_child(self.input)
def get(self,session):
@@ -689,14 +693,11 @@
def render_title(self, session):
return "Host name"
- class DisabledInput(StringInput):
- pass
-
class Tags(StringField):
def __init__(self, app, name):
super(EditNodeTagsForm.Tags, self).__init__(app, name)
- self.input = self.DisabledInput(app, "input")
+ self.input = DisabledInput(app, "input")
self.replace_child(self.input)
def render_title(self, session):
@@ -716,9 +717,6 @@
value = truncate_text(value, 50, True)
return value
- class DisabledInput(StringInput):
- pass
-
class EditTagNodesForm(ObjectFrameTaskForm):
'''
This form will allow the editing of nodes for a single given tag
@@ -728,24 +726,21 @@
self.tags = self.Tags(app, "tags")
self.add_field(self.tags)
-
+
self.node_name = self.NodeName(app, "node_name")
self.add_field(self.node_name)
-
+
self.possible_nodes = self.NodesList(app, "pnod")
self.add_field(self.possible_nodes)
self.update_enabled = False
-
-
+
def process_submit(self, session):
tag = self.tags.input.get(session)
nodes_value = self.possible_nodes.get(session)
self.tags.validate(session)
if not self.errors.get(session):
- self.tags.set(session, tag)
-
self.task.invoke(session, None, tag, nodes_value)
self.task.exit_with_redirect(session)
@@ -812,7 +807,7 @@
def __init__(self, app, name):
super(EditTagNodesForm.NodeName, self).__init__(app, name)
- self.input = self.DisabledInput(app, "input")
+ self.input = DisabledInput(app, "input")
self.replace_child(self.input)
def render_inputs(self, session, *args):
@@ -824,16 +819,26 @@
def render_title(self, session):
return "Current hosts"
-
- class DisabledInput(StringInput):
- pass
class Tags(StringField):
def __init__(self, app, name):
super(EditTagNodesForm.Tags, self).__init__(app, name)
- self.input = self.DisabledInput(app, "input")
+ self.input = DisabledInput(app, "input")
self.replace_child(self.input)
+
+ def validate(self, session):
+ # We don't want to create tags here, just edit an existing
+ # tag. So make sure it exists,
+ super(EditTagNodesForm.Tags, self).validate(session)
+ message = None
+ if not self.form.errors.get(session):
+ t = self.input.get(session)
+ if self.app.wallaby.get_tag_by_name(t) is None:
+ message = "Tag '%s' does not exist, press cancel" %
t
+
+ if message:
+ self.form.errors.add(session, FormError(message))
def render_title(self, session):
return "Tag"
@@ -841,9 +846,6 @@
def get(self,session):
value = self.input.get(session)
return value
-
- class DisabledInput(StringInput):
- pass
class EditTagFeaturesForm(ObjectFrameTaskForm):
'''
@@ -862,8 +864,7 @@
self.add_field(self.possible_features)
self.update_enabled = False
-
-
+
def process_submit(self, session):
tag = self.tags.input.get(session)
features_value = self.possible_features.get(session)
@@ -931,7 +932,7 @@
def __init__(self, app, name):
super(EditTagFeaturesForm.FeatureName, self).__init__(app, name)
- self.input = self.DisabledInput(app, "input")
+ self.input = DisabledInput(app, "input")
self.replace_child(self.input)
def render_inputs(self, session, *args):
@@ -947,16 +948,24 @@
def render_title(self, session):
return "Current features"
-
- class DisabledInput(StringInput):
- pass
class Tags(StringField):
def __init__(self, app, name):
super(EditTagFeaturesForm.Tags, self).__init__(app, name)
- self.input = self.DisabledInput(app, "input")
+ self.input = DisabledInput(app, "input")
self.replace_child(self.input)
+
+ def validate(self, session):
+ super(EditTagFeaturesForm.Tags, self).validate(session)
+ message = None
+ if not self.form.errors.get(session):
+ t = self.input.get(session)
+ if self.app.wallaby.get_tag_by_name(t) is None:
+ message = "Tag '%s' does not exist, press cancel" %
t
+
+ if message:
+ self.form.errors.add(session, FormError(message))
def render_title(self, session):
return "Tag"
@@ -964,9 +973,6 @@
def get(self,session):
value = self.input.get(session)
return value
-
- class DisabledInput(StringInput):
- pass
class TagsNodeEditTask(ObjectFrameTask):
'''
@@ -1020,12 +1026,6 @@
def do_enter(self, session, osession):
tag_id = osession.values_by_path["main.grid.tag.id"]
self.form.tags.set(session, tag_id)
-
- nodes = "No nodes currently assigned"
- node_list = self.app.wallaby.get_node_names(tag_id)
- if len(node_list) > 0:
- nodes = ", ".join(node_list)
- self.form.node_name.set(session, nodes)
def callback(self, result):
if result is not None:
@@ -1097,14 +1097,6 @@
def do_enter(self, session, osession):
tag_id = osession.values_by_path["main.grid.tag.id"]
self.form.tags.set(session, tag_id)
- features = "No features currently assigned"
- tag = self.app.wallaby.get_tag_by_name(tag_id)
- feature_list = list()
- if tag is not None:
- feature_list = tag.features
- if len(feature_list) > 0:
- features = ", ".join(feature_list)
- self.form.feature_name.set(session, features)
def callback(self, result):
if result == False:
Modified: branches/statusquo/cumin/python/cumin/model.py
===================================================================
--- branches/statusquo/cumin/python/cumin/model.py 2013-12-20 16:40:19 UTC (rev 5790)
+++ branches/statusquo/cumin/python/cumin/model.py 2013-12-20 16:43:39 UTC (rev 5791)
@@ -249,9 +249,14 @@
return job_server
def get_scheduler_from_jobserver(self, session, job_server):
- cls = self.app.model.com_redhat_grid.Scheduler
+ cls = self.com_redhat_grid.Scheduler
return cls.get_object(session.cursor, _id=job_server._schedulerRef_id)
+ def get_negotiator(self, session):
+ cls = self.com_redhat_grid.Negotiator
+ negotiator = self.find_youngest(cls, session.cursor)
+ return negotiator
+
class CuminProperty(object):
def __init__(self, cls, name):
self.model = cls.model
Modified: branches/statusquo/cumin/python/cumin/objectselector.py
===================================================================
--- branches/statusquo/cumin/python/cumin/objectselector.py 2013-12-20 16:40:19 UTC (rev
5790)
+++ branches/statusquo/cumin/python/cumin/objectselector.py 2013-12-20 16:43:39 UTC (rev
5791)
@@ -302,7 +302,7 @@
self.table.add_child(self.table.export)
def add_search_filter(self, this):
- search = StringInput(self.app, "search")
+ search = self.SearchInput(self.app, "search")
search.param.default = ""
search.title = "Search in %s column" % this.attr.title
@@ -310,7 +310,7 @@
self.filters.add_child(search)
def add_selectable_search_filter(self, inputSet):
- search = StringInput(self.app, "search")
+ search = self.SearchInput(self.app, "search")
search.param.default = ""
search.title = "Search in column"
search.size = 35
@@ -318,7 +318,6 @@
self.selectablefilters.add_child(search)
self.selectablefilters.add_child(inputSet)
-
def render_search_id(self, session):
if len(self.filters.children):
return self.filters.children[0].render_id(session)
@@ -350,6 +349,10 @@
def get_data_options(self, session):
return self.table.get_data_options(session)
+ class SearchInput(StringInput):
+ def validate_on_unmarshal(self, value, param, session):
+ return True
+
class ObjectSelectorTable(ObjectTable):
def __init__(self, app, name, cls):
super(ObjectSelectorTable, self).__init__(app, name, cls)
@@ -504,6 +507,11 @@
def render_select_box(self, session):
return self.parent.children_by_name['search'].path
+ def validate_on_unmarshal(self, param, value, session):
+ if param == self.operator_param:
+ return value in self.operator_selector.do_get_items(session)
+ return True
+
class SearchOperatorOptions(OptionInputSet):
def __init__(self, app, param):
super(SelectableSearchObjectTable.SearchFieldOptions.SearchOperatorOptions,
self).__init__(app, "operator_input", param)
Modified: branches/statusquo/wooly/python/wooly/__init__.py
===================================================================
--- branches/statusquo/wooly/python/wooly/__init__.py 2013-12-20 16:40:19 UTC (rev 5790)
+++ branches/statusquo/wooly/python/wooly/__init__.py 2013-12-20 16:43:39 UTC (rev 5791)
@@ -429,6 +429,9 @@
def get_redirect(self, session):
return self.page.redirect.get(session)
+ def validate_on_unmarshal(self, param, value, session):
+ return True
+
class Frame(Widget):
def show(self, session):
super(Frame, self).show(session)
@@ -942,6 +945,7 @@
unmarshal = classmethod(unmarshal)
def unmarshal_url_vars(self, string, separator=";"):
+ from wooly.forms import FormInput
vars = string.split(separator)
for var in vars:
@@ -954,9 +958,13 @@
value = unquote_plus(svalue)
param = self.page.get_page_parameter_by_path(key)
-
if param:
+ if not param.widget.validate_on_unmarshal(param, value, self):
+ # Don't try setting a form input anywhere other than
+ # the file stream of a POST request!
+ raise Exception("Illegal attempt to set parameter %s" %
param)
param.add(self, param.unmarshal(value), key)
+
elif key == self.csrf_tag_name:
self.csrf_value = value
Modified: branches/statusquo/wooly/python/wooly/forms.py
===================================================================
--- branches/statusquo/wooly/python/wooly/forms.py 2013-12-20 16:40:19 UTC (rev 5790)
+++ branches/statusquo/wooly/python/wooly/forms.py 2013-12-20 16:43:39 UTC (rev 5791)
@@ -129,6 +129,11 @@
def render_disabled_attr(self, session, *args):
return self.disabled and "disabled=\"disabled\"" or None
+ def validate_on_unmarshal(self, param, value, session):
+ # By default, disallow FormInputs except in a
+ # wsgi input stream for POST
+ return session.post
+
class MissingValueError(FormError):
def __init__(self, widget):
super(MissingValueError, self).__init__(None)
Modified: branches/statusquo/wooly/python/wooly/server.py
===================================================================
--- branches/statusquo/wooly/python/wooly/server.py 2013-12-20 16:40:19 UTC (rev 5790)
+++ branches/statusquo/wooly/python/wooly/server.py 2013-12-20 16:43:39 UTC (rev 5791)
@@ -219,11 +219,7 @@
def adapt_request_to_session(self, env, session):
- try:
- session.unmarshal_url_vars(env["QUERY_STRING"])
- except:
- # allow exceptions to pass so we can trap ReosmaryNotFound later
- pass
+ session.unmarshal_url_vars(env["QUERY_STRING"])
session.post = env["REQUEST_METHOD"] == "POST"
if session.post: