class FieldsSchema(validators.Schema): chained_validators = [validators.FieldsMatch('passwd', 'passwd2')] name = validators.UnicodeString() age = validators.Int() passwd = validators.NotEmpty() passwd2 = validators.UnicodeString()
class UserFormSchema(validators.Schema): user_id = validators.Int() user_name = validators.UnicodeString(not_empty=True, strip=True) display_name = validators.UnicodeString(not_empty=True, strip=True) disabled = validators.StringBool(if_empty=False) email_address = validators.Email(not_empty=True, strip=True) chained_validators = [beaker_validators.UniqueUserName('user_id', 'user_name')]
class AclName(validators.Schema): '''Validator for the acls.name method''' # validator schemas don't have methods (R0903, W0232) #pylint:disable-msg=R0903,W0232 packageName = validators.UnicodeString(not_empty=True, strip=True) collectionName = validators.UnicodeString(not_empty=False, strip=True) collectionVersion = validators.UnicodeString(not_empty=False, strip=True) eol = validators.StringBool()
class GroupFormSchema(validators.Schema): display_name = validators.UnicodeString( not_empty=True, max=Group.display_name.property.columns[0].type.length, strip=True) group_name = validators.UnicodeString( not_empty=True, max=Group.group_name.property.columns[0].type.length, strip=True) root_password = StrongPassword() ldap = validators.StringBool(if_empty=False)
class NotifyList(validators.Schema): '''Validator schema for the notify method.''' # validator schemas don't have methods (R0903, W0232) #pylint:disable-msg=R0903,W0232 # We don't use a more specific validator for collection or version because # the chained validator does it for us and we don't want to hit the # database multiple times name = validators.UnicodeString(not_empty=False, strip=True) version = validators.UnicodeString(not_empty=False, strip=True) eol = validators.StringBool() chained_validators = (CollectionNameVersion(), )
class UserEditSchema(validators.Schema): """ separate validation schema from the fields definition make it possible to define a more complex schema that involves field dependency or logical operators """ user_name = validators.String(not_empty=True, max=16) status = validators.OneOf(['ENABLED', 'LOCKED', 'DISABLED']) password = validators.UnicodeString(max=50) password_confirm = validators.UnicodeString(max=50) chained_validators = [ validators.FieldsMatch('password', 'password_confirm') ]
class TagFormSchema(validators.Schema): id = validators.Int() tag = validators.UnicodeString(not_empty=True, max=20, strip=True) default = validators.StringBool(if_empty=False) expire_in_days = validators.Int() needs_product = validators.StringBool(if_empty=False) chained_validators = [UniqueRetentionTag('id', 'tag')]
def test_unicodestring_validator(): v = validators.UnicodeString() assert u'TurboGears' == v.to_python('TurboGears') assert 'TurboGears' == v.from_python('TurboGears') v = validators.UnicodeString(inputEncoding='cp1251') assert repr(v.to_python('\xf0\xf3\xeb\xe8\xf2')) == \ "u'\u0440\u0443\u043b\u0438\u0442'" assert v.from_python(u'\u0440\u0443\u043b\u0438\u0442') == \ '\xd1\x80\xd1\x83\xd0\xbb\xd0\xb8\xd1\x82' # in utf-8 encoding v = validators.UnicodeString() try: # feed cp1251 encoded data when utf8 is expected print repr(v.to_python('\xf0\xf3\xeb\xe8\xf2')) assert 0, 'malformed data not detected' except validators.Invalid: pass
class CommentCaptchaForm(Form): template = "bodhi.templates.captchacommentform" submit_text = "Add Comment" fields = [ TextArea(name='text', label='', validator=validators.All( validators.NotEmpty(), validators.UnicodeString()), rows=3, cols=40), HiddenField(name='title', validator=validators.All( validators.NotEmpty(), validators.UnicodeString())), TextField(name='author', label='Author', default='E-Mail Address', validator=validators.Email()), CaptchaField(name='captcha', label='Enter the code shown') ]
def test_unicode_input(): """Unicode values are rendered correctly""" tf = widgets.TextField("name", validator=validators.UnicodeString()) output = tf.render(u'Pete \u011C', format='xhtml') assert 'value="Pete \xc4\x9c"' in output return # XXX: the folowing causes OTHER(!) tests to fail! try: print tf.render('Pete \xfe\xcd') except ValueError, e: pass
class SearchController(Controller): @expose(template="bodhi.templates.form") def index(self, search=None, tg_errors=None, *args, **kw): if tg_errors: flash(tg_errors) if search: raise redirect('/search/%s' % search) return dict(form=search_form, values={}, action=url('/search/'), title='Search Updates') @expose(template="bodhi.templates.search") @validate(validators={"search": validators.UnicodeString()}) @error_handler(index) @paginate('updates', default_order='-date_submitted', limit=20, max_limit=1000) def default(self, search, *args, **kw): results = set() search = search.strip() # Search name-version-release map( results.add, PackageUpdate.select(LIKE(PackageUpdate.q.title, '%%%s%%' % search), orderBy=PackageUpdate.q.date_submitted)) # Search bug numbers try: map(lambda bug: map(results.add, bug.updates), Bugzilla.select(Bugzilla.q.bz_id == int(search))) except ValueError: # can't convert search search to integer pass # Search CVEs if search.startswith('CVE') or search.startswith('CAN'): # Search bug titles for CVE, since that is how we track them now map(lambda bug: map(results.add, bug.updates), Bugzilla.select(LIKE(Bugzilla.q.title, '%%%s%%' % search))) # We still have some CVE objects lying around, so search them too map(lambda cve: map(results.add, cve.updates), CVE.select(CVE.q.cve_id == search)) # If there is only 1 result, then jump right to it num_items = len(results) if len(results) == 1: raise redirect(results.pop().get_url()) return dict(updates=list(results), num_items=num_items, title="%d Results Found" % num_items)
class CommentForm(Form): template = "bodhi.templates.commentform" submit_text = "Add Comment" fields = [ TextArea(name='text', label='', validator=validators.UnicodeString(), rows=3, cols=40), HiddenField(name='title'), # We're currently hardcoding the karma radio buttons by hand in the # commentform template, because the RadioButtonList is ugly ]
class BuildRootOverrideForm(Form): template = "bodhi.templates.overrideform" fields = [ AutoCompleteField('builds', label='Build', search_controller=url('/new/search'), search_param='name', result_name='pkgs', template='bodhi.templates.packagefield', validator=AutoCompleteValidator()), TextArea('notes', validator=validators.UnicodeString(), rows=13, cols=65), CalendarDatePicker('expiration', not_empty=False) ] submit_text = "Submit"
class GroupCreate(validators.Schema): name = validators.All( UnknownGroup, validators.UnicodeString(max=32, min=3), validators.Regex(regex='^[a-z0-9\-_]+$'), ) display_name = validators.NotEmpty owner = validators.All( KnownUser, validators.NotEmpty, ) prerequisite = KnownGroup group_type = ValidGroupType needs_sponsor = validators.Bool() user_can_remove = validators.Bool() invite_only = validators.Bool()
class GroupSave(validators.Schema): groupname = validators.All( KnownGroup, validators.UnicodeString(max=32, min=2), ) display_name = validators.NotEmpty owner = KnownUser prerequisite = KnownGroup group_type = ValidGroupType invite_only = validators.StringBool needs_sponsor = validators.StringBool user_can_remove = validators.StringBool prerequisite = KnownGroup # or None url = validators.UnicodeString # TODO - Could be more precise. mailing_list = validators.UnicodeString # TODO - Could be more precise. mailing_list_url = validators.UnicodeString # TODO - Could be more precise. irc_channel = validators.UnicodeString # TODO - Could be more precise. irc_network = validators.UnicodeString # TODO - Could be more precise. joinmsg = validators.UnicodeString # TODO - Could be more precise. apply_rules = validators.UnicodeString # TODO - Could be more precise.
def _to_python(self, value, state): tokens = [] if isinstance(value, basestring): tokens = value.split() elif isinstance(value, dict): if isinstance(value['text'], list): tokens = value['text'] else: tokens = [value['text']] elif isinstance(value, (list, tuple)): tokens = value results = [] for token in tokens: if token: for build in token.replace(',', ' ').split(): build = validators.UnicodeString().to_python(build) results.append(PackageValidator().to_python(build)) else: raise Invalid(self.message('empty_build', state), value, state) return results
class OSVersions(AdminPage): # For XMLRPC methods in this class. exposed = False id = widgets.HiddenField(name="id") alias = widgets.TextField(name="alias", validator=validators.UnicodeString(if_empty=None)) arches = CheckBoxList(name="arches", label="Arches", options=lambda: [(arch.id, arch.arch) for arch in Arch.query], validator=validators.Int()) osmajor_form = HorizontalForm( fields = [id, alias], submit_text = _(u"Edit OSMajor"), ) osversion_form = HorizontalForm( fields = [id, arches], action = "edit osversion", submit_text = _(u"Edit OSVersion"), ) def __init__(self,*args,**kw): kw['search_name'] = 'osversion' kw['search_url'] = url("/osversions/by_name?anywhere=1") super(OSVersions,self).__init__(*args,**kw) self.search_col = OSMajor.osmajor self.join = [OSVersion.osmajor] self.search_mapper = OSVersion self.add = False @identity.require(identity.in_group("admin")) @expose(template="bkr.server.templates.form") def edit(self, id=None, *args, **kw): try: osversion = OSVersion.by_id(id) except InvalidRequestError: flash(_(u"Invalid OSVersion ID %s" % id)) redirect(".") return dict(title = unicode(osversion), value = dict(id = osversion.id, arches = [arch.id for arch in osversion.arches]), form = self.osversion_form, action = "./save", options = None) @identity.require(identity.in_group("admin")) @expose(template="bkr.server.templates.osmajor") def edit_osmajor(self, id=None, *args, **kw): try: osmajor = OSMajor.by_id(id) except InvalidRequestError: flash(_(u"Invalid OSMajor ID %s" % id)) redirect(".") return dict(title = "OSMajor", value = osmajor, form = self.osmajor_form, action = "./save_osmajor", options = None) @identity.require(identity.in_group("admin")) @expose() @validate(form=osmajor_form) def save_osmajor(self, id=None, alias=None, *args, **kw): try: osmajor = OSMajor.by_id(id) except InvalidRequestError: flash(_(u"Invalid OSMajor ID %s" % id)) redirect(".") if osmajor.alias != alias: if alias: try: existing = OSMajor.by_name_alias(alias) except NoResultFound: pass else: flash(_(u'Cannot save alias %s, it is already used by %s') % (alias, existing)) redirect('.') osmajor.alias = alias flash(_(u"Changes saved for %s" % osmajor)) else: flash(_(u"No changes for %s" % osmajor)) redirect(".") @identity.require(identity.in_group('admin')) @expose() def save_osmajor_installopts(self, osmajor_id=None, installopts=None): try: osmajor = OSMajor.by_id(osmajor_id) except InvalidRequestError: flash(_(u"Invalid OSMajor ID %s" % id)) redirect(".") for arch, options in installopts.iteritems(): # arch=None means applied to all arches io = OSMajorInstallOptions.lazy_create(osmajor_id=osmajor.id, arch_id=Arch.by_name(arch).id if arch else None) io.ks_meta = options['ks_meta'] io.kernel_options = options['kernel_options'] io.kernel_options_post = options['kernel_options_post'] flash(_(u'Install options saved for %s') % osmajor) redirect('.') @identity.require(identity.in_group("admin")) @expose() @validate(form=osversion_form) def save(self, id=None, arches=None, *args, **kw): try: osversion = OSVersion.by_id(id) except InvalidRequestError: flash(_(u"Invalid OSVersion ID %s" % id)) redirect(".") arch_objects = [Arch.by_id(arch) for arch in arches] if osversion.arches != arch_objects: osversion.arches = arch_objects flash(_(u"Changes Saved for %s" % osversion)) else: flash(_(u"No Changes for %s" % osversion)) redirect(".") @expose(format='json') def by_name(self, input,*args,**kw): input = input.lower() if 'anywhere' in kw: search = OSVersion.list_osmajor_by_name(input, find_anywhere=True) else: search = OSVersion.list_osmajor_by_name(input) osmajors = ["%s" % (match.osmajor.osmajor) for match in search] osmajors = list(set(osmajors)) return dict(matches=osmajors) @expose(template="bkr.server.templates.admin_grid") @paginate('list',limit=50, default_order='osmajor.osmajor') def index(self,*args,**kw): osversions = self.process_search(*args,**kw) list_by_letters = [] for elem in osversions: osmajor_name = elem.osmajor.osmajor if osmajor_name: list_by_letters.append(osmajor_name[0].capitalize()) alpha_nav_data = set(list_by_letters) template_data = self.osversions(osversions,*args, **kw) nav_bar = self._build_nav_bar(alpha_nav_data,self.search_name) template_data['alpha_nav_bar'] = nav_bar template_data['search_widget'] = self.search_widget_form return template_data def osversions(self, osversions=None, *args, **kw): q = session.query(self.search_mapper) # This line +3 dupes the start of process_search if osversions is None: for j in self.join: q = q.join(j) osversions = q osversions_grid = myPaginateDataGrid(fields=[ myPaginateDataGrid.Column(name='osmajor.osmajor', getter=lambda x: make_link(url = './edit_osmajor?id=%s' % x.osmajor.id, text = x.osmajor), title='OS Major', options=dict(sortable=True)), myPaginateDataGrid.Column(name='osmajor.alias', getter=lambda x: x.osmajor.alias, title='Alias', options=dict(sortable=True)), myPaginateDataGrid.Column(name='osminor', getter=lambda x: make_link(url = './edit?id=%s' % x.id, text = x.osminor), title='OS Minor', options=dict(sortable=True)), myPaginateDataGrid.Column(name='arches', getter=lambda x: " ".join([arch.arch for arch in x.arches]), title='Arches', options=dict(sortable=True)), ]) return dict(title="OS Versions", grid = osversions_grid, addable = False, list = osversions) default = index
def _to_python(self, value, state): bugs = validators.UnicodeString().to_python(value.strip()) bugs = bugs.replace(',', ' ').replace('#', '').split() return bugs
class Fields(widgets.WidgetsList): name = widgets.TextField(validator=validators.UnicodeString()) age = widgets.TextField(validator=validators.Int()) passwd = widgets.PasswordField(validator=validators.NotEmpty()) passwd2 = widgets.PasswordField(validator=validators.UnicodeString())
class NewUpdateForm(Form): template = "bodhi.templates.new" submit_text = "Save Update" update_types = config.get('update_types').split() request_types = ['Testing', 'Stable', 'None', None] fields = [ AutoCompleteField('builds', label='Package', search_controller=url('/new/search'), search_param='name', result_name='pkgs', template='bodhi.templates.packagefield', validator=AutoCompleteValidator()), CheckBox('inheritance', label='Follow Build inheritance', validator=validators.StringBool(), default=False, attrs={'title' : 'Build Inheritance - ' 'TODO'}), SingleSelectField('type_', label='Type', options=update_types, validator=validators.OneOf(update_types)), SingleSelectField('request', options=request_types, validator=validators.OneOf(request_types + [r.lower() for r in request_types if r]), default='testing'), TextField('bugs', validator=BugValidator(), attrs={'title' : 'Bug Numbers - A space or comma ' 'delimited list of bug numbers or ' 'aliases. Example: #1234, 789 ' 'CVE-2008-0001'}), TextArea('notes', validator=validators.UnicodeString(), rows=13, cols=65, attrs={'title' : 'Advisory Notes - <p>Some details ' 'about this update that will appear in ' 'the notice.</p>' '<p><strong>Example:</strong><br />' 'This is an update that fixes problems with ' '**<strong>connecting to a share</strong>**.</p>' '<p>The following things *<em>break</em>*:</p>' '<p>* Browsing with `<code>gnome-app-install</code>`<br />' '* Emailing</p>'}), CheckBox(name='close_bugs', help_text='Automatically close bugs', validator=validators.StringBool(), default=True, attrs={'title' : 'Close Bugs - ' 'Automatically close bugs ' 'when this update is ' 'pushed as stable'}), HiddenField('edited', default=None), CheckBox(name='suggest_reboot', label='Suggest Reboot', validator=validators.StringBool(), default=False, attrs={'title': 'Suggest Reboot - ' 'Recommend that the user ' 'restarts their machine ' 'after installing this ' 'update'}), CheckBox(name='autokarma', label='Enable karma automatism', default=True, validator=validators.StringBool(), attrs={'onchange': 'if ($("#form_autokarma").attr("checked")) {' '$("#form_stable_karma").attr("disabled", false);' 'if ($("#form_stable_karma").attr("value") == 0) $("#form_stable_karma").attr("value", 3);' '$("#form_unstable_karma").attr("disabled", false);' 'if ($("#form_unstable_karma").attr("value") == 0) $("#form_unstable_karma").attr("value", -3);' ' } else { ' '$("#form_stable_karma").attr("disabled", true);' '$("#form_unstable_karma").attr("disabled", true);' '}', 'title': 'Karma Automatism - Enable update request ' 'automation based on user feedback', }), TextField('stable_karma', label='Threshold for pushing to stable', validator=validators.Int(), default='3', attrs={'title' : 'Stable Karma - The threshold for ' 'automatically pushing this update to stable', 'size' : '1'}), TextField('unstable_karma', label='Threshold for unpushing', validator=validators.Int(), default='-3', attrs={'title' : 'Unstable Karma - The threshold for ' 'automatically unpushing an unstable update', 'size' : '1'}) ]
'notes': override.notes, 'edited': override.build, } if override.date_expired: flash('This override is EXPIRED. Editing it will re-enable it') return dict(form=override_form, values=values, action=url("/override/save_edit"), title='Edit Buildroot Override') @identity.require(identity.not_anonymous()) @expose('json') @validate( validators={ 'builds': validators.UnicodeString(), 'notes': validators.UnicodeString(), 'expiration': validators.DateTimeConverter(format='%m/%d/%Y', not_empty=False) }) @error_handler(new) def save_edit_cli(self, builds, notes, expiration=None, **kw): log.debug(repr(locals())) if expiration: if datetime.utcnow() > expiration: flash('Cannot set an expiration in the past') if request_format() == 'json': return dict() raise redirect('/override/edit?build=' + builds) try: override = BuildRootOverride.byBuild(builds)
class BuildRootOverrideController(Controller): @identity.require(identity.not_anonymous()) @expose() def index(self): raise redirect('/override/list') @identity.require(identity.not_anonymous()) @expose(template="bodhi.templates.overrides", allow_json=True) @validate( validators={ 'build': validators.UnicodeString(), 'mine': validators.StringBool(), 'release': validators.UnicodeString(), 'show_expired': validators.StringBool() }) @paginate('overrides', default_order='-date_submitted', limit=20, max_limit=1000) def list(self, build=None, tg_errors=None, mine=False, release=None, show_expired=False, **kw): query = [] title = '%d Buildroot Overrides' if mine: query.append( BuildRootOverride.q.submitter == identity.current.user_name) title += ' submitted by %s' % identity.current.user_name if release: rel = Release.byName(release) query.append(BuildRootOverride.q.releaseID == rel.id) title += ' for %s' % rel.long_name if not show_expired: query.append(BuildRootOverride.q.date_expired == None) overrides = BuildRootOverride.select(AND(*query)) if request_format() == 'json': overrides = [o.__json__() for o in overrides] num_items = len(overrides) else: num_items = overrides.count() return dict(overrides=overrides, title=title % num_items, num_items=num_items, show_expired=show_expired, mine=mine) @identity.require(identity.not_anonymous()) @expose(template="bodhi.templates.form") def new(self, tg_errors=None, *args, **kw): if tg_errors: flash(str(tg_errors)) expiration = datetime.utcnow() + \ timedelta(days=config.get('buildroot_overrides.expire_after', 1)) return dict(form=override_form, values={'expiration': expiration}, action=url('/override/save'), title='Buildroot Overrides') @identity.require(identity.not_anonymous()) @expose(allow_json=True) def expire(self, build, *args, **kw): """ Expire a given override """ override = BuildRootOverride.byBuild(build) if override.date_expired: flash('Override %s already expired!' % build) if request_format() == 'json': return dict() raise redirect('/override') override.date_expired = datetime.utcnow() try: override.untag() except Exception, e: log.error(str(e)) flash(str(e)) raise redirect('/override') log.info('Buildroot override %s manually expired by %s' % (build, identity.current.user_name)) flash('Buildroot override for %s successful untagged' % build) if request_format() == 'json': return dict() raise redirect('/override')