Example #1
0
    def put(self, oid):
        """Update a single item in the DB.

        :arg self: The class of the object to be updated
        :arg integer oid: the ID of the object in the DB
        :returns: An HTTP status code based on the output of the action.

        More info about HTTP status codes for this action `here
        <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6>`_.

        """
        try:
            self.valid_args()
            cls_name = self.__class__.__name__
            repo = repos[cls_name]['repo']
            query_func = repos[cls_name]['get']
            existing = getattr(repo, query_func)(oid)
            if existing is None:
                raise NotFound
            ensure_authorized_to('update', existing)
            data = self._file_upload(request)
            inst = self._update_instance(existing, repo,
                                         repos,
                                         new_upload=data)
            self.refresh_cache(cls_name, oid)
            return Response(json.dumps(inst.dictize()), 200,
                            mimetype='application/json')
        except Exception as e:
            return error.format_exception(
                e,
                target=self.__class__.__name__.lower(),
                action='PUT')
Example #2
0
def categories():
    """List Categories."""
    try:
        if request.method == 'GET':
            ensure_authorized_to('read', Category)
            form = CategoryForm()
        if request.method == 'POST':
            ensure_authorized_to('create', Category)
            form = CategoryForm(request.form)
            del form.id
            if form.validate():
                slug = form.name.data.lower().replace(" ", "")
                category = Category(name=form.name.data,
                                    short_name=slug,
                                    description=form.description.data)
                project_repo.save_category(category)
                cached_cat.reset()
                msg = gettext("Category added")
                flash(msg, 'success')
            else:
                flash(gettext('Please correct the errors'), 'error')
        categories = cached_cat.get_all()
        n_projects_per_category = dict()
        for c in categories:
            n_projects_per_category[c.short_name] = \
                cached_projects.n_count(c.short_name)

        return render_template('admin/categories.html',
                               title=gettext('Categories'),
                               categories=categories,
                               n_projects_per_category=n_projects_per_category,
                               form=form)
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
Example #3
0
def new_announcement():
    """Create new announcement."""
    def respond():
        response = dict(template='admin/new_announcement.html',
                        title=gettext("Write a new post"),
                        form=form)
        return handle_content_type(response)

    form = AnnouncementForm()
    del form.id

    # project_sanitized, owner_sanitized = sanitize_project_owner(project, owner, current_user)

    if request.method != 'POST':
        ensure_authorized_to('create', Announcement())
        return respond()

    if not form.validate():
        flash(gettext('Please correct the errors'), 'error')
        return respond()

    announcement = Announcement(title=form.title.data,
                                body=form.body.data,
                                published=form.published.data,
                                media_url=form.media_url.data,
                                user_id=current_user.id)
    ensure_authorized_to('create', announcement)
    announcement_repo.save(announcement)

    msg_1 = gettext('Annnouncement created!')
    markup = Markup('<i class="icon-ok"></i> {}')
    flash(markup.format(msg_1), 'success')

    return redirect_content_type(url_for('admin.announcement'))
Example #4
0
def del_category(id):
    """Delete a category."""
    try:
        category = project_repo.get_category(id)
        if category:
            if len(cached_cat.get_all()) > 1:
                ensure_authorized_to('delete', category)
                if request.method == 'GET':
                    return render_template('admin/del_category.html',
                                           title=gettext('Delete Category'),
                                           category=category)
                if request.method == 'POST':
                    project_repo.delete_category(category)
                    msg = gettext("Category deleted")
                    flash(msg, 'success')
                    cached_cat.reset()
                    return redirect(url_for(".categories"))
            else:
                msg = gettext('Sorry, it is not possible to delete the only'
                              ' available category. You can modify it, '
                              ' click the edit button')
                flash(msg, 'warning')
                return redirect(url_for('.categories'))
        else:
            abort(404)
    except HTTPException:
        raise
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
Example #5
0
 def _create_instance_from_request(self, data):
     data = self.hateoas.remove_links(data)
     inst = self.__class__(**data)
     self._update_object(inst)
     ensure_authorized_to('create', inst)
     self._validate_instance(inst)
     return inst
Example #6
0
 def _create_json_response(self, query_result, oid):
     if len(query_result) == 1 and query_result[0] is None:
         raise abort(404)
     items = []
     for result in query_result:
         # This is for n_favs orderby case
         if not isinstance(result, DomainObject):
             if 'n_favs' in result.keys():
                 result = result[0]
         try:
             if (result.__class__ != self.__class__):
                 (item, headline, rank) = result
             else:
                 item = result
                 headline = None
                 rank = None
             datum = self._create_dict_from_model(item)
             if headline:
                 datum['headline'] = headline
             if rank:
                 datum['rank'] = rank
             ensure_authorized_to('read', item)
             items.append(datum)
         except (Forbidden, Unauthorized):
             # Remove last added item, as it is 401 or 403
             if len(items) > 0:
                 items.pop()
         except Exception:  # pragma: no cover
             raise
     if oid is not None:
         ensure_authorized_to('read', query_result[0])
         items = items[0]
     return json.dumps(items)
Example #7
0
 def _file_delete(self, request, obj):
     """Delete file object."""
     cls_name = self.__class__.__name__.lower()
     if cls_name in self.allowed_classes_upload:
         keys = obj.info.keys()
         if 'file_name' in keys and 'container' in keys:
             ensure_authorized_to('delete', obj)
             uploader.delete_file(obj.info['file_name'],
                                  obj.info['container'])
Example #8
0
 def _create_instance_from_request(self, data):
     data = self.hateoas.remove_links(data)
     inst = self.__class__(**data)
     self._update_object(inst)
     instance_name = inst.__class__.__name__
     if instance_name != 'UserScore':
         ensure_authorized_to('create', inst)
     self._validate_instance(inst)
     return inst
