def _sanitize_response(response_value, block_type): if block_type == 'file-input': return response_value # don't mess with this magic elif block_type == 'multi-select-input': return [sanitize.strip_html(entry) for entry in response_value] else: return sanitize.strip_html(response_value)
def map_schemas_to_schemablocks(*args): """Map schemas to schema blocks WARNING: Deletes existing schema blocks """ state = args[0] try: RegistrationSchema = state.get_model('osf', 'registrationschema') except Exception: try: RegistrationSchema = state.get_model('osf', 'metaschema') except Exception: # Working outside a migration from osf.models import RegistrationSchema # Delete all existing schema blocks (avoid creating duplicates) unmap_schemablocks(*args) for rs in RegistrationSchema.objects.all(): logger.info('Migrating schema {}, version {} to schema blocks.'.format(rs.schema.get('name'), rs.schema_version)) for page in rs.schema['pages']: # Create page heading block create_schema_block( state, rs.id, 'page-heading', display_text=strip_html(page.get('title', '')), help_text=strip_html(page.get('description', '')) ) for question in page['questions']: create_schema_blocks_for_question(state, rs, question)
def test_bulk_creates_children_and_sanitizes_html_logged_in_owner( self, app, user, project, url): title = '<em>Reasoning</em> <strong>Aboot Projects</strong>' description = 'A <script>alert("super reasonable")</script> child' res = app.post_json_api(url, { 'data': [{ 'type': 'nodes', 'attributes': { 'title': title, 'description': description, 'category': 'project', 'public': True } }] }, auth=user.auth, bulk=True) child_id = res.json['data'][0]['id'] assert res.status_code == 201 url = '/{}nodes/{}/'.format(API_BASE, child_id) res = app.get(url, auth=user.auth) assert res.json['data']['attributes']['title'] == strip_html(title) assert res.json['data']['attributes']['description'] == strip_html( description) assert res.json['data']['attributes']['category'] == 'project' project.reload() child_id = res.json['data']['id'] assert child_id == project.nodes[0]._id assert AbstractNode.load(child_id).logs.latest( ).action == NodeLog.PROJECT_CREATED
def new_node(category, title, user, description='', parent=None, campaign=None): """Create a new project or component. :param str category: Node category :param str title: Node title :param User user: User object :param str description: Node description :param Node project: Optional parent object :return Node: Created node """ # We use apps.get_model rather than import .model.Node # because we want the concrete Node class, not AbstractNode Node = apps.get_model('osf.Node') category = category title = strip_html(title.strip()) if description: description = strip_html(description.strip()) node = Node( title=title, category=category, creator=user, description=description, parent=parent ) node.save() if campaign: from framework.auth.campaigns import system_tag_for_campaign node.add_system_tag(system_tag_for_campaign(campaign)) return node
def new_node(category, title, user, description='', parent=None): """Create a new project or component. :param str category: Node category :param str title: Node title :param User user: User object :param str description: Node description :param Node project: Optional parent object :return Node: Created node """ # We use apps.get_model rather than import .model.Node # because we want the concrete Node class, not AbstractNode Node = apps.get_model('osf.Node') category = category title = strip_html(title.strip()) if description: description = strip_html(description.strip()) node = Node( title=title, category=category, creator=user, description=description, parent=parent ) node.save() return node
def test_bulk_creates_children_and_sanitizes_html_logged_in_owner( self, app, user, project, url): title = '<em>Reasoning</em> <strong>Aboot Projects</strong>' description = 'A <script>alert("super reasonable")</script> child' res = app.post_json_api(url, { 'data': [{ 'type': 'nodes', 'attributes': { 'title': title, 'description': description, 'category': 'project', 'public': True } }] }, auth=user.auth, bulk=True) child_id = res.json['data'][0]['id'] assert res.status_code == 201 url = '/{}nodes/{}/'.format(API_BASE, child_id) res = app.get(url, auth=user.auth) assert res.json['data']['attributes']['title'] == strip_html(title) assert res.json['data']['attributes']['description'] == strip_html( description) assert res.json['data']['attributes']['category'] == 'project' project.reload() child_id = res.json['data']['id'] assert child_id == project.nodes[0]._id assert AbstractNode.load( child_id).logs.latest().action == NodeLog.PROJECT_CREATED
def test_strip_html_on_non_strings_returns_original_value(self): assert_true(sanitize.strip_html(True)) assert_false(sanitize.strip_html(False)) assert_equal(sanitize.strip_html(12), 12) assert_equal(sanitize.strip_html(12.3), 12.3) dtime = timezone.now() assert_equal(sanitize.strip_html(dtime), dtime)
def test_strip_html(self): assert_equal( sanitize.strip_html('<foo>bar</foo>'), 'bar' ) assert_equal( sanitize.strip_html(b'<foo>bar</foo>'), 'bar' )
def map_schema_to_schemablocks(rs, state=None): for page in rs.schema['pages']: # Create page heading block create_schema_block(state, rs.id, 'page-heading', display_text=strip_html(page.get('title', '')), help_text=strip_html(page.get('description', ''))) for question in page['questions']: create_schema_blocks_for_question(state, rs, question)
def find_title_description_help_example(rs, question): """ For mapping schemas to schema blocks: Schemas are inconsistent with regards to the information going into "title", "description", and "help" blocks. :returns tuple, title, description, help, example strings """ title = question.get('title', '') description = strip_html(question.get('description', '')) help = strip_html(question.get('help', '')) example = strip_html(question.get('example', '')) schema_name = rs.schema.get('name', '') # Descriptions that contain any of these keywords # are turned into help text instead. help_text_keywords = [ 'please', 'choose', 'provide', 'format', 'describe', 'who', 'what', 'when', 'where', 'use', 'you', 'your', 'skip', 'enter', ] if title: if schema_name in [ 'OSF Preregistration', 'Prereg Challenge', 'Secondary Data Preregistration' ]: # These two schemas have clear "example" text in the "help" section example = help help = description description = '' else: for keyword in help_text_keywords: if keyword in description.lower(): help = description description = '' break else: # if no title, description text is moved to title. title = description description = '' return title, description, help, example
def deserialize_contributors(node, user_dicts, auth, validate=False): """View helper that returns a list of User objects from a list of serialized users (dicts). The users in the list may be registered or unregistered users. e.g. ``[{'id': 'abc123', 'registered': True, 'fullname': ..}, {'id': None, 'registered': False, 'fullname'...}, {'id': '123ab', 'registered': False, 'fullname': ...}] If a dict represents an unregistered user without an ID, creates a new unregistered User record. :param Node node: The node to add contributors to :param list(dict) user_dicts: List of serialized users in the format above. :param Auth auth: :param bool validate: Whether to validate and sanitize fields (if necessary) """ # Add the registered contributors contribs = [] for contrib_dict in user_dicts: fullname = contrib_dict['fullname'] visible = contrib_dict['visible'] email = contrib_dict.get('email') if validate is True: # Validate and sanitize inputs as needed. Email will raise error if invalid. # TODO Edge case bug: validation and saving are performed in same loop, so all in list # up to the invalid entry will be saved. (communicate to the user what needs to be retried) fullname = sanitize.strip_html(fullname) if not fullname: raise ValidationError('Full name field cannot be empty') if email: validate_email(email) # Will raise a ValidationError if email invalid if contrib_dict['id']: contributor = OSFUser.load(contrib_dict['id']) else: try: contributor = OSFUser.create_unregistered( fullname=fullname, email=email) contributor.save() except ValidationError: ## FIXME: This suppresses an exception if ID not found & new validation fails; get_user will return None contributor = get_user(email=email) # Add unclaimed record if necessary if not contributor.is_registered: contributor.add_unclaimed_record(node, referrer=auth.user, given_name=fullname, email=email) contributor.save() contribs.append({ 'user': contributor, 'visible': visible, 'permissions': expand_permissions(contrib_dict.get('permission')) }) return contribs
def set_title(self, title, auth, save=False): """Set the title of this Node and log it. :param str title: The new title. :param auth: All the auth information including user, API key. """ if not self.has_permission(auth.user, 'write'): raise PermissionsError( 'Must have admin or write permissions to edit a preprint\'s title.' ) # Called so validation does not have to wait until save. validate_title(title) original_title = self.title new_title = sanitize.strip_html(title) # Title hasn't changed after sanitzation, bail out if original_title == new_title: return False self.title = new_title self.add_log( action=PreprintLog.EDITED_TITLE, params={ 'preprint': self._id, 'title_new': self.title, 'title_original': original_title, }, auth=auth, save=False, ) if save: self.save() return None
def set_description(self, description, auth, save=False): """Set the description and log the event. :param str description: The new description :param auth: All the auth informtion including user, API key. :param bool save: Save self after updating. """ if not self.has_permission(auth.user, 'write'): raise PermissionsError( 'Must have admin or write permissions to edit a preprint\'s title.' ) original = self.description new_description = sanitize.strip_html(description) if original == new_description: return False self.description = new_description self.add_log( action=PreprintLog.EDITED_DESCRIPTION, params={ 'preprint': self._id, 'description_new': self.description, 'description_original': original }, auth=auth, save=False, ) if save: self.save() return None
def set_description(self, description, auth, save=False): """Set the description and log the event. :param str description: The new description :param auth: All the auth informtion including user, API key. :param bool save: Save self after updating. """ if not self.has_permission(auth.user, 'write'): raise PermissionsError('Must have admin or write permissions to edit a preprint\'s title.') original = self.description new_description = sanitize.strip_html(description) if original == new_description: return False self.description = new_description self.add_log( action=PreprintLog.EDITED_DESCRIPTION, params={ 'preprint': self._id, 'description_new': self.description, 'description_original': original }, auth=auth, save=False, ) if save: self.save() return None
def set_title(self, title, auth, save=False): """Set the title of this Node and log it. :param str title: The new title. :param auth: All the auth information including user, API key. """ if not self.has_permission(auth.user, 'write'): raise PermissionsError('Must have admin or write permissions to edit a preprint\'s title.') # Called so validation does not have to wait until save. validate_title(title) original_title = self.title new_title = sanitize.strip_html(title) # Title hasn't changed after sanitzation, bail out if original_title == new_title: return False self.title = new_title self.add_log( action=PreprintLog.EDITED_TITLE, params={ 'preprint': self._id, 'title_new': self.title, 'title_original': original_title, }, auth=auth, save=False, ) if save: self.save() return None
def register_user(**kwargs): """ Register new user account. HTTP Method: POST :param-json str email1: :param-json str email2: :param-json str password: :param-json str fullName: :param-json str campaign: :raises: HTTPError(http.BAD_REQUEST) if validation fails or user already exists """ # Verify that email address match. # Note: Both `landing.mako` and `register.mako` already have this check on the form. Users can not submit the form # if emails do not match. However, this check should not be removed given we may use the raw api call directly. json_data = request.get_json() if str(json_data['email1']).lower() != str(json_data['email2']).lower(): raise HTTPError(http.BAD_REQUEST, data=dict(message_long='Email addresses must match.')) # Verify that captcha is valid if settings.RECAPTCHA_SITE_KEY and not validate_recaptcha( json_data.get('g-recaptcha-response'), remote_ip=request.remote_addr): raise HTTPError(http.BAD_REQUEST, data=dict(message_long='Invalid Captcha')) try: full_name = request.json['fullName'] full_name = strip_html(full_name) campaign = json_data.get('campaign') if campaign and campaign not in campaigns.get_campaigns(): campaign = None user = framework_auth.register_unconfirmed( request.json['email1'], request.json['password'], full_name, campaign=campaign, ) framework_auth.signals.user_registered.send(user) except (ValidationValueError, DuplicateEmailError): raise HTTPError( http.BAD_REQUEST, data=dict(message_long=language.ALREADY_REGISTERED.format( email=markupsafe.escape(request.json['email1'])))) except ValidationError as e: raise HTTPError(http.BAD_REQUEST, data=dict(message_long=e.message)) if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=user.username) message = language.REGISTRATION_SUCCESS.format(email=user.username) return {'message': message} else: return {'message': 'You may now log in.'}
def project_new_post(auth, **kwargs): user = auth.user data = request.get_json() title = strip_html(data.get('title')) title = title.strip() category = data.get('category', 'project') template = data.get('template') description = strip_html(data.get('description')) new_project = {} if template: original_node = AbstractNode.load(template) changes = { 'title': title, 'category': category, 'template_node': original_node, } if description: changes['description'] = description project = original_node.use_as_template( auth=auth, changes={ template: changes, } ) else: try: project = new_node(category, title, user, description) except ValidationError as e: raise HTTPError( http.BAD_REQUEST, data=dict(message_long=e.message) ) new_project = _view_project(project, auth) return { 'projectUrl': project.url, 'newNode': new_project['node'] if new_project else None }, http.CREATED
def test_field_content_is_sanitized_upon_submission( self, app, data_sample, user_one, url_token_list): bad_text = '<a href="http://sanitized.name">User_text</a>' cleaned_text = sanitize.strip_html(bad_text) payload = copy.deepcopy(data_sample) payload['data']['attributes']['name'] = bad_text res = app.post_json_api(url_token_list, payload, auth=user_one.auth) assert res.status_code == 201 assert res.json['data']['attributes']['name'] == cleaned_text
def test_update_user_sanitizes_html_properly( self, app, user_one, url_user_one): """Post request should update resource, and any HTML in fields should be stripped""" bad_fullname = 'Malcolm <strong>X</strong>' bad_family_name = 'X <script>alert("is")</script> a cool name' res = app.patch_json_api(url_user_one, { 'data': { 'id': user_one._id, 'type': 'users', 'attributes': { 'full_name': bad_fullname, 'family_name': bad_family_name, } } }, auth=user_one.auth) assert res.status_code == 200 assert res.json['data']['attributes']['full_name'] == strip_html( bad_fullname) assert res.json['data']['attributes']['family_name'] == strip_html( bad_family_name)
def test_field_content_is_sanitized_upon_submission( self, app, user, url, sample_data): bad_text = '<a href=\'http://sanitized.name\'>User_text</a>' cleaned_text = sanitize.strip_html(bad_text) payload = copy.copy(sample_data) payload['data']['attributes']['name'] = bad_text payload['data']['attributes']['description'] = bad_text res = app.post_json_api(url, payload, auth=user.auth) assert res.status_code == 201 assert res.json['data']['attributes']['name'] == cleaned_text
def test_update_user_sanitizes_html_properly(self, app, user_one, url_user_one): """Post request should update resource, and any HTML in fields should be stripped""" bad_fullname = 'Malcolm <strong>X</strong>' bad_family_name = 'X <script>alert("is")</script> a cool name' res = app.patch_json_api(url_user_one, { 'data': { 'id': user_one._id, 'type': 'users', 'attributes': { 'full_name': bad_fullname, 'family_name': bad_family_name, } } }, auth=user_one.auth) assert res.status_code == 200 assert res.json['data']['attributes']['full_name'] == strip_html( bad_fullname) assert res.json['data']['attributes']['family_name'] == strip_html( bad_family_name)
def project_new_node(auth, node, **kwargs): form = NewNodeForm(request.form) user = auth.user if form.validate(): try: new_component = new_node( title=strip_html(form.title.data), user=user, category=form.category.data, parent=node, ) except ValidationError as e: raise HTTPError(http.BAD_REQUEST, data=dict(message_long=e.message)) redirect_url = node.url message = ( 'Your component was created successfully. You can keep working on the project page below, ' 'or go to the new <u><a href={component_url}>component</a></u>.' ).format(component_url=new_component.url) if form.inherit_contributors.data and node.has_permission(user, WRITE): for contributor in node.contributors: perm = CREATOR_PERMISSIONS if contributor._id == user._id else node.get_permissions( contributor) if contributor._id == user._id and not contributor.is_registered: new_component.add_unregistered_contributor( fullname=contributor.fullname, email=contributor.email, permissions=perm, auth=auth, existing_user=contributor) else: new_component.add_contributor(contributor, permissions=perm, auth=auth) new_component.save() redirect_url = new_component.url + 'contributors/' message = ( 'Your component was created successfully. You can edit the contributor permissions below, ' 'work on your <u><a href={component_url}>component</a></u> or return to the <u> ' '<a href="{project_url}">project page</a></u>.').format( component_url=new_component.url, project_url=node.url) status.push_status_message(message, kind='info', trust=True) return { 'status': 'success', }, 201, None, redirect_url else: # TODO: This function doesn't seem to exist anymore? status.push_errors_to_status(form.errors) raise HTTPError(http.BAD_REQUEST, redirect_url=node.url)
def map_schemas_to_schemablocks(*args): """Map schemas to schema blocks WARNING: Deletes existing schema blocks """ state = args[0] if args else apps try: schema_model = state.get_model('osf', 'registrationschema') except LookupError: # Use MetaSchema model if migrating from a version before RegistrationSchema existed schema_model = state.get_model('osf', 'metaschema') try: RegistrationSchemaBlock = state.get_model('osf', 'registrationschemablock') except LookupError: return # can't create SchemaBlocks if they don't exist for rs in schema_model.objects.all(): if RegistrationSchemaBlock.objects.filter(schema_id=rs.id).exists(): continue logger.info('Migrating schema {}, version {} to schema blocks.'.format( rs.name, rs.schema_version)) if rs.schema.get('atomicSchema'): create_schema_blocks_for_atomic_schema(rs) continue for page in rs.schema['pages']: # Create page heading block create_schema_block(state, rs.id, 'page-heading', display_text=strip_html(page.get('title', '')), help_text=strip_html( page.get('description', ''))) for question in page['questions']: create_schema_blocks_for_question(state, rs, question)
def new_private_link(name, user, nodes, anonymous): """Create a new private link. :param str name: private link name :param User user: User object :param list Node node: a list of node object :param bool anonymous: make link anonymous or not :return PrivateLink: Created private link """ PrivateLink = apps.get_model('osf.PrivateLink') NodeLog = apps.get_model('osf.NodeLog') key = str(uuid.uuid4()).replace('-', '') if name: name = strip_html(name) if name is None or not name.strip(): raise ValidationError('Invalid link name.') else: name = 'Shared project link' private_link = PrivateLink( key=key, name=name, creator=user, anonymous=anonymous ) private_link.save() private_link.nodes.add(*nodes) auth = Auth(user) for node in nodes: log_dict = { 'project': node.parent_id, 'node': node._id, 'user': user._id, 'anonymous_link': anonymous, } node.add_log( NodeLog.VIEW_ONLY_LINK_ADDED, log_dict, auth=auth ) private_link.save() return private_link
def project_new_node(auth, node, **kwargs): form = NewNodeForm(request.form) user = auth.user if form.validate(): try: new_component = new_node( title=strip_html(form.title.data), user=user, category=form.category.data, parent=node, ) except ValidationError as e: raise HTTPError( http.BAD_REQUEST, data=dict(message_long=e.message) ) redirect_url = node.url message = ( 'Your component was created successfully. You can keep working on the project page below, ' 'or go to the new <u><a href={component_url}>component</a></u>.' ).format(component_url=new_component.url) if form.inherit_contributors.data and node.has_permission(user, WRITE): for contributor in node.contributors: perm = CREATOR_PERMISSIONS if contributor._id == user._id else node.get_permissions(contributor) if contributor._id == user._id and not contributor.is_registered: new_component.add_unregistered_contributor( fullname=contributor.fullname, email=contributor.email, permissions=perm, auth=auth, existing_user=contributor ) else: new_component.add_contributor(contributor, permissions=perm, auth=auth) new_component.save() redirect_url = new_component.url + 'contributors/' message = ( 'Your component was created successfully. You can edit the contributor permissions below, ' 'work on your <u><a href={component_url}>component</a></u> or return to the <u> ' '<a href="{project_url}">project page</a></u>.' ).format(component_url=new_component.url, project_url=node.url) status.push_status_message(message, kind='info', trust=True) return { 'status': 'success', }, 201, None, redirect_url else: # TODO: This function doesn't seem to exist anymore? status.push_errors_to_status(form.errors) raise HTTPError(http.BAD_REQUEST, redirect_url=node.url)
def validate_title(value): """Validator for Node#title. Makes sure that the value exists and is not above 512 characters. """ if value is None or not value.strip(): raise ValidationError('Title cannot be blank.') value = sanitize.strip_html(value) if value is None or not value.strip(): raise ValidationError('Invalid title.') if len(value) > 512: raise ValidationError('Title cannot exceed 512 characters.') return True
def validate_title(value): """Validator for Node#title. Makes sure that the value exists and is not above 200 characters. """ if value is None or not value.strip(): raise ValidationValueError('Title cannot be blank.') value = strip_html(value) if value is None or not value.strip(): raise ValidationValueError('Invalid title.') if len(value) > 200: raise ValidationValueError('Title cannot exceed 200 characters.') return True
def project_private_link_edit(auth, **kwargs): name = request.json.get('value', '') try: validate_title(name) except ValidationError as e: message = 'Invalid link name.' if e.message == 'Invalid title.' else e.message raise HTTPError(http.BAD_REQUEST, data=dict(message_long=message)) private_link_id = request.json.get('pk', '') private_link = PrivateLink.load(private_link_id) if private_link: new_name = strip_html(name) private_link.name = new_name private_link.save() return new_name else: raise HTTPError(http.BAD_REQUEST, data=dict(message_long='View-only link not found.'))
def invite_contributor_post(node, **kwargs): """API view for inviting an unregistered user. Performs validation, but does not actually invite the user. Expects JSON arguments with 'fullname' (required) and email (not required). """ fullname = request.json.get('fullname').strip() email = request.json.get('email') # Validate and sanitize inputs as needed. Email will raise error if invalid. fullname = sanitize.strip_html(fullname) if email: email = email.lower().strip() try: validate_email(email) except ValidationError as e: return {'status': 400, 'message': e.message}, 400 if not fullname: return { 'status': 400, 'message': 'Full name field cannot be empty' }, 400 # Check if email is in the database user = get_user(email=email) if user: if user.is_registered: msg = 'User is already in database. Please go back and try your search again.' return {'status': 400, 'message': msg}, 400 elif node.is_contributor(user): msg = 'User with this email address is already a contributor to this project.' return {'status': 400, 'message': msg}, 400 elif not user.is_confirmed: serialized = profile_utils.serialize_unregistered(fullname, email) else: serialized = profile_utils.add_contributor_json(user) # use correct display name serialized['fullname'] = fullname serialized['email'] = email else: # Create a placeholder serialized = profile_utils.serialize_unregistered(fullname, email) return {'status': 'success', 'contributor': serialized}
def invite_contributor_post(node, **kwargs): """API view for inviting an unregistered user. Performs validation, but does not actually invite the user. Expects JSON arguments with 'fullname' (required) and email (not required). """ fullname = request.json.get('fullname').strip() email = request.json.get('email') # Validate and sanitize inputs as needed. Email will raise error if invalid. fullname = sanitize.strip_html(fullname) if email: email = email.lower().strip() try: validate_email(email) except ValidationError as e: return {'status': 400, 'message': e.message}, 400 if not fullname: return {'status': 400, 'message': 'Full name field cannot be empty'}, 400 # Check if email is in the database user = get_user(email=email) if user: if user.is_registered: msg = 'User is already in database. Please go back and try your search again.' return {'status': 400, 'message': msg}, 400 elif node.is_contributor(user): msg = 'User with this email address is already a contributor to this project.' return {'status': 400, 'message': msg}, 400 elif not user.is_confirmed: serialized = profile_utils.serialize_unregistered(fullname, email) else: serialized = profile_utils.add_contributor_json(user) # use correct display name serialized['fullname'] = fullname serialized['email'] = email else: # Create a placeholder serialized = profile_utils.serialize_unregistered(fullname, email) return {'status': 'success', 'contributor': serialized}
def set_group_name(self, name, auth=None): """Set the name of the group. :param str new Name: The new osf group name :param auth: Auth object """ self._require_manager_permission(auth) new_name = sanitize.strip_html(name) # Title hasn't changed after sanitzation, bail out if self.name == new_name: return False old_name = self.name self.name = new_name self.add_log(OSFGroupLog.EDITED_NAME, params={ 'group': self._id, 'name_original': old_name }, auth=auth) self.update_search() for node in self.nodes: node.update_search()
def project_private_link_edit(auth, **kwargs): name = request.json.get('value', '') try: validate_title(name) except ValidationError as e: message = 'Invalid link name.' if e.message == 'Invalid title.' else e.message raise HTTPError( http.BAD_REQUEST, data=dict(message_long=message) ) private_link_id = request.json.get('pk', '') private_link = PrivateLink.load(private_link_id) if private_link: new_name = strip_html(name) private_link.name = new_name private_link.save() return new_name else: raise HTTPError( http.BAD_REQUEST, data=dict(message_long='View-only link not found.') )
def __call__(self, form, field): if not field.data == strip_html(field.data): raise ValidationError(self.message)
def register_user(**kwargs): """ Register new user account. HTTP Method: POST :param-json str email1: :param-json str email2: :param-json str password: :param-json str fullName: :param-json str campaign: :raises: HTTPError(http.BAD_REQUEST) if validation fails or user already exists """ # Verify that email address match. # Note: Both `landing.mako` and `register.mako` already have this check on the form. Users can not submit the form # if emails do not match. However, this check should not be removed given we may use the raw api call directly. json_data = request.get_json() if str(json_data['email1']).lower() != str(json_data['email2']).lower(): raise HTTPError( http.BAD_REQUEST, data=dict(message_long='Email addresses must match.') ) # Verify that captcha is valid if settings.RECAPTCHA_SITE_KEY and not validate_recaptcha(json_data.get('g-recaptcha-response'), remote_ip=request.remote_addr): raise HTTPError( http.BAD_REQUEST, data=dict(message_long='Invalid Captcha') ) try: full_name = request.json['fullName'] full_name = strip_html(full_name) campaign = json_data.get('campaign') if campaign and campaign not in campaigns.get_campaigns(): campaign = None accepted_terms_of_service = timezone.now() if json_data.get('acceptedTermsOfService') else None user = framework_auth.register_unconfirmed( request.json['email1'], request.json['password'], full_name, campaign=campaign, accepted_terms_of_service=accepted_terms_of_service ) framework_auth.signals.user_registered.send(user) except (ValidationValueError, DuplicateEmailError): raise HTTPError( http.BAD_REQUEST, data=dict( message_long=language.ALREADY_REGISTERED.format( email=markupsafe.escape(request.json['email1']) ) ) ) except BlacklistedEmailError as e: raise HTTPError( http.BAD_REQUEST, data=dict(message_long=language.BLACKLISTED_EMAIL) ) except ValidationError as e: raise HTTPError( http.BAD_REQUEST, data=dict(message_long=e.message) ) if settings.CONFIRM_REGISTRATIONS_BY_EMAIL: send_confirm_email(user, email=user.username) message = language.REGISTRATION_SUCCESS.format(email=user.username) return {'message': message} else: return {'message': 'You may now log in.'}
def get_custom_publish_text(connection): if connection is None: return '' return strip_html(connection.get_custom_publish_text(), tags=['strong', 'li', 'ul'])
def test_strip_html_sanitizes_collection_types_as_strings(self): assert_equal(sanitize.strip_html({'foo': '<b>bar</b>'}), "{'foo': 'bar'}") assert_equal(sanitize.strip_html(['<em>baz</em>']), "['baz']")