def add_relevant_issue_classes(project):
    """ Adds relevant issue classes to the given project. Only adds issue classes that were created after the last time
    this function was ran, avoiding re-adding issue classes that the user may have removed from the project.
    :param project: project to add the issue classes to
    :return:
    """
    issue_classes = get_relevant_issue_classes(project)
    logger.info("Adding %d issue_classes to project %s" %
                (len(issue_classes), project.pk))

    with backend.transaction():
        for issue_class in issue_classes:
            project_issue_class_query = {
                'project': project,
                'issue_class': issue_class
            }
            try:
                backend.get(ProjectIssueClass, project_issue_class_query)
                continue
            except ProjectIssueClass.DoesNotExist:
                project_issue_class = ProjectIssueClass(
                    project_issue_class_query)
                project_issue_class.enabled = True
                backend.save(project_issue_class)

        # re-sync the issue classes associated with the project with the database
        project.revert()
Пример #2
0
    def decorated_function(*args, **kwargs):
        def process_anonymously():
            request.user = None
            request.access_token = None
            return f(*args, **kwargs)

        def invalid_token(message, status_code=401, cookie_token=False):
            response = jsonify({'message': message})
            if cookie_token:
                response.set_cookie('access_token', '', expires=0)
            return response, status_code

        cookie_token = False
        if request.args.get('access_token'):
            access_token_key = request.args['access_token']
        elif request.cookies.get('access_token'):
            access_token_key = request.cookies['access_token']
            cookie_token = True
        else:
            authorization = request.headers.get('Authorization', '')
            match = re.match(r"^bearer\s+([\w\d]+)$", authorization, re.I)
            if not match:
                if anon_ok:
                    return process_anonymously()
                return {'message': 'Authorization header not valid'}, 401
            access_token_key = match.group(1)
        try:
            access_token = backend.get(AccessToken,
                                       {'token': access_token_key})

        except AccessToken.DoesNotExist:
            if anon_ok:
                return process_anonymously()
            # redirect to login
            return invalid_token('Invalid / expired access token: %s' %
                                 access_token_key,
                                 cookie_token=cookie_token)
        request.access_token = access_token
        try:
            request.user = backend.get(User, {'pk': access_token.user['pk']},
                                       raw=raw,
                                       only=only,
                                       include=include)
        except User.DoesNotExist:
            with backend.transaction():
                backend.delete(access_token)
            return invalid_token('User does not exist',
                                 status_code=404,
                                 cookie_token=cookie_token)

        if superuser and not request.user.is_superuser():
            return {
                'message':
                'This endpoint requires super-user privileges. Sorry :/'
            }, 401

        return f(*args, **kwargs)
Пример #3
0
def _import_issue_classes():

    issue_update_keys = ('severity', 'description', 'title')
    analyzer_update_keys = ('language', )

    logger.info("Importing issue classes from checkmate...")
    analyzers = settings.checkmate_settings.analyzers
    for analyzer, params in analyzers.items():
        logger.info("Importing issue classes for analyzer {}".format(analyzer))
        if not all([key in params for key in analyzer_update_keys]):
            logger.warning(
                "Skipping analyzer {} as it does not contain a '{}' field".
                format(key))
            continue
        for code, issue_params in params.get('issues_data', {}).items():
            if not all([key in issue_params for key in issue_update_keys]):
                logger.warning(
                    "Skipping issue class for code {}, as it does not contain a '{}' field"
                    .format(code, key))
                continue
            logger.info("Importing issue class for code {}".format(code))
            try:
                issue_class = backend.get(IssueClass, {
                    'analyzer': analyzer,
                    'code': code
                })
            except IssueClass.DoesNotExist:
                issue_class = IssueClass({
                    'analyzer': analyzer,
                    'code': code,
                })
            for key in issue_update_keys:
                issue_class[key] = issue_params[key]
            for key in analyzer_update_keys:
                issue_class[key] = params[key]
            with backend.transaction():
                backend.save(issue_class)
                issue_class.categories.delete()
            for category in issue_params.get('categories', []):
                try:
                    issue_category = backend.get(IssueCategory,
                                                 {'name': category})
                except IssueCategory.DoesNotExist:
                    issue_category = IssueCategory({'name': category})
                    with backend.transaction():
                        backend.save(issue_category)
                issue_class.categories.append(issue_category)
            for tag_name in issue_params.get('tags', ['generic']):
                try:
                    tag = backend.get(Tag, {'name': tag_name})
                except Tag.DoesNotExist:
                    tag = Tag({'name': tag_name})
                    with backend.transaction():
                        backend.save(tag)
                issue_class.tags.append(tag)
            with backend.transaction():
                backend.save(issue_class)