Example #9
0
def update_profile(name):
    """
    Update user's profile.

    Returns Jinja2 template.

    """
    user = user_repo.get_by_name(name)
    if not user:
        return abort(404)
    ensure_authorized_to('update', user)

    if not user.admin :        
        if is_amnesty_sso_enable():        
            return redirect(amnesty_url_for('/<name>/'))

    show_passwd_form = True
    if user.twitter_user_id or user.google_user_id or user.facebook_user_id:
        show_passwd_form = False
    usr = cached_users.get_user_summary(name)
    # Extend the values
    user.rank = usr.get('rank')
    user.score = usr.get('score')
    # Creation of forms
    update_form = UpdateProfileForm(obj=user)
    update_form.set_locales(current_app.config['LOCALES'])

    avatar_form = AvatarUploadForm()
    password_form = ChangePasswordForm()

    if request.method == 'POST':

        # Update user avatar
        if request.form.get('btn') == 'Upload':
            _handle_avatar_update(user, avatar_form)
        # Update user profile
        elif request.form.get('btn') == 'Profile':
            _handle_profile_update(user, update_form)
        # Update user password
        elif request.form.get('btn') == 'Password':
            _handle_password_update(user, password_form)
        # Update user external services
        elif request.form.get('btn') == 'External':
            _handle_external_services_update(user, update_form)
        # Otherwise return 415
        else:
            return abort(415)
        return redirect(url_for('.update_profile', name=user.name))

    title_msg = "Update your profile: %s" % user.fullname
    return render_template('/account/update.html',
                           form=update_form,
                           upload_form=avatar_form,
                           password_form=password_form,
                           title=title_msg,
                           show_passwd_form=show_passwd_form)
Example #10
0
def delete_announcement(id):
    announcement = announcement_repo.get_by(id=id)
    if announcement is None:
        raise abort(404)

    ensure_authorized_to('delete', announcement)
    announcement_repo.delete(announcement)
    msg_1 = gettext('Announcement deleted!')
    markup = Markup('<i class="icon-ok"></i> {}')
    flash(markup.format(msg_1), 'success')
    return redirect_content_type(url_for('admin.announcement'))
Example #11
0
 def _delete_instance(self, oid):
     repo = repos[self.__class__.__name__]['repo']
     query_func = repos[self.__class__.__name__]['get']
     inst = getattr(repo, query_func)(oid)
     if inst is None:
         raise NotFound
     ensure_authorized_to('delete', inst)
     self._log_changes(inst, None)
     delete_func = repos[self.__class__.__name__]['delete']
     getattr(repo, delete_func)(inst)
     return inst
Example #12
0
def set_gravatar(name):
    """Set gravatar for a user."""
    user = user_repo.get_by(name=name)
    if not user:
        abort(404)

    ensure_authorized_to('update', user)

    gravatar.set(user)
    flash(gettext('Your avatar has been updated! It may \
                  take some minutes to refresh...'), 'success')

    return redirect(url_for('account.update_profile', name=user.name))
Example #13
0
 def get(self, token):
     try:
         ensure_authorized_to('read', self._resource_name, token=token)
         user_tokens = self._get_all_tokens()
         if token:
             response = self._get_token(token, user_tokens)
         else:
             response = user_tokens
         return Response(json.dumps(response), mimetype='application/json')
     except Exception as e:
         return error.format_exception(
             e,
             target=self._resource_name,
             action='GET')
def sync(short_name):
    """Sync a project with a GitHub repo."""
    project = project_repo.get_by_shortname(short_name)
    if not project:  # pragma: no cover
        abort(404)
    ensure_authorized_to('update', project)
    form = GitHubURLForm(request.form)
    if request.method == 'POST' and form.validate():
        github_url = form.github_url.data
        return redirect(url_for('.import_repo', github_url=github_url,
                                short_name=project.short_name))
    elif request.method == 'POST':  # pragma: no cover
        flash(gettext('Please correct the errors'), 'error')
    return render_template('projects/github/sync.html', form=form,
                           project=project)
Example #15
0
def add_admin(user_id=None):
    """Add admin flag for user_id."""
    try:
        if user_id:
            user = user_repo.get(user_id)
            if user:
                ensure_authorized_to('update', user)
                user.admin = True
                user_repo.update(user)
                return redirect(url_for(".users"))
            else:
                msg = "User not found"
                return format_error(msg, 404)
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
Example #16
0
def reset_api_key(name):
    """
    Reset API-KEY for user.

    Returns a Jinja2 template.

    """
    user = user_repo.get_by_name(name)
    if not user:
        return abort(404)
    ensure_authorized_to('update', user)
    user.api_key = model.make_uuid()
    user_repo.update(user)
    cached_users.delete_user_summary(user.name)
    msg = gettext('New API-KEY generated')
    flash(msg, 'success')
    return redirect(url_for('account.profile', name=name))
Example #17
0
 def _create_json_response(self, query_result, oid):
     if len(query_result) == 1 and query_result[0] is None:
         raise abort(404)
     items = []
     for item in query_result:
         try:
             items.append(self._create_dict_from_model(item))
             ensure_authorized_to('read', item)
         except (Forbidden, Unauthorized):
             # Remove last added item, as it is 401 or 403
             items.pop()
         except Exception:  # pragma: no cover
             raise
     if oid is not None:
         ensure_authorized_to('read', query_result[0])
         items = items[0]
     return json.dumps(items)
