def get_item_form(name, request, renderers=None, validators=None, values=None): """Will return a form for the given item :name: Name of the form :request: Current request :renderers: Dictionary of external renderers which should be used for renderering some form elements. :validators: List of external formbar validators which should be added to the form for validation :values: Dictionary with external values to prefill the form or add addional values for rule evaluation. :returns: Form """ if renderers is None: renderers = {} if validators is None: validators = [] if values is None: values = {} item = get_item_from_request(request) renderers = add_renderers(renderers) clazz = request.context.__model__ name = request.session.get("%s.form" % clazz) or name # handle blobforms if isinstance(item, Blobform): # TODO: Why not use the get_form_config method here. This can # handle Blobforms and usual form configs. () <2014-08-26 22:21> item, formconfig = get_blobform_config(request, item, name) else: formconfig = get_form_config(item, name) form = Form(formconfig, item, request.db, translate=request.translate, renderers=renderers, change_page_callback={ 'url': 'set_current_form_page', 'item': clazz.__tablename__, 'itemid': item.id }, request=request, csrf_token=request.session.get_csrf_token(), eval_url=get_eval_url(), url_prefix=get_app_url(request), locale=locale_negotiator(request), values=values, timezone=get_timezone(request), dependencies=create_dependencies(request)) # Add validators for validator in validators: form.add_validator(validator) return form
def get_item_form(name, request, renderers=None, validators=None, values=None): """Will return a form for the given item :name: Name of the form :request: Current request :renderers: Dictionary of external renderers which should be used for renderering some form elements. :validators: List of external formbar validators which should be added to the form for validation :values: Dictionary with external values to prefill the form or add addional values for rule evaluation. :returns: Form """ if renderers is None: renderers = {} if validators is None: validators = [] if values is None: values = {} item = get_item_from_request(request) renderers = add_renderers(renderers) clazz = request.context.__model__ name = request.session.get("%s.form" % clazz) or name ## handle blobforms if isinstance(item, Blobform): # TODO: Why not use the get_form_config method here. This can # handle Blobforms and usual form configs. () <2014-08-26 22:21> item, formconfig = get_blobform_config(request, item, name) else: formconfig = get_form_config(item, name) form = Form(formconfig, item, request.db, translate=request.translate, renderers=renderers, change_page_callback={'url': 'set_current_form_page', 'item': clazz.__tablename__, 'itemid': item.id}, request=request, csrf_token=request.session.get_csrf_token(), eval_url=get_eval_url(), url_prefix=get_app_url(request), locale=locale_negotiator(request), values=values) # Add validators for validator in validators: form.add_validator(validator) return form
def changepassword(request): """Method to change the users password by the user. The user user musst provide his old and the new pasword. Users are only allowed to change their own password.""" # Check authentification # As this view has now security configured it is # generally callable by all users. For this reason we first check if # the user is authenticated. If the user is not authenticated the # raise an 401 (unauthorized) exception. if not request.user: raise HTTPUnauthorized clazz = User _ = request.translate rvalue = {} # Load the item return 400 if the item can not be found. id = request.matchdict.get('id') factory = clazz.get_item_factory() try: item = factory.load(id, request.db) # Check authorisation # User are only allowed to set their own password. if item.id != request.user.id: raise HTTPForbidden() except sa.orm.exc.NoResultFound: raise HTTPBadRequest() form = Form(get_form_config(item, 'changepassword'), item, request.db, translate=_, renderers={}, change_page_callback={'url': 'set_current_form_page', 'item': clazz.__tablename__, 'itemid': id}, request=request, csrf_token=request.session.get_csrf_token()) if request.POST: mapping = {'item': item} # Do extra validation which is not handled by formbar. # Is the provided old password correct? validator = Validator('oldpassword', _('The given password is not correct'), check_password) pw_len_validator = Validator('password', _('Password must be at least 12 ' 'characters long.'), password_minlength_validator) pw_nonchar_validator = Validator('password', _('Password must contain at least 2 ' 'non-letters.'), password_nonletter_validator) form.add_validator(validator) form.add_validator(pw_len_validator) form.add_validator(pw_nonchar_validator) if form.validate(request.params): form.save() # Actually save the password. This is not done in the form # as the password needs to be encrypted. encrypt_password_callback(request, item) msg = _('Changed password for "${item}" successfull.', mapping=mapping) log.info(msg) request.session.flash(msg, 'success') route_name = get_action_routename(item, 'changepassword') url = request.route_path(route_name, id=item.id) # Invalidate cache invalidate_cache() return HTTPFound(location=url) else: msg = _('Error on changing the password for ' '"${item}".', mapping=mapping) log.info(msg) request.session.flash(msg, 'error') rvalue['clazz'] = clazz rvalue['item'] = item rvalue['form'] = form.render(page=get_current_form_page(clazz, request)) return rvalue
def register_user(request): settings = request.registry.settings if not is_registration_enabled(settings): raise exc.exception_response(503) handle_history(request) _ = request.translate config = Config(load(get_path_to_form_config('auth.xml'))) form_config = config.get_form('register_user') form = Form(form_config, csrf_token=request.session.get_csrf_token(), translate=_) # Do extra validation which is not handled by formbar. # Is the login unique? login_unique_validator = Validator('login', _('There is already a user with this ' 'name'), is_login_unique) pw_len_validator = Validator('pass', _('Password must be at least 12 characters ' 'long.'), password_minlength_validator) pw_nonchar_validator = Validator('pass', _('Password must contain at least 2 ' 'non-letters.'), password_nonletter_validator) form.add_validator(login_unique_validator) form.add_validator(pw_len_validator) form.add_validator(pw_nonchar_validator) registration_complete = False if request.POST: if form.validate(request.params): # 1. Create user. Do not activate him. Default role is user. ufac = User.get_item_factory() user = ufac.create(None, form.data) # Set login from formdata user.login = form.data['login'] # Encrypt password and save user.password = encrypt_password(form.data['pass']) # Deactivate the user. To activate the user needs to confirm # with the activation link user.activated = False atoken = str(uuid.uuid4()) user.activation_token = atoken # Set profile data user.profile[0].email = form.data['_email'] # 2. Set user group gfac = Usergroup.get_item_factory() default_grps = settings.get("auth.register_user_default_groups", str(USER_GROUP_ID)) for gid in [int(id) for id in default_grps.split(",")]: group = gfac.load(gid) user.groups.append(group) # 3. Set user role rfac = Role.get_item_factory() default_roles = settings.get("auth.register_user_default_roles", str(USER_ROLE_ID)) for rid in [int(id) for id in default_roles.split(",")]: role = rfac.load(rid) user.roles.append(role) # Set default user group. request.db.add(user) # 4. Send confirmation email. The user will be activated # after the user clicks on the confirmation link mailer = Mailer(request) recipient = user.profile[0].email subject = _('Confirm user registration') values = {'url': request.route_url('confirm_user', token=atoken), 'app_name': get_app_title(), 'email': settings['mail.default_sender'], '_': _} mail = Mail([recipient], subject, template="register_user", values=values) mailer.send(mail) msg = _("User has been created and a confirmation mail was sent" " to the users email adress. Please check your email.") request.session.flash(msg, 'success') registration_complete = True return {'form': form.render(), 'complete': registration_complete}
def register_user(request): settings = request.registry.settings if not is_registration_enabled(settings): raise exc.exception_response(503) _ = request.translate config = Config(load(get_path_to_form_config('auth.xml'))) form_config = config.get_form('register_user') form = Form(form_config, csrf_token=request.session.get_csrf_token(), translate=_) # Do extra validation which is not handled by formbar. # Is the login unique? login_unique_validator = Validator( 'login', _('There is already a user with this ' 'name'), is_login_unique) pw_len_validator = Validator( 'pass', _('Password must be at least 12 characters ' 'long.'), password_minlength_validator) pw_nonchar_validator = Validator( 'pass', _('Password must contain at least 2 ' 'non-letters.'), password_nonletter_validator) form.add_validator(login_unique_validator) form.add_validator(pw_len_validator) form.add_validator(pw_nonchar_validator) registration_complete = False if request.POST: if form.validate(request.params): # 1. Create user. Do not activate him. Default role is user. ufac = User.get_item_factory() user = ufac.create(None, form.data) # Set login from formdata user.login = form.data['login'] # Encrypt password and save user.password = encrypt_password(form.data['pass']) # Deactivate the user. To activate the user needs to confirm # with the activation link user.activated = False atoken = str(uuid.uuid4()) user.activation_token = atoken # Set profile data user.profile[0].email = form.data['_email'] # 2. Set user group gfac = Usergroup.get_item_factory() default_grps = settings.get("auth.register_user_default_groups", str(USER_GROUP_ID)) for gid in [int(id) for id in default_grps.split(",")]: group = gfac.load(gid) user.groups.append(group) # 3. Set user role rfac = Role.get_item_factory() default_roles = settings.get("auth.register_user_default_roles", str(USER_ROLE_ID)) for rid in [int(id) for id in default_roles.split(",")]: role = rfac.load(rid) user.roles.append(role) # Set default user group. request.db.add(user) # 4. Send confirmation email. The user will be activated # after the user clicks on the confirmation link mailer = Mailer(request) recipient = user.profile[0].email subject = _('Confirm user registration') values = { 'url': request.route_url('confirm_user', token=atoken), 'app_name': get_app_title(), 'email': settings['mail.default_sender'], 'login': user.login, '_': _ } mail = Mail([recipient], subject, template="register_user", values=values) mailer.send(mail) msg = _("User has been created and a confirmation mail was sent" " to the users email adress. Please check your email.") request.session.flash(msg, 'success') registration_complete = True return {'form': form.render(), 'complete': registration_complete}
def changepassword(request): """Method to change the users password by the user. The user user musst provide his old and the new pasword. Users are only allowed to change their own password.""" # Check authentification # As this view has now security configured it is # generally callable by all users. For this reason we first check if # the user is authenticated. If the user is not authenticated the # raise an 401 (unauthorized) exception. if not request.user: raise HTTPUnauthorized clazz = User handle_history(request) handle_params(request) _ = request.translate rvalue = {} # Load the item return 400 if the item can not be found. id = request.matchdict.get('id') factory = clazz.get_item_factory() try: item = factory.load(id, request.db) # Check authorisation # User are only allowed to set their own password. if item.id != request.user.id: raise HTTPForbidden() except sa.orm.exc.NoResultFound: raise HTTPBadRequest() form = Form(get_form_config(item, 'changepassword'), item, request.db, translate=_, renderers={}, change_page_callback={'url': 'set_current_form_page', 'item': clazz.__tablename__, 'itemid': id}, request=request, csrf_token=request.session.get_csrf_token()) if request.POST: mapping = {'item': item} # Do extra validation which is not handled by formbar. # Is the provided old password correct? validator = Validator('oldpassword', _('The given password is not correct'), check_password) pw_len_validator = Validator('password', _('Password must be at least 12 ' 'characters long.'), password_minlength_validator) pw_nonchar_validator = Validator('password', _('Password must contain at least 2 ' 'non-letters.'), password_nonletter_validator) form.add_validator(validator) form.add_validator(pw_len_validator) form.add_validator(pw_nonchar_validator) if form.validate(request.params): form.save() # Actually save the password. This is not done in the form # as the password needs to be encrypted. encrypt_password_callback(request, item) msg = _('Changed password for "${item}" successfull.', mapping=mapping) log.info(msg) request.session.flash(msg, 'success') route_name = get_action_routename(item, 'changepassword') url = request.route_path(route_name, id=item.id) # Invalidate cache invalidate_cache() return HTTPFound(location=url) else: msg = _('Error on changing the password for ' '"${item}".', mapping=mapping) log.info(msg) request.session.flash(msg, 'error') rvalue['clazz'] = clazz rvalue['item'] = item rvalue['form'] = form.render(page=get_current_form_page(clazz, request)) return rvalue
def register_user(request): settings = request.registry.settings if not is_registration_enabled(settings): raise exc.exception_response(503) handle_history(request) _ = request.translate config = Config(load(get_path_to_form_config('auth.xml', 'ringo'))) form_config = config.get_form('register_user') form = Form(form_config, csrf_token=request.session.get_csrf_token(), translate=_) # Do extra validation which is not handled by formbar. # Is the login unique? validator = Validator('login', 'There is already a user with this name', is_login_unique) form.add_validator(validator) if request.POST: if form.validate(request.params): # 1. Create user. Do not activate him. Default role is user. ufac = User.get_item_factory() user = ufac.create(None, form.data) # Set login from formdata user.login = form.data['login'] # Encrypt password and save user.password = encrypt_password(form.data['pass']) # Deactivate the user. To activate the user needs to confirm # with the activation link user.activated = False atoken = str(uuid.uuid4()) user.activation_token = atoken # Set profile data user.profile[0].email = form.data['_email'] # 2. Set user group gfac = Usergroup.get_item_factory() group = gfac.load(USER_GROUP_ID) user.groups.append(group) # 3. Set user role rfac = Role.get_item_factory() role = rfac.load(USER_ROLE_ID) user.roles.append(role) # Set default user group. request.db.add(user) # 4. Send confirmation email. The user will be activated # after the user clicks on the confirmation link mailer = Mailer(request) recipient = user.profile[0].email subject = _('Confirm user registration') values = {'url': request.route_url('confirm_user', token=atoken), 'app_name': get_app_title(), 'email': settings['mail.default_sender'], '_': _} mail = Mail([recipient], subject, template="register_user", values=values) mailer.send(mail) target_url = request.route_path('login') headers = forget(request) msg = _("User has been created and a confirmation mail was sent" " to the users email adress. Please check your email.") request.session.flash(msg, 'success') return HTTPFound(location=target_url, headers=headers) return {'form': form.render()}
class TestFormValidation(unittest.TestCase): def setUp(self): tree = load(os.path.join(test_dir, 'form.xml')) config = Config(tree) form_config = config.get_form('customform') self.form = Form(form_config) def test_form_init(self): pass def test_form_unknown_field(self): values = {'unknown': 'test', 'integer': '15', 'date': '1998-02-01'} self.form.validate(values) # Check that the unknown field has been filtered out as it was # not part of the form. self.assertEqual(self.form.data.has_key('unknown'), False) def test_form_validate_fail(self): values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'} self.assertEqual(self.form.validate(values), False) def test_form_validate_fail_checkvalues(self): values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'} self.assertEqual(self.form.validate(values), False) self.assertEqual(self.form.submitted_data['integer'], '15') self.assertEqual(self.form.submitted_data['date'], '1998-02-01') def test_form_validate_ok(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'} validator = Validator('integer', 'Error message', external_validator) self.form.add_validator(validator) self.assertEqual(self.form.validate(values), True) def test_form_validate_ext_validator_fail(self): values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'} validator = Validator('integer', 'Error message', external_validator) self.form.add_validator(validator) self.assertEqual(self.form.validate(values), False) def test_form_validate_ext_validator_ok(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'} self.assertEqual(self.form.validate(values), True) def test_form_deserialize_int(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'} self.form.validate(values) self.assertEqual(self.form.data['integer'], 16) def test_form_deserialize_float(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '87.5'} self.assertEqual(self.form.validate(values), True) self.assertEqual(self.form.data['float'], 87.5) def test_form_deserialize_date(self): values = {'default': 'test', 'integer': '16', 'float': '87.5', 'date': '1998-02-01'} self.form.validate(values) self.assertEqual(self.form.data['date'], datetime.date(1998, 2, 1)) def test_form_deserialize_string(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99'} self.form.validate(values) self.assertEqual(self.form.data['default'], 'test') def test_form_deserialize_time(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'time': '00:12:11'} self.form.validate(values) self.assertEqual(self.form.data['time'], 731) def test_form_deserialize_interval(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '00:12:11'} self.form.validate(values) self.assertEqual(self.form.data['interval'], datetime.timedelta(0, 731)) def test_form_convert_interval_ok(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '01:12'} self.form.validate(values) self.assertEqual(self.form.data['interval'], datetime.timedelta(hours=1, minutes=12)) def test_form_convert_interval_false(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '00:12:11'} self.form.validate(values) self.assertEqual(self.form.data['interval'] == datetime.timedelta(1), False) def test_form_convert_interval_mm_ok(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '12'} self.form.validate(values) self.assertEqual(self.form.data['interval'], datetime.timedelta(minutes=12)) def test_form_save(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'} self.assertEqual(self.form.validate(values), True) def test_form_warnings(self): values = {'select': '2', 'default': 'test', 'integer': '16', 'date': '1998-02-01'} self.form.validate(values) warnings = self.form.get_warnings() self.assertEqual(len(warnings), 2) def test_form_save_without_validation(self): self.assertRaises(StateError, self.form.save) def test_form_fields(self): self.assertEqual(len(self.form.fields.values()), 9) def test_form_field_select_options(self): selfield = self.form.get_field('select') self.assertEqual(len(selfield.get_options()), 4) def test_generated_rules(self): num_rules = 0 fields = self.form.fields for field in fields: num_rules += len(self.form.get_field(field).get_rules()) self.assertEqual(num_rules, 5) def test_generated_warning_rules(self): num_rules = 0 fields = self.form.fields for fieldname in fields: field = self.form.get_field(fieldname) rules = [r for r in field.get_rules() if r.triggers=="warning"] num_rules += len(rules) self.assertEqual(num_rules, 2) def test_generated_error_rules(self): num_rules = 0 fields = self.form.fields for fieldname in fields: field = self.form.get_field(fieldname) rules = [r for r in field.get_rules() if r.triggers=="error"] num_rules += len(rules) self.assertEqual(num_rules, 3)
class TestFormValidation(unittest.TestCase): def setUp(self): tree = load(os.path.join(test_dir, 'form.xml')) config = Config(tree) form_config = config.get_form('customform') self.form = Form(form_config) def test_form_init(self): pass def test_form_unknown_field(self): values = {'unknown': 'test', 'integer': '15', 'date': '1998-02-01'} self.form.validate(values) # Check that the unknown field has been filtered out as it was # not part of the form. self.assertEqual(self.form.data.has_key('unknown'), False) def test_form_validate_fail(self): values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'} self.assertEqual(self.form.validate(values), False) def test_form_validate_fail_checkvalues(self): values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'} self.assertEqual(self.form.validate(values), False) self.assertEqual(self.form.submitted_data['integer'], '15') self.assertEqual(self.form.submitted_data['date'], '1998-02-01') def test_form_validate_ok(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'} validator = Validator('integer', 'Error message', external_validator) self.form.add_validator(validator) self.assertEqual(self.form.validate(values), True) def test_form_validate_ext_validator_fail(self): values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'} validator = Validator('integer', 'Error message', external_validator) self.form.add_validator(validator) self.assertEqual(self.form.validate(values), False) def test_form_validate_ext_validator_ok(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'} self.assertEqual(self.form.validate(values), True) def test_form_deserialize_int(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'} self.form.validate(values) self.assertEqual(self.form.data['integer'], 16) def test_form_deserialize_float(self): values = { 'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '87.5' } self.assertEqual(self.form.validate(values), True) self.assertEqual(self.form.data['float'], 87.5) def test_form_deserialize_date(self): values = { 'default': 'test', 'integer': '16', 'float': '87.5', 'date': '1998-02-01' } self.form.validate(values) self.assertEqual(self.form.data['date'], datetime.date(1998, 2, 1)) def test_form_deserialize_string(self): values = { 'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99' } self.form.validate(values) self.assertEqual(self.form.data['default'], 'test') def test_form_deserialize_time(self): values = { 'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'time': '00:12:11' } self.form.validate(values) self.assertEqual(self.form.data['time'], 731) def test_form_deserialize_interval(self): values = { 'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '00:12:11' } self.form.validate(values) self.assertEqual(self.form.data['interval'], datetime.timedelta(0, 731)) def test_form_convert_interval_ok(self): values = { 'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '01:12' } self.form.validate(values) self.assertEqual(self.form.data['interval'], datetime.timedelta(hours=1, minutes=12)) def test_form_convert_interval_false(self): values = { 'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '00:12:11' } self.form.validate(values) self.assertEqual(self.form.data['interval'] == datetime.timedelta(1), False) def test_form_convert_interval_mm_ok(self): values = { 'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '12' } self.form.validate(values) self.assertEqual(self.form.data['interval'], datetime.timedelta(minutes=12)) def test_form_save(self): values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'} self.assertEqual(self.form.validate(values), True) def test_form_warnings(self): values = { 'select': '2', 'default': 'test', 'integer': '16', 'date': '1998-02-01' } self.form.validate(values) warnings = self.form.get_warnings() self.assertEqual(len(warnings), 2) def test_form_save_without_validation(self): self.assertRaises(StateError, self.form.save) def test_form_fields(self): self.assertEqual(len(self.form.fields.values()), 9) def test_form_field_select_options(self): selfield = self.form.get_field('select') self.assertEqual(len(selfield.get_options()), 4) def test_generated_rules(self): num_rules = 0 fields = self.form.fields for field in fields: num_rules += len(self.form.get_field(field).get_rules()) self.assertEqual(num_rules, 5) def test_generated_warning_rules(self): num_rules = 0 fields = self.form.fields for fieldname in fields: field = self.form.get_field(fieldname) rules = [r for r in field.get_rules() if r.triggers == "warning"] num_rules += len(rules) self.assertEqual(num_rules, 2) def test_generated_error_rules(self): num_rules = 0 fields = self.form.fields for fieldname in fields: field = self.form.get_field(fieldname) rules = [r for r in field.get_rules() if r.triggers == "error"] num_rules += len(rules) self.assertEqual(num_rules, 3)