Пример #4
0
    def decorated_function(*args, **kwargs):

        snapshot_a_id = kwargs.get(id_key_a, '')
        snapshot_b_id = kwargs.get(id_key_b, '')
        try:
            snapshot_a = get_snapshot(request.project,
                                      snapshot_a_id,
                                      only=('pk', ))
        except Snapshot.DoesNotExist as e:
            return {
                'message': e.message if e.message else 'invalid snapshot A'
            }, 404
        try:
            snapshot_b = get_snapshot(request.project,
                                      snapshot_b_id,
                                      only=('pk', ))
        except Snapshot.DoesNotExist as e:
            return {
                'message': e.message if e.message else 'invalid snapshot B'
            }, 404

        try:
            diff = backend.get(Diff, {
                'snapshot_a.pk': snapshot_a['pk'],
                'snapshot_b.pk': snapshot_b['pk']
            },
                               include=include)
        except Diff.DoesNotExist as e:
            return {'message': e.message if e.message else 'invalid diff'}, 404

        setattr(request, store_as, diff)
        return f(*args, **kwargs)
Пример #5
0
def auto_tag(project):
    """ First step of the analysis for Git projects. Determines if automatic tags have already been added and, if not
    adds them from the requirements.txt file, if one exists in the repository.
    :param project: project to auto tag
    :return:
    """
    logger.debug("Adding automatic tags to {}".format(project.pk))
    repository = project.git.eager.repository

    # auto tag the project (but only once)
    if project.get('automatic_tags_added'):
        return

    default_branch = project.git.get_default_branch()
    if default_branch is None:
        return
    tags = extract_tags_from_requirements_txt(repository, default_branch)

    with backend.transaction():
        for tag_name in tags:
            try:
                tag = backend.get(Tag, {'name': tag_name})
            except Tag.DoesNotExist:
                tag = Tag({'name': tag_name})
                backend.save(tag)

            project.tags.append(tag)

    project.automatic_tags_added = True
    with backend.transaction():
        backend.update(project, ['automatic_tags_added'])
    def get(self, email_validation_code):
        with backend.transaction():
            try:
                user = backend.get(
                    User,
                    {'email_validation_code': email_validation_code}
                )
                if not user.get('new_email'):
                    if not user.get('email'):
                        return {'message': 'no valid e-mail set'}, 403
                    backend.update(user, {'email_validated': True}, unset_fields=['email_validation_code'])

                    settings.hooks.call("user.email.validated", user)

                    logger.warning("Hooray, user {0} has verified his email address".format(user.name))

                else:
                    if backend.filter(User, {'email': user.new_email}):
                        return {'message': 'A user with this e-mail already exists'}, 403
                    old_email = user.email
                    new_email = user.new_email
                    backend.update(user, {'email_validated': True, 'email': user.new_email},
                                   unset_fields=['new_email', 'email_validation_code'])

                    settings.hooks.call("user.email.updated", user)

            except User.DoesNotExist:
                return {'message': 'Unknown validation code'}, 404
        return {'message': 'success'}, 200
    def post(self):
        form = LoginForm(request.form)
        if form.validate():
            with backend.transaction():
                try:
                    # TODO manually specifying includes is not ideal
                    user = backend.get(User, {'email': form.email.data.lower()},
                                       include=UserProfile.includes)
                    if user.delete is True:
                        return {'message': "Your account is scheduled for deletion. "
                                           "You can sign-up again in a few minutes."}, 403
                    if not user.check_password(form.password.data):
                        return ({'message': 'Invalid password'},
                                403)

                    access_token = user.get_access_token()

                    backend.save(access_token)

                    user_profile = UserProfile.export(user)
                    response = self.make_response({
                        'access_token': access_token.token,
                        'message': 'Success!',
                        'user': user_profile,
                    })

                    expires = (datetime.datetime.now() + datetime.timedelta(days=7)) if form.remember_me.data else None
                    response.set_cookie('access_token', value=access_token.token, expires=expires)

                    return response

                except User.DoesNotExist:
                    return {'message': 'Unknown user'}, 404
        return {'message': 'Invalid data', 'errors': form.errors}, 403