Example #18
0
def featured(project_id=None):
    """List featured projects of PYBOSSA."""
    try:
        if request.method == 'GET':
            categories = cached_cat.get_all()
            projects = {}
            for c in categories:
                n_projects = cached_projects.n_count(category=c.short_name)
                projects[c.short_name] = cached_projects.get(
                    category=c.short_name,
                    page=1,
                    per_page=n_projects)
            response = dict(template = '/admin/projects.html',
                            projects=projects,
                            categories=categories,
                            form=dict(csrf=generate_csrf()))
            return handle_content_type(response)
        else:
            project = project_repo.get(project_id)
            if project:
                ensure_authorized_to('update', project)
                if request.method == 'POST':
                    if project.featured is True:
                        msg = "Project.id %s already featured" % project_id
                        return format_error(msg, 415)
                    cached_projects.reset()
                    project.featured = True
                    project_repo.update(project)
                    return json.dumps(project.dictize())

                if request.method == 'DELETE':
                    if project.featured is False:
                        msg = 'Project.id %s is not featured' % project_id
                        return format_error(msg, 415)
                    cached_projects.reset()
                    project.featured = False
                    project_repo.update(project)
                    return json.dumps(project.dictize())
            else:
                msg = 'Project.id %s not found' % project_id
                return format_error(msg, 404)
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
Example #19
0
def start_export(name):
    """
    Starts a export of all user data according to EU GDPR

    Data will be available on GET /export after it is processed

    """
    user = user_repo.get_by_name(name)
    if not user:
        return abort(404)
    if user.id != current_user.id:
        return abort(403)

    ensure_authorized_to('update', user)
    export_queue.enqueue(export_userdata,
                         user_id=user.id)
    msg = gettext('GDPR export started')
    flash(msg, 'success')
    return redirect_content_type(url_for('account.profile', name=name))
Example #20
0
    def _file_upload(self, data):
        """Method that must be overriden by the class to allow file uploads for
        only a few classes."""
        cls_name = self.__class__.__name__.lower()
        content_type = 'multipart/form-data'
        if (content_type in request.headers.get('Content-Type') and
                cls_name in self.allowed_classes_upload):
            tmp = dict()
            for key in request.form.keys():
                tmp[key] = request.form[key]

            if isinstance(self, announcement.Announcement):
                # don't check project id for announcements
                ensure_authorized_to('create', self)
                upload_method = current_app.config.get('UPLOAD_METHOD')
                if request.files.get('file') is None:
                    raise AttributeError
                _file = request.files['file']
                container = "user_%s" % current_user.id
            else:
                ensure_authorized_to('create', self.__class__,
                                    project_id=tmp['project_id'])
                project = project_repo.get(tmp['project_id'])
                upload_method = current_app.config.get('UPLOAD_METHOD')
                if request.files.get('file') is None:
                    raise AttributeError
                _file = request.files['file']
                if current_user.admin:
                    container = "user_%s" % project.owner.id
                else:
                    container = "user_%s" % current_user.id
            uploader.upload_file(_file,
                                 container=container)
            file_url = get_avatar_url(upload_method,
                                      _file.filename, container)
            tmp['media_url'] = file_url
            if tmp.get('info') is None:
                tmp['info'] = dict()
            tmp['info']['container'] = container
            tmp['info']['file_name'] = _file.filename
            return tmp
        else:
            return None
Example #21
0
def del_admin(user_id=None):
    """Del admin flag for user_id."""
    try:
        if user_id:
            user = user_repo.get(user_id)
            if user:
                ensure_authorized_to('update', user)
                user.admin = False
                user_repo.update(user)
                return redirect(url_for('.users'))
            else:
                msg = "User.id not found"
                return format_error(msg, 404)
        else:  # pragma: no cover
            msg = "User.id is missing for method del_admin"
            return format_error(msg, 415)
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
Example #22
0
def update_category(id):
    """Update a category."""
    try:
        category = project_repo.get_category(id)
        if category:
            ensure_authorized_to('update', category)
            form = CategoryForm(obj=category)
            form.populate_obj(category)
            if request.method == 'GET':
                response = dict(template='admin/update_category.html',
                                title=gettext('Update Category'),
                                category=category,
                                form=form)
                return handle_content_type(response)
            if request.method == 'POST':
                form = CategoryForm(request.body)
                if form.validate():
                    slug = form.name.data.lower().replace(" ", "")
                    new_category = Category(id=form.id.data,
                                            name=form.name.data,
                                            short_name=slug)
                    project_repo.update_category(new_category)
                    cached_cat.reset()
                    msg = gettext("Category updated")
                    flash(msg, 'success')
                    return redirect_content_type(url_for(".categories"))
                else:
                    msg = gettext("Please correct the errors")
                    flash(msg, 'success')
                    response = dict(template='admin/update_category.html',
                                    title=gettext('Update Category'),
                                    category=category,
                                    form=form)
                    return handle_content_type(response)
        else:
            abort(404)
    except HTTPException:
        raise
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
Example #23
0
 def _update_instance(self, oid):
     repo = repos[self.__class__.__name__]['repo']
     query_func = repos[self.__class__.__name__]['get']
     existing = getattr(repo, query_func)(oid)
     if existing is None:
         raise NotFound
     ensure_authorized_to('update', existing)
     data = json.loads(request.data)
     # Remove hateoas links
     data = self.hateoas.remove_links(data)
     # may be missing the id as we allow partial updates
     data['id'] = oid
     self.__class__(**data)
     old = self.__class__(**existing.dictize())
     for key in data:
         setattr(existing, key, data[key])
     update_func = repos[self.__class__.__name__]['update']
     self._validate_instance(existing)
     getattr(repo, update_func)(existing)
     self._log_changes(old, existing)
     return existing
Example #24
0
    def test_auth_owner_can_update_results(self):
        """Test auth owner can update results of a specific project"""

        result = self.create_result()
        result.info = dict(new='value')

        assert ensure_authorized_to('update', result)

        updated_result = self.result_repo.get_by(id=result.id)

        err_msg = "The result has not been updated"
        assert updated_result.info['new'] == 'value', err_msg
Example #25
0
    def get(self, oid):
        """Get an object.

        Returns an item from the DB with the request.data JSON object or all
        the items if oid == None

        :arg self: The class of the object to be retrieved
        :arg integer oid: the ID of the object in the DB
        :returns: The JSON item/s stored in the DB

        """
        try:
            ensure_authorized_to('read', self.__class__)
            query = self._db_query(oid)
            json_response = self._create_json_response(query, oid)
            return Response(json_response, mimetype='application/json')
        except Exception as e:
            return error.format_exception(
                e,
                target=self.__class__.__name__.lower(),
                action='GET')
Example #26
0
def reset_api_key(name):
    """
    Reset API-KEY for user.

    Returns a Jinja2 template.

    """
    if request.method == 'POST':
        user = user_repo.get_by_name(name)
        if not user:
            return abort(404)
        ensure_authorized_to('update', user)
        user.api_key = model.make_uuid()
        user_repo.update(user)
        cached_users.delete_user_summary(user.name)
        msg = gettext('New API-KEY generated')
        flash(msg, 'success')
        return redirect_content_type(url_for('account.profile', name=name))
    else:
        csrf = dict(form=dict(csrf=generate_csrf()))
        return jsonify(csrf)
Example #27
0
 def _update_instance(self, oid):
     repo = repos[self.__class__.__name__]['repo']
     query_func = repos[self.__class__.__name__]['get']
     existing = getattr(repo, query_func)(oid)
     if existing is None:
         raise NotFound
     ensure_authorized_to('update', existing)
     data = json.loads(request.data)
     # Remove hateoas links
     data = self.hateoas.remove_links(data)
     # may be missing the id as we allow partial updates
     data['id'] = oid
     self.__class__(**data)
     old = self.__class__(**existing.dictize())
     for key in data:
         setattr(existing, key, data[key])
     update_func = repos[self.__class__.__name__]['update']
     self._validate_instance(existing)
     getattr(repo, update_func)(existing)
     self._log_changes(old, existing)
     return existing
Example #28
0
    def test_auth_owner_can_update_results(self):
        """Test auth owner can update results of a specific project"""

        result = self.create_result()
        result.info = dict(new='value')

        assert ensure_authorized_to('update', result)

        updated_result = self.result_repo.get_by(id=result.id)

        err_msg = "The result has not been updated"
        assert updated_result.info['new'] == 'value', err_msg
Example #29
0
def reset_api_key(name):
    """
    Reset API-KEY for user.

    Returns a Jinja2 template.

    """
    if request.method == 'POST':
        user = user_repo.get_by_name(name)
        if not user:
            return abort(404)
        ensure_authorized_to('update', user)
        user.api_key = model.make_uuid()
        user_repo.update(user)
        cached_users.delete_user_summary(user.name)
        msg = gettext('New API-KEY generated')
        flash(msg, 'success')
        return redirect_content_type(url_for('account.profile', name=name))
    else:
        csrf = dict(form=dict(csrf=generate_csrf()))
        return jsonify(csrf)
Example #30
0
    def get(self, oid):
        """Get an object.

        Returns an item from the DB with the request.data JSON object or all
        the items if oid == None

        :arg self: The class of the object to be retrieved
        :arg integer oid: the ID of the object in the DB
        :returns: The JSON item/s stored in the DB

        """
        try:
            ensure_authorized_to('read', self.__class__)
            query = self._db_query(oid)
            json_response = self._create_json_response(query, oid)
            return Response(json_response, mimetype='application/json')
        except Exception as e:
            return error.format_exception(
                e,
                target=self.__class__.__name__.lower(),
                action='GET')
Example #31
0
def featured(project_id=None):
    """List featured projects of PyBossa."""
    try:
        if request.method == 'GET':
            categories = cached_cat.get_all()
            projects = {}
            for c in categories:
                n_projects = cached_projects.n_count(category=c.short_name)
                projects[c.short_name] = cached_projects.get(
                    category=c.short_name, page=1, per_page=n_projects)
            return render_template('/admin/projects.html',
                                   projects=projects,
                                   categories=categories)
        else:
            project = project_repo.get(project_id)
            if project:
                ensure_authorized_to('update', project)
                if request.method == 'POST':
                    if project.featured is True:
                        msg = "Project.id %s already featured" % project_id
                        return format_error(msg, 415)
                    cached_projects.reset()
                    project.featured = True
                    project_repo.update(project)
                    return json.dumps(project.dictize())

                if request.method == 'DELETE':
                    if project.featured is False:
                        msg = 'Project.id %s is not featured' % project_id
                        return format_error(msg, 415)
                    cached_projects.reset()
                    project.featured = False
                    project_repo.update(project)
                    return json.dumps(project.dictize())
            else:
                msg = 'Project.id %s not found' % project_id
                return format_error(msg, 404)
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
def reset_api_key(name):
    """
    Reset API-KEY for user.

    Returns a Jinja2 template.

    """
    user = user_repo.get_by_name(name)
    if not user:
        return abort(404)
    ensure_authorized_to('update', user)

    if not user.admin :        
        if is_amnesty_sso_enable():        
            return redirect(amnesty_url_for('/<name>/'))

    user.api_key = model.make_uuid()
    user_repo.update(user)
    cached_users.delete_user_summary(user.name)
    msg = gettext('New API-KEY generated')
    flash(msg, 'success')
    return redirect(url_for('account.profile', name=name))
    def get(self, oid):
        """Get all completed tasks. Need admin access"""
        try:
            ensure_authorized_to('read', self.__class__)
            # check admin access
            if 'api_key' in request.args.keys():
                apikey = request.args['api_key']
                user = user_repo.get_by(api_key=apikey)
                if not user or user.admin is False:
                    raise BadRequest("Insufficient privilege to the request")
            else:
                raise BadRequest("Insufficient privilege to the request")

            # set filter from args
            # add 'state'='completed' if missing
            filters = {}
            filters['state'] = 'completed'
            for k in request.args.keys():
                if k not in ['limit', 'offset', 'api_key']:
                    # 'exported' column belongs to Task class
                    # ignore it for attr check in TaskRun class
                    # but add it to filter so that its checked
                    # against Task class in filter_completed_task_runs_by
                    if k not in ['exported']:
                        # Raise an error if the k arg is not a column
                        getattr(self.__class__, k)
                    filters[k] = request.args[k]

            # set limit, offset
            limit, offset = self._set_limit_and_offset()
            # query database to obtain the requested data
            query = task_repo.filter_tasks_by(limit=limit,
                                              offset=offset,
                                              **filters)
            json_response = self._create_json_response(query, oid)
            return Response(json_response, mimetype='application/json')
        except Exception as e:
            return error.format_exception(
                e, target=self.__class__.__name__.lower(), action='GET')