Пример #8
0
def delete_project(project_id, task_id=None):
    """ Deletes the project with the given project id.
    :param project_id: id of the project to delete
    :param task_id: id of the task
    """
    if not task_id:
        task_id = analyze_project.request.id
    try:
        project = backend.get(Project, {'pk': project_id})
    except Project.DoesNotExist:
        logger.error(
            "Project {} does not exist! Cannot delete it.".format(project_id))
        return

    try:
        with ExclusiveTask(backend, {
                'project.pk': project.pk,
                'type': {
                    '$in': ['analysis', 'reset', 'delete']
                }
        }, {
                'type': 'delete',
                'project': project
        },
                           task_id,
                           no_update_on_exit=True) as delete_task:
            with TaskLogger(delete_task, backend=backend, ping=True):
                _delete_project(project)
                logger.info("Deletion of project {} ({}) complete!".format(
                    project.name, project.pk))

    except ExclusiveTask.LockError:
        logger.info(
            "Unable to acquire lock for deletion of project {} ({}).".format(
                project.name, project.pk))
Пример #9
0
def get_snapshot(project, snapshot_id, raw=True, only=None, include=None):
    """
    Returns the snapshot corresponding to a given ID.
    Uses providers set by the plugins.
    :param snapshot_id: id of the snapshot to retrieve, can be empty??
    :param raw: backend param
    :param only: backend param
    :param include: backend param
    :return: snapshot
    """

    #we try to retrieve the snapshot by PK...
    try:
        snapshot = backend.get(Snapshot, {'pk': snapshot_id},
                               include=include,
                               only=only,
                               raw=raw)
        return snapshot
    except Snapshot.DoesNotExist:
        pass

    for params in settings.providers['snapshot.resolve']:
        if not params['source'] == project.source:
            continue  #this is not the right provider...
        snapshot = params['provider'](project,
                                      snapshot_id,
                                      raw=raw,
                                      only=only,
                                      include=include)
        if snapshot is not None:
            return snapshot

    raise Snapshot.DoesNotExist(
        "Could not resolve snapshot ID {}".format(snapshot_id))
Пример #10
0
    def get(self, project_id):

        form = ProjectDetailsForm(request.args)

        if not form.validate():
            return {'message' : 'please correct the errors mentioned below.', 'errors' : form.errors}, 400

        data = form.data

        exported_project = self.export(request.project)
        #we add the analysis queue position of the project
        exported_project['analysis_queue_position'] = request.project.get_analysis_queue_position()

        exported_project['user_role'] = 'anon'
        if request.user is not None:
            try:
                #we add role information to the project (useful for displaying the correct menus)
                user_role = backend.get(UserRole,{'project' : request.project, 'user' : request.user})
                exported_project['user_role'] = user_role.role
            except UserRole.DoesNotExist:
                pass

        if data['with_stats']:
            exported_project['stats'] = request.project.stats

        return {'project': exported_project}, 200