Example #34
0
def update_announcement(id):
    announcement = announcement_repo.get_by(id=id)
    if announcement is None:
        raise abort(404)

    def respond():
        response = dict(template='admin/new_announcement.html',
                        title=gettext("Edit a post"),
                        levelOptions=json.dumps(
                            current_app.config['ANNOUNCEMENT_LEVEL_OPTIONS']),
                        form=form)
        return handle_content_type(response)

    form = AnnouncementForm()

    if request.method != 'POST':
        ensure_authorized_to('update', announcement)
        form = AnnouncementForm(obj=announcement)
        return respond()

    if not form.validate():
        flash(gettext('Please correct the errors'), 'error')
        return respond()

    ensure_authorized_to('update', announcement)
    announcement = Announcement(id=form.id.data,
                                title=form.title.data,
                                body=form.body.data,
                                info=json.loads(form.info.data),
                                published=form.published.data,
                                media_url=form.media_url.data,
                                user_id=current_user.id)
    announcement_repo.update(announcement)

    msg_1 = gettext('Announcement updated!')
    markup = Markup('<i class="icon-ok"></i> {}')
    flash(markup.format(msg_1), 'success')

    return redirect_content_type(url_for('admin.announcement'))
Example #35
0
def update_category(id):
    """Update a category."""
    try:
        category = project_repo.get_category(id)
        if category:
            ensure_authorized_to('update', category)
            form = CategoryForm(obj=category)
            form.populate_obj(category)
            if request.method == 'GET':
                return render_template('admin/update_category.html',
                                       title=gettext('Update Category'),
                                       category=category,
                                       form=form)
            if request.method == 'POST':
                form = CategoryForm(request.form)
                if form.validate():
                    slug = form.name.data.lower().replace(" ", "")
                    new_category = Category(id=form.id.data,
                                            name=form.name.data,
                                            short_name=slug)
                    project_repo.update_category(new_category)
                    cached_cat.reset()
                    msg = gettext("Category updated")
                    flash(msg, 'success')
                    return redirect(url_for(".categories"))
                else:
                    msg = gettext("Please correct the errors")
                    flash(msg, 'success')
                    return render_template('admin/update_category.html',
                                           title=gettext('Update Category'),
                                           category=category,
                                           form=form)
        else:
            abort(404)
    except HTTPException:
        raise
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
 def _create_instance_from_request(self, data):
     # Remove facebook_user_id key and retrieve the respective user
     fb_user = None
     if "facebook_user_id" in data.keys():
         fb_api = UserFbAPI()
         fb_user_id = data["facebook_user_id"]
         fb_user = fb_api.get_user_by_fb_id(fb_user_id)
         del data["facebook_user_id"]
     
     data = self.hateoas.remove_links(data)
     inst = self.__class__(**data)
     
     if fb_user == None:
         self._update_object(inst)
     else:
         inst.user_id = fb_user.id
     
     getattr(require, self.__class__.__name__.lower()).create(inst)
     self._update_object(inst)
     ensure_authorized_to('create', inst)
     self._validate_instance(inst)
     return inst
Example #37
0
 def _create_json_response(self, query_result, oid):
     if len(query_result) == 1 and query_result[0] is None:
         raise abort(404)
     items = []
     for result in query_result:
         # This is for n_favs orderby case
         if not isinstance(result, DomainObject):
             if 'n_favs' in result.keys():
                 result = result[0]
         try:
             if (result.__class__ != self.__class__):
                 (item, headline, rank) = result
             else:
                 item = result
                 headline = None
                 rank = None
             if not self._verify_auth(item):
                 continue
             datum = self._create_dict_from_model(item)
             if headline:
                 datum['headline'] = headline
             if rank:
                 datum['rank'] = rank
             ensure_authorized_to('read', item)
             items.append(datum)
         except (Forbidden, Unauthorized):
             # Remove last added item, as it is 401 or 403
             if len(items) > 0:
                 items.pop()
         except Exception:  # pragma: no cover
             raise
     if oid is not None:
         if not items:
             raise Forbidden('Forbidden')
         ensure_authorized_to('read', query_result[0])
         self._sign_item(items[0])
         items = items[0]
     return json.dumps(items)
Example #38
0
def add_admin(user_id=None):
    """Add admin flag for user_id."""
    try:
        if user_id:
            user = user_repo.get(user_id)
            if not user:
                return format_error('User not found', 404)

            if not user.enabled:
                markup = Markup('<strong>{}</strong> {} <strong>{}</strong>')
                flash(markup.format(gettext('User account '),
                                    user.fullname,
                                    gettext(' is disabled')))
                return redirect_content_type(url_for(".users"))

            if not can_have_super_user_access(user):
                markup = Markup('<strong>{} {}</strong> {} {}')
                flash(markup.format(gettext('Denied admin privileges to'),
                                    user.fullname,
                                    user.email_addr,
                                    'disqualify for admin access.'))
                return redirect_content_type(url_for(".users"))

            ensure_authorized_to('update', user)

            admins_emails = [u.email_addr for u in user_repo.filter_by(admin=True)]
            admins_msg = generate_notification_email_for_admins(user, admins_emails, "Admin")
            mail_queue.enqueue(send_mail, admins_msg)
            user.admin = True
            user_repo.update(user)

            msg = generate_invitation_email_for_admins_subadmins(user, "Admin")
            mail_queue.enqueue(send_mail, msg)
            return redirect_content_type(url_for(".users"))

    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
Example #39
0
def categories():
    """List Categories."""
    try:
        if request.method == 'GET':
            ensure_authorized_to('read', Category)
            form = CategoryForm()
        if request.method == 'POST':
            ensure_authorized_to('create', Category)
            form = CategoryForm(request.body)
            del form.id
            if form.validate():
                slug = form.name.data.lower().replace(" ", "")
                category = Category(name=form.name.data,
                                    short_name=slug,
                                    description=form.description.data)
                project_repo.save_category(category)
                cached_cat.reset()
                msg = gettext("Category added")
                flash(msg, 'success')
            else:
                flash(gettext('Please correct the errors'), 'error')
        categories = cached_cat.get_all()
        categories = sorted(categories,
                            key=lambda category: category.name)
        n_projects_per_category = dict()
        for c in categories:
            n_projects_per_category[c.short_name] = \
                cached_projects.n_count(c.short_name)

        response = dict(template='admin/categories.html',
                        title=gettext('Categories'),
                        categories=categories,
                        n_projects_per_category=n_projects_per_category,
                        form=form)
        return handle_content_type(response)
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
Example #40
0
def del_category(id):
    """Delete a category."""
    try:
        category = project_repo.get_category(id)
        if category:
            if len(cached_cat.get_all()) > 1:
                ensure_authorized_to('delete', category)
                if request.method == 'GET':
                    response = dict(template='admin/del_category.html',
                                    title=gettext('Delete Category'),
                                    category=category,
                                    form=dict(csrf=generate_csrf()))
                    return handle_content_type(response)
                if request.method == 'POST':
                    project_repo.delete_category(category)
                    msg = gettext("Category deleted")
                    flash(msg, 'success')
                    cached_cat.reset()
                    return redirect_content_type(url_for(".categories"))
            else:
                msg = gettext('Sorry, it is not possible to delete the only'
                              ' available category. You can modify it, '
                              ' click the edit button')
                flash(msg, 'warning')
                return redirect_content_type(url_for('.categories'))
        else:
            abort(404)
    except IntegrityError:
        msg = gettext('Sorry, it is not possible to delete a category'
                      ' if there are projects assigned to it.')
        flash(msg, 'error')
        return redirect_content_type(url_for('.categories'))
    except HTTPException:
        raise
    except Exception as e:  # pragma: no cover
        current_app.logger.error(e)
        return abort(500)
Example #41
0
def new_announcement():
    """Create new announcement."""
    def respond():
        response = dict(template='admin/new_announcement.html',
                        title=gettext("Write a new post"),
                        levelOptions=json.dumps(
                            current_app.config['ANNOUNCEMENT_LEVEL_OPTIONS']),
                        form=form)
        return handle_content_type(response)

    form = AnnouncementForm()
    del form.id

    # project_sanitized, owner_sanitized = sanitize_project_owner(project, owner, current_user)

    if request.method != 'POST':
        ensure_authorized_to('create', Announcement())
        return respond()

    if not form.validate():
        flash(gettext('Please correct the errors'), 'error')
        return respond()

    announcement = Announcement(title=form.title.data,
                                body=form.body.data,
                                info=json.loads(form.info.data),
                                published=form.published.data,
                                media_url=form.media_url.data,
                                user_id=current_user.id)
    ensure_authorized_to('create', announcement)
    announcement_repo.save(announcement)

    msg_1 = gettext('Annnouncement created!')
    markup = Markup('<i class="icon-ok"></i> {}')
    flash(markup.format(msg_1), 'success')

    return redirect_content_type(url_for('admin.announcement'))
Example #42
0
def update_announcement(id):
    announcement = announcement_repo.get_by(id=id)
    if announcement is None:
        raise abort(404)

    def respond():
        response = dict(template='admin/new_announcement.html',
                        title=gettext("Edit a post"),
                        form=form)
        return handle_content_type(response)

    form = AnnouncementForm()

    if request.method != 'POST':
        ensure_authorized_to('update', announcement)
        form = AnnouncementForm(obj=announcement)
        return respond()

    if not form.validate():
        flash(gettext('Please correct the errors'), 'error')
        return respond()

    ensure_authorized_to('update', announcement)
    announcement = Announcement(id=form.id.data,
                                title=form.title.data,
                                body=form.body.data,
                                published=form.published.data,
                                media_url=form.media_url.data,
                                user_id=current_user.id)
    announcement_repo.update(announcement)

    msg_1 = gettext('Announcement updated!')
    markup = Markup('<i class="icon-ok"></i> {}')
    flash(markup.format(msg_1), 'success')

    return redirect_content_type(url_for('admin.announcement'))