Пример #11
0
    def post(self, password_reset_code):
        form = PasswordResetForm(request.form)
        if form.validate():
            with backend.transaction():
                try:
                    user = backend.get(
                        User,
                        {'password_reset_code': password_reset_code}
                    )
                except User.DoesNotExist:
                    return {'message': 'Unknown user'}, 404

                user.set_password(form.password.data)
                backend.update(user, ['password', 'password_set'], unset_fields=['password_reset_code'])
                access_token = user.get_access_token()
                backend.save(access_token)

                send_mail(
                    email_to=user.email,
                    template="password_reset_successful",
                    template_context={
                        "user_name": user.name
                    }
                )

                return {'message': 'success'}, 200

        return ({'message': 'Invalid data',
                 'errors': form.errors},
                403)
Пример #12
0
    def post(self):
        form = PasswordResetRequestForm(request.form)
        if form.validate():
            with backend.transaction():
                try:
                    user = backend.get(User, {'email': form.email.data})
                    if 'email_validated' in user and user.email_validated:
                        backend.update(
                            user,
                            {'password_reset_code': uuid.uuid4().hex}
                        )

                        reset_url = "{}{}/user/password-reset?reset_code={}".format(
                            settings.get('url'),
                            settings.get('frontend.url'),
                            user.password_reset_code
                        )

                        # Reset Email
                        send_mail(
                            email_to=form.email.data,
                            template="reset_password",
                            template_context={
                                "user_name": user.name,
                                "reset_url": reset_url
                            }
                        )
                        return {'message': 'Email with reset link was sent.'}, 200
                    return {'message': "Your email is not validated, so we cannot send you "
                                       "a password-reset token."}, 403
                except User.DoesNotExist:
                    return {'message': 'Unknown user'}, 404
        return {'message': 'Invalid data', 'errors': form.errors}, 403
Пример #13
0
 def _get_user(user_id):
     try:
         return backend.get(
             User,
             {'$or': [{'name': user_id},
                      {'pk': user_id}]}
         )
     except (User.DoesNotExist, User.MultipleDocumentsReturned):
         raise AttributeError()
Пример #14
0
 def get_project(project_id):
     if not project_id:
         return None
     try:
         project = backend.get(Project, {'pk': project_id})
         if not project.is_authorized(request.user):
             return None
         return project
     except Project.DoesNotExist:
         return None
Пример #15
0
 def _get_project_issue_class():
     query = {
         'project': request.project,
         'issue_class': request.issue_class
     }
     try:
         project_issue_class = backend.get(ProjectIssueClass, query)
     except ProjectIssueClass.DoesNotExist:
         project_issue_class = ProjectIssueClass(query)
     return project_issue_class
Пример #16
0
    def decorated_function(*args, **kwargs):

        if (snapshot_id_key in kwargs and path_key in kwargs
                and kwargs[snapshot_id_key] is not None
                and kwargs[path_key] is not None):
            try:
                snapshot = get_snapshot(request.project,
                                        kwargs[snapshot_id_key],
                                        raw=False)
            except Snapshot.DoesNotExist:
                return {'message': 'invalid snapshot'}, 404

            try:
                file_revision = backend.get(FileRevision, {
                    'snapshots': snapshot,
                    'path': kwargs[path_key],
                })
                request.file_revision = file_revision
            except (FileRevision.DoesNotExist,
                    FileRevision.MultipleDocumentsReturned):
                # TODO is multipledocumentsreturned a 404?
                return {'message': 'invalid file revision'}, 404

        elif file_revision_id_key in kwargs:
            try:
                file_revision = backend.get(
                    FileRevision, {
                        'pk': kwargs[file_revision_id_key],
                        'project': request.project,
                    })
                request.file_revision = file_revision
            except FileRevision.DoesNotExist:
                return {'message': 'invalid file revision'}, 404
        else:
            return {
                'message':
                'you must specify either a snapshot ID and path or a file revision ID'
            }, 404

        return f(*args, **kwargs)