Example #43
0
def visualize(short_name, task_id):
  """Return a file with all the TaskRuns for a given Task"""
  # Check if it a supported geotagx project whose schema we know
  if 'GEOTAGX_SUPPORTED_PROJECTS_SCHEMA' in current_app.config.keys() \
		and short_name in current_app.config['GEOTAGX_SUPPORTED_PROJECTS_SCHEMA'].keys():
	  # Check if the project exists
	  (project, owner, n_tasks, n_task_runs,
	   overall_progress, last_activity) = projects_view.project_by_shortname(short_name)

	  ensure_authorized_to('read', project)
	  redirect_to_password = projects_view._check_if_redirect_to_password(project)
	  if redirect_to_password:
	      return redirect_to_password

	  # Check if the task belongs to the project and exists
	  task = task_repo.get_task_by(project_id=project.id, id=task_id)
	  if task:
	      taskruns = task_repo.filter_task_runs_by(task_id=task_id, project_id=project.id)
	      results = [tr.dictize() for tr in taskruns]
	      return render_template('geotagx/projects/task_runs_visualize.html',
			                           project=project,
			                           owner=owner,
			                           n_tasks=n_tasks,
			                           n_task_runs=n_task_runs,
			                           overall_progress=overall_progress,
			                           last_activity=last_activity,
			                           n_completed_tasks=cached_projects.n_completed_tasks(project.id),
			                           n_volunteers=cached_projects.n_volunteers(project.id),
			                           task_info = task.info,
			                           task_runs_json = results,
			                           geotagx_project_template_schema = \
			                           	current_app.config['GEOTAGX_SUPPORTED_PROJECTS_SCHEMA'][short_name])
	  else:
	      return abort(404)
  else:
  	return abort(404)
Example #44
0
def users(user_id=None):
    """Manage users of PyBossa."""
    form = SearchForm(request.form)
    users = [user for user in user_repo.filter_by(admin=True)
             if user.id != current_user.id]

    if request.method == 'POST' and form.user.data:
        query = form.user.data
        found = [user for user in user_repo.search_by_name(query)
                 if user.id != current_user.id]
        [ensure_authorized_to('update', found_user) for found_user in found]
        if not found:
            flash("<strong>Ooops!</strong> We didn't find a user "
                  "matching your query: <strong>%s</strong>" % form.user.data)
        return render_template('/admin/users.html', found=found, users=users,
                               title=gettext("Manage Admin Users"),
                               form=form)

    return render_template('/admin/users.html', found=[], users=users,
                           title=gettext("Manage Admin Users"), form=form)
Example #45
0
def users(user_id=None):
    """Manage users of PYBOSSA."""
    form = SearchForm(request.body)
    users = [
        user for user in user_repo.filter_by(admin=True)
        if user.id != current_user.id
    ]

    if request.method == 'POST' and form.user.data:
        query = form.user.data
        filters = {'admin': True, 'enabled': True}
        found = [
            user
            for user in user_repo.search_by_name_orfilters(query, **filters)
            if user.id != current_user.id
        ]
        [ensure_authorized_to('update', found_user) for found_user in found]
        if not found:
            markup = Markup('<strong>{}</strong> {} <strong>{}</strong>')
            flash(
                markup.format(
                    gettext("Ooops!"),
                    gettext(
                        "We didn't find any enabled user matching your query:"
                    ), form.user.data))

        response = dict(template='/admin/users.html',
                        found=found,
                        users=users,
                        title=gettext("Manage Admin Users"),
                        form=form)
        return handle_content_type(response)

    response = dict(template='/admin/users.html',
                    found=[],
                    users=users,
                    title=gettext("Manage Admin Users"),
                    form=form)
    return handle_content_type(response)
Example #46
0
def subadminusers():
    """Manage subadminusers of PyBossa."""
    form = SearchForm(request.form)
    users = [
        user for user in user_repo.filter_by(subadmin=True)
        if user.id != current_user.id
    ]

    if request.method == 'POST' and form.user.data:
        query = form.user.data

        filters = {'subadmin': True, 'enabled': True}
        found = [
            user
            for user in user_repo.search_by_name_orfilters(query, **filters)
            if user.id != current_user.id
        ]
        [ensure_authorized_to('update', found_user) for found_user in found]
        if not found:
            markup = Markup('<strong>{}</strong> {} <strong>{}</strong>')
            flash(
                markup.format(
                    gettext('Ooops!'),
                    gettext(
                        "We didn't find any enabled user matching your query:"
                    ), form.user.data))

        return render_template('/admin/subadminusers.html',
                               found=found,
                               users=users,
                               title=gettext("Manage Subadmin Users"),
                               form=form)

    return render_template('/admin/subadminusers.html',
                           found=[],
                           users=users,
                           title=gettext("Manage Subadmin Users"),
                           form=form)
Example #47
0
    def test_admin_user_can_save_results(self):
        """Test admin users cannot save results of a specific project"""

        result = Result()

        assert ensure_authorized_to('create', result)