Пример #17
0
    def delete(self, project_id, user_role_id):
        with backend.transaction():
            try:
                user_role = backend.get(UserRole, {'project': request.project, 'pk': user_role_id})
                if user_role.role == 'owner' and user_role.user == request.user:
                    if len(backend.filter(UserRole, {'project': request.project,'role' : 'owner'})) == 1:
                        return {'message' : 'You are the last owner of this project, cannot remove you.'}, 400
            except UserRole.DoesNotExist:
                return {'message': 'invalid role'}, 404

            backend.delete(user_role)

        return {'message': 'success'}, 200
Пример #18
0
def delete_user(user_id, task_id=None):
    """
    What we need to do here:

    -Remove all user data from database, unless user was customer
        - Projects
        - User profile
        - AccessToken

    """
    if not task_id:
        task_id = delete_user.request.id

    try:
        user = backend.get(User, {'pk': user_id})
    except User.DoesNotExist:
        logger.error(
            "User {} does not exist! Cannot delete it.".format(user_id))
        return

    try:
        with ExclusiveTask(backend,
                           {'type': {
                               '$in': ['delete_{}'.format(user.pk)]
                           }}, {'type': 'delete_{}'.format(user.pk)},
                           task_id,
                           no_update_on_exit=True) as delete_task:

            with TaskLogger(delete_task, backend=backend, ping=True):
                with backend.transaction():
                    logger.debug("Starting deletion of user {0} ({1}).".format(
                        user.name, user.pk))

                    # Delete all related models
                    backend.filter(UserRole, {'user': user}).delete()
                    backend.filter(AccessToken, {'user': user}).delete()
                    backend.filter(User, {'pk': user.pk}).delete()

                    # Todo: Delete all of the user's projects that have no "owner" user roles anymore...

                logger.info("Deletion of user {0} ({1}) complete!".format(
                    user.name, user.pk))

    except ExclusiveTask.LockError:
        pass
    except BaseException as err:
        logger.error("Error {0}: Can't delete user {1}.".format(
            err.__class__.__name__, user))
        logger.error(traceback.format_exc())
Пример #19
0
    def post(self, project_id):

        form = ProjectTagsForm(request.form)

        if not form.validate():
            return {'message' : 'please correct the errors mentioned below.', 'errors' : form.errors}, 400

        data = form.data

        with backend.transaction():
            try:
                tag = backend.get(Tag, {'name': data['name']})
            except Tag.DoesNotExist:
                return {'message': 'invalid tag'}, 404
            request.project.tags.append(tag)
        return {'message': 'success!'}, 200
Пример #20
0
    def get(self, project_id, task_id):
        """ Returns the log for the specified project task. Accepts a from request parameter, which seeks into
        the log file to return the rest of the file.
        :param project_id: id of the project
        :param task_id: id of the task
        :return: log, its length, offset, and the task status
        """

        form = TaskLogForm(request.args)

        if not form.validate():
            return {
                'message': 'please correct the errors mentioned below.'
            }, 400

        data = form.data

        from_chr = data['from_chr']

        try:
            task = backend.get(Task, {
                'project.pk': request.project.pk,
                'pk': task_id
            },
                               raw=True)
        except Task.DoesNotExist:
            return {'message': "unknown task"}, 404

        log_path = os.path.join(settings.get('backend.path'),
                                settings.get('backend.paths.tasks'),
                                "{}.log".format(task['pk']))

        try:
            with open(log_path, "r") as task_log:
                task_log.seek(from_chr)
                content = task_log.read()

            data = {
                'task_log': content,
                'len': len(content),
                'from': from_chr,
                'task_status':
                task['status'] if 'status' in task else "unknown"
            }
            return data, 200
        except IOError:
            return {'message': "no log found {}".format(log_path)}, 404
Пример #21
0
 def get(self, project_id, task_id):
     """ Get the task with the given task id for the project with the given project id.
     :param project_id: id of the project
     :param task_id: id of the task
     :return: task information
     """
     try:
         task = backend.get(Task, {
             'project.pk': request.project.pk,
             'pk': task_id
         },
                            only=self.export_fields,
                            include=('project', ),
                            raw=True)
     except Task.DoesNotExist:
         return {'message': "unknown task"}, 404
     return {'task': self.export(task)}, 200
Пример #22
0
    def decorated_function(*args, **kwargs):

        if id_key not in kwargs:
            return {'message': 'you must specify an issue ID'}, 404
        issue_id = kwargs[id_key]
        try:
            issue = backend.get(Issue, {'pk': issue_id}, include=include)

        except Issue.DoesNotExist as e:
            return {
                'message': e.message if e.message else 'invalid issue'
            }, 404

        #we make sure the issue belongs to the project for which the user is authenticated
        if issue.project != request.project:
            return {'message': 'access denied'}, 403

        request.issue = issue
        return f(*args, **kwargs)
Пример #23
0
    def decorated_function(*args, **kwargs):

        if id_key not in kwargs:
            return {'message': 'you must specify an issue class ID'}, 404
        issue_class_id = kwargs[id_key]
        try:
            issue_class = backend.get(
                IssueClass,
                {'$or': [{
                    'pk': issue_class_id
                }, {
                    'code': issue_class_id
                }]},
                include=include)

        except IssueClass.DoesNotExist as e:
            return {
                'message': e.message if e.message else 'invalid issue class'
            }, 404

        request.issue_class = issue_class
        return f(*args, **kwargs)
def reset_project(project_id, task_id=None):
    if not task_id:
        task_id = reset_project.request.id
    try:
        project = backend.get(Project, {'pk': project_id})
    except Project.DoesNotExist:
        logger.warning(
            "Project %s does not exist and thus cannot be deleted." %
            project_id)
        return

    try:
        with ExclusiveTask(
                backend, {
                    'project.pk': project.pk,
                    'type': {
                        '$in': ['analysis', 'reset', 'delete']
                    }
                }, {
                    'type': 'reset',
                    'project': project
                }, task_id) as reset_task:
            with TaskLogger(reset_task, backend=backend, ping=True):
                _reset_project(project)
    except ExclusiveTask.LockError:
        # We were unable to acquire a lock for this project.
        logger.info(
            "Project %s (%s) is currently being processed, aborting..." %
            (project.name, project.pk))
        with backend.transaction():
            backend.update(project, {
                'last_reset': {
                    'dt': datetime.datetime.now(),
                    'status': 'blocked'
                }
            })
    finally:
        logger.info("Done.")
def analyze_project(project_id, task_id=None):
    """ Performs an analysis of the project with the given id
    :param project_id: primary key of the project
    :param task_id: celery task id
    :return:
    """

    if not task_id:
        task_id = analyze_project.request.id
    try:
        project = backend.get(Project, {'pk': project_id})
    except Project.DoesNotExist:
        logger.error("Project {} does not exist".format(project_id))
        return

    try:
        with ExclusiveTask(
                backend,
            {
                'project': project,
                'type': {
                    '$in':
                    (Task.Type.analysis, Task.Type.reset, Task.Type.delete)
                }
            },
            {
                'project': project,
                'type': Task.Type.analysis
            },
                task_id,
        ) as analysis_task:
            with TaskLogger(analysis_task, backend=backend, ping=True):
                _analyze_project(project)
    except ExclusiveTask.LockError:
        # We were unable to acquire a lock for this project.
        pass
    finally:
        logger.info("Done.")
Пример #26
0
    def post(self, project_id, role, user_id):

        with backend.transaction():
            try:
                user = self._get_user(user_id)
            except AttributeError:
                return ({'message': 'invalid user'},
                        404)

            if role not in ('admin', 'collaborator', 'owner'):
                return ({'message': 'invalid role: %s' % role},
                        403)
            try:
                user_role = backend.get(UserRole, {'project': request.project,
                                                   'user': user})
                if user_role.role == 'owner' and user_role.user == request.user and role != 'owner':
                    if len(backend.filter(UserRole, {'project': request.project,'role' : 'owner'})) == 1:
                        return {'message' : 'You are the last owner of this project, cannot remove you.'}, 400
            except UserRole.DoesNotExist:
                user_role = UserRole({'project': request.project, 'user': user})
            user_role.role = role
            backend.save(user_role)
        return ProjectRoles.get(self, project_id=project_id)