Example #48
0
def update_profile(name):
    """
    Update user's profile.

    Returns Jinja2 template.

    """
    user = user_repo.get_by_name(name)
    if not user:
        return abort(404)
    if current_user.name != name:
        return abort(403)
    ensure_authorized_to('update', user)
    show_passwd_form = True
    if user.twitter_user_id or user.google_user_id or user.facebook_user_id:
        show_passwd_form = False
    usr = cached_users.get_user_summary(name)
    # Extend the values
    user.rank = usr.get('rank')
    user.score = usr.get('score')
    btn = request.body.get('btn', 'None').capitalize()
    if btn != 'Profile':
        update_form = UpdateProfileForm(formdata=None, obj=user)
    else:
        update_form = UpdateProfileForm(obj=user)
    update_form.set_locales(current_app.config['LOCALES'])
    avatar_form = AvatarUploadForm()
    password_form = ChangePasswordForm()

    title_msg = "Update your profile: %s" % user.fullname

    if request.method == 'POST':
        # Update user avatar
        succeed = False
        btn = request.body.get('btn', 'None').capitalize()
        if btn == 'Upload':
            succeed = _handle_avatar_update(user, avatar_form)
        # Update user profile
        elif btn == 'Profile':
            succeed = _handle_profile_update(user, update_form)
        # Update user password
        elif btn == 'Password':
            succeed = _handle_password_update(user, password_form)
        # Update user external services
        elif btn == 'External':
            succeed = _handle_external_services_update(user, update_form)
        # Otherwise return 415
        else:
            return abort(415)
        if succeed:
            cached_users.delete_user_summary(user.name)
            return redirect_content_type(url_for('.update_profile',
                                                 name=user.name),
                                         status=SUCCESS)
        else:
            data = dict(template='/account/update.html',
                        form=update_form,
                        upload_form=avatar_form,
                        password_form=password_form,
                        title=title_msg,
                        show_passwd_form=show_passwd_form)
            return handle_content_type(data)

    data = dict(template='/account/update.html',
                form=update_form,
                upload_form=avatar_form,
                password_form=password_form,
                title=title_msg,
                show_passwd_form=show_passwd_form)
    return handle_content_type(data)
Example #49
0
def update_volume(short_name, volume_id):
    """Update a volume."""
    category = project_repo.get_category_by(short_name=short_name)
    if not category:  # pragma: no cover
        abort(404)

    ensure_authorized_to('update', category)
    volumes = category.info.get('volumes', [])

    try:
        volume = [v for v in volumes if v['id'] == volume_id][0]
    except IndexError:
        abort(404)

    form = VolumeForm(**volume)
    form.category_id.data = category.id
    all_importers = importer.get_all_importer_names()
    form.importer.choices = [(name, name) for name in all_importers]

    upload_form = AvatarUploadForm()
    import_form = GenericBulkTaskImportForm()(volume['importer'],
                                              **volume.get('data', {}))

    def update():
        """Helper function to update the current volume."""
        try:
            idx = [
                i for i, _vol in enumerate(volumes) if _vol['id'] == volume_id
            ][0]
        except IndexError:  # pragma: no cover
            abort(404)
        volumes[idx] = volume
        category.info['volumes'] = volumes
        project_repo.update_category(category)

    cat_projects = project_repo.filter_by(category_id=category.id)
    has_projects = len(
        [p for p in cat_projects if p.info.get('volume_id') == volume_id]) > 0

    if request.method == 'POST':
        # Process task import form
        if (request.form.get('btn') == 'Import'
                or request.body.get('btn') == 'Import'):

            import_form = GenericBulkTaskImportForm()(volume['importer'],
                                                      request.body)
            if import_form.validate():
                if has_projects:
                    flash('Update failed as projects have already been built',
                          'error')
                else:
                    volume['data'] = import_form.get_import_data()
                    import_data = import_form.get_import_data()
                    try:
                        importer.count_tasks_to_import(**import_data)
                        update()
                        flash('Volume updated', 'success')
                    except BulkImportException as err:
                        flash(err.message, 'error')

            else:
                flash('Please correct the errors', 'error')

        # Process volume details form
        elif request.form.get('btn') != 'Upload':
            form = VolumeForm(request.body)
            all_importers = importer.get_all_importer_names()
            form.importer.choices = [(name, name) for name in all_importers]

            if form.validate():
                if has_projects:
                    flash('Update failed as projects have already been built',
                          'error')
                else:
                    volume['name'] = form.name.data
                    volume['short_name'] = form.short_name.data
                    volume['importer'] = form.importer.data
                    update()
                    flash('Volume updated', 'success')
            else:
                flash('Please correct the errors', 'error')

        # Process thumbnail upload form
        else:
            if upload_form.validate_on_submit():
                _file = request.files['avatar']
                coordinates = (upload_form.x1.data, upload_form.y1.data,
                               upload_form.x2.data, upload_form.y2.data)
                suffix = time.time()
                _file.filename = "volume_{0}_{1}.png".format(
                    volume['id'], suffix)
                container = "category_{}".format(category.id)
                uploader.upload_file(_file,
                                     container=container,
                                     coordinates=coordinates)

                # Delete previous thumbnail from storage
                if volume.get('thumbnail'):
                    uploader.delete_file(volume['thumbnail'], container)
                volume['thumbnail'] = _file.filename
                volume['container'] = container
                upload_method = current_app.config.get('UPLOAD_METHOD')
                thumbnail_url = get_avatar_url(upload_method, _file.filename,
                                               container)
                volume['thumbnail_url'] = thumbnail_url
                update()
                project_repo.save_category(category)
                flash('Thumbnail updated', 'success')
                url = url_for('.get_volumes', short_name=category.short_name)
                return redirect_content_type(url)
            else:
                flash('You must provide a file', 'error')

    response = dict(form=form,
                    all_importers=all_importers,
                    upload_form=upload_form,
                    import_form=import_form,
                    volume=volume,
                    has_projects=has_projects)
    return handle_content_type(response)
Example #50
0
    def test_admin_user_can_read_result(self):
        """Test admin users can read results"""

        result = self.create_result()

        assert ensure_authorized_to('read', result)