Пример #27
0
    def decorated_function(*args, **kwargs):

        if id_key not in kwargs or kwargs[id_key] is None:
            request.project = None
            if not optional:
                return {'message': 'no project was specified'}, 404
            return f(*args, **kwargs)
        try:

            project_id = kwargs[id_key]

            project = backend.get(
                Project,
                {'$or': [{
                    'pk': project_id
                }, {
                    'permalink': project_id
                }]},
                raw=raw,
                only=only,
                include=include)

            if project.get('delete', False):
                return {'message': 'project marked for deletion'}, 422

            # We get all organizations where the user is an owner
            if not private_ok and not (public_ok
                                       and project.get('public', False)):
                if request.user is None or not project.is_authorized(
                        request.user, roles=roles):
                    return {'message': 'Authorization denied'}, 403

        except Project.DoesNotExist:
            return {'message': 'Invalid project'}, 404

        request.project = project
        return f(*args, **kwargs)
Пример #28
0
 def get_file_revision(query):
     return backend.get(FileRevision, query, raw=True)
def _find_project(name_or_pk):
    try:
        return backend.get(Project,{'$or' : [{'name' : name_or_pk}, {'pk' : name_or_pk}]})
    except Project.DoesNotExist:
        raise click.ClickException("Project does not exist!")
Пример #30
0
    def post(self):
        form = SignupForm(request.form)
        if form.validate():
            with backend.transaction():
                email_matches = backend.filter(User, {'email': form.email.data})
                if len(email_matches) > 0:
                    for user in email_matches:
                        if user.delete is True:
                            return ({'message': 'Your account is scheduled for deletion. Try again in a few minutes".'},
                                    403)
                    return {'message': "A user with this e-mail address already exists. "
                                       "Please try resetting your password.",
                            'resetPasswordLink': True}, 403

                try:
                    user = backend.get(User, {'name': form.name.data.lower()})
                    return {'errors': {'name': {'message': 'This login has already been chosen by another user'}},
                            'message': 'Login already in use.'}, 403
                except User.DoesNotExist:
                    pass
                except User.MultipleDocumentsReturned:
                    return {'errors': {'name': {'message': 'This login has already been chosen by another user'}},
                            'message': 'Login already in use.'}, 403
                user = User({
                    'email': form.email.data.lower(),
                    'name': form.name.data.lower(),
                    'email_validated': False,
                    'email_validation_code': uuid.uuid4().hex,
                    'terms_accepted': form.terms.data,
                    'terms_accepted_at': datetime.datetime.utcnow(),
                    'terms_accepted_from_ip': request.remote_addr,
                    'email_settings': {
                        'newsletter': True,
                        'notifications': True,
                    },
                })
                user.set_password(form.password.data)
                backend.save(user)
                access_token = AccessToken({'user': user,
                                            'token': uuid.uuid4().hex})
                backend.save(access_token)

                user_profile = UserProfile.export(user)

                response = self.make_response({
                    'access_token': access_token.token,
                    'message': 'Success!',
                    'user': user_profile,
                })

                response.set_cookie(
                    'access_token',
                    value=access_token.token,
                    expires=(datetime.datetime.utcnow() + datetime.timedelta(days=7)),
                )

                activation_url = u"{}{}/user/validate/{}".format(
                    settings.get('url'),
                    settings.get('frontend.url'),
                    user.email_validation_code,
                )

                # Activate email
                send_mail(
                    email_to=user.email,
                    template="verify_email",
                    template_context={
                        "user_name": user.name,
                        "activation_url": activation_url,
                    })

                logger.warning("Hooray, a new user has just signed up: %s" % user.name)

                return response
        return {'message': 'Invalid data', 'errors': form.errors}, 403