Example #1
0
    def prefill_search_user(self, search):
        """ Prefill the search user

        :param SearchQuery search: The search query instance
        """

        current_user = get_user(required=False)
        search.is_admin = is_admin(current_user)

        if search.is_admin and search.args.get('user'):
            search.user = get_resource_service('users').find_one(
                req=None, _id=search.args['user'])
            search.is_admin = is_admin(search.user)
        else:
            search.user = current_user
Example #2
0
def set_product_query(query,
                      company,
                      user=None,
                      navigation_id=None,
                      product_type=None):
    """
    Checks the user for admin privileges
    If user is administrator then there's no filtering
    If user is not administrator then products apply if user has a company
    If user is not administrator and has no company then everything will be filtered
    :param query: search query
    :param company: company
    :param user: user to check against (used for notification checking)
    :param navigation_id: navigation to filter products
    :param product_type: product_type to filter products
    If not provided session user will be checked
    """
    products = None

    if product_type and company:
        products = get_products_by_company(company['_id'],
                                           product_type=product_type)
    else:
        if is_admin(user):
            if navigation_id:
                products = get_products_by_navigation(navigation_id)
            else:
                return  # admin will see everything by default

        if company:
            products = get_products_by_company(company['_id'], navigation_id)
        else:
            # user does not belong to a company so blocking all stories
            abort(403, gettext('User does not belong to a company.'))

    query['bool']['should'] = []
    product_ids = [
        p['sd_product_id'] for p in products if p.get('sd_product_id')
    ]
    if product_ids:
        query['bool']['should'].append(
            {'terms': {
                'products.code': product_ids
            }})

    for product in products:
        if product.get('query'):
            if product['query'] == '_featured':
                if navigation_id:  # only return featured when nav item is selected
                    raise FeaturedQuery
            else:
                query['bool']['should'].append(query_string(product['query']))

    query['bool']['minimum_should_match'] = 1

    if not query['bool']['should']:
        abort(403, gettext('Your company doesn\'t have any products defined.'))
Example #3
0
def edit(_id):
    if flask.request.args.get('context', '') == 'wire':
        items = get_items_for_user_action([_id], 'items')
        if not items:
            return

        item = items[0]
        if is_json_request(flask.request):
            return flask.jsonify(item)

    if 'print' in flask.request.args:
        assert flask.request.args.get('monitoring_profile')
        monitoring_profile = get_entity_or_404(
            flask.request.args.get('monitoring_profile'), 'monitoring')
        items = get_items_for_monitoring_report([_id],
                                                monitoring_profile,
                                                full_text=True)
        flask.request.view_args['date_items_dict'] = get_date_items_dict(items)
        flask.request.view_args['monitoring_profile'] = monitoring_profile
        flask.request.view_args['monitoring_report_name'] = app.config.get(
            'MONITORING_REPORT_NAME', 'Newsroom')
        flask.request.view_args['print'] = True
        return wire_print(_id)

    profile = find_one('monitoring', _id=ObjectId(_id))
    if not profile:
        return NotFound(gettext('monitoring Profile not found'))

    if flask.request.method == 'POST':
        form = MonitoringForm(monitoring=profile)
        if form.validate_on_submit():
            updates = form.data
            request_updates = flask.request.get_json()

            # If the updates have anything other than 'users', only admin or monitoring_admin can update
            if len(request_updates.keys()
                   ) == 1 and 'users' not in request_updates:
                user = get_user()
                if not is_admin(user):
                    return jsonify({'error': 'Bad request'}), 400

                company = get_entity_or_404(profile['company'], 'companies')
                if str(user['_id']) != str(
                        company.get('monitoring_administrator')):
                    return jsonify({'error': 'Bad request'}), 400

            process_form_request(updates, request_updates, form)
            set_version_creator(updates)
            get_resource_service('monitoring').patch(ObjectId(_id),
                                                     updates=updates)
            return jsonify({'success': True}), 200
        return jsonify(form.errors), 400
    return jsonify(profile), 200
Example #4
0
def is_company_enabled(user, company=None):
    """
    Checks if the company of the user is enabled
    """
    if not user.get('company'):
        # there's no company assigned return true for admin user else false
        return True if is_admin(user) else False

    user_company = get_cached_resource_by_id('companies', user.get('company')) if not company else company
    if not user_company:
        return False

    return user_company.get('is_enabled', False)
Example #5
0
def _is_company_enabled(user):
    """
    Checks if the company of the user is enabled
    """
    if not user.get('company'):
        # there's no company assigned return true for admin user else false
        return True if is_admin(user) else False

    company = get_resource_service('companies').find_one(
        req=None, _id=user.get('company'))
    if not company:
        return False

    return company.get('is_enabled',
                       False) and not _is_company_expired(company)
Example #6
0
def login():
    form = LoginForm()
    if form.validate_on_submit():

        if not is_valid_login_attempt(form.email.data):
            return flask.render_template('account_locked.html', form=form)

        user = get_auth_user_by_email(form.email.data)

        if user is not None and _is_password_valid(
                form.password.data.encode('UTF-8'), user):

            user = get_resource_service('users').find_one(req=None,
                                                          _id=user['_id'])

            if not is_admin(user) and not user.get('company'):
                flask.flash(
                    gettext('Insufficient Permissions. Access denied.'),
                    'danger')
                return flask.render_template('login.html', form=form)

            if not _is_company_enabled(user):
                flask.flash(gettext('Company account has been disabled.'),
                            'danger')
                return flask.render_template('login.html', form=form)

            if _is_account_enabled(user):
                flask.session['user'] = str(
                    user['_id'])  # str to avoid serialization issues
                flask.session['name'] = '{} {}'.format(user.get('first_name'),
                                                       user.get('last_name'))
                flask.session['user_type'] = user['user_type']
                flask.session.permanent = form.remember_me.data
                flask.flash('login', 'analytics')

                if flask.session.get('locale') and flask.session[
                        'locale'] != user.get('locale'):
                    get_resource_service('users').system_update(
                        user['_id'], {'locale': flask.session['locale']}, user)

                return flask.redirect(
                    flask.request.args.get('next')
                    or flask.url_for('wire.index'))
            else:
                flask.flash(gettext('Account is disabled.'), 'danger')
        else:
            flask.flash(gettext('Invalid username or password.'), 'danger')
    return flask.render_template('login.html', form=form)
Example #7
0
def item(_id):
    item = get_entity_or_404(_id, 'agenda')

    user = get_user()
    company = get_user_company(user)
    if not is_admin_or_internal(user):
        item.get('event', {}).pop('files', None)
        planning_items = item.get('planning_items', [])
        [item.pop('internal_note', None) for item in planning_items]
        coverages = item.get('coverages', [])
        [c.get('planning', {}).pop('internal_note', None) for c in coverages]
        item.get('event', {}).pop('internal_note', None)

    if company and not is_admin(user) and company.get('events_only', False):
        # if the company has permission events only permission then
        # remove planning items and coverages.
        if not item.get('event'):
            # for adhoc planning items abort the request
            flask.abort(403)

        item.pop('planning_items', None)
        item.pop('coverages', None)

    if is_json_request(flask.request):
        return flask.jsonify(item)

    if 'print' in flask.request.args:
        map = flask.request.args.get('map')
        template = 'agenda_item_print.html'
        update_action_list([_id], 'prints', force_insert=True)
        return flask.render_template(
            template,
            item=item,
            map=map,
            dateString=get_agenda_dates(item),
            location=get_location_string(item),
            contacts=get_public_contacts(item),
            links=get_links(item),
            is_admin=is_admin_or_internal(user)
        )

    data = get_view_data()
    data['item'] = item
    return flask.render_template('agenda_index.html', data=data, title=item.get('name', item.get('headline')))
Example #8
0
def set_product_query(query,
                      company,
                      section,
                      user=None,
                      navigation_id=None,
                      events_only=False):
    """
    Checks the user for admin privileges
    If user is administrator then there's no filtering
    If user is not administrator then products apply if user has a company
    If user is not administrator and has no company then everything will be filtered
    :param query: search query
    :param company: company
    :param section: section i.e. wire, agenda, marketplace etc
    :param user: user to check against (used for notification checking)
    :param navigation_id: navigation to filter products
    :param events_only: From agenda to display events only or not
    If not provided session user will be checked
    """
    products = None

    if is_admin(user):
        if navigation_id:
            products = get_products_by_navigation(navigation_id)
        else:
            return  # admin will see everything by default

    if company:
        products = get_products_by_company(company['_id'],
                                           navigation_id,
                                           product_type=section)
    else:
        # user does not belong to a company so blocking all stories
        abort(403, gettext('User does not belong to a company.'))

    query['bool']['should'] = []
    product_ids = [
        p['sd_product_id'] for p in products if p.get('sd_product_id')
    ]
    if product_ids:
        query['bool']['should'].append(
            {'terms': {
                'products.code': product_ids
            }})

    # add company type filters (if any)
    if company and company.get('company_type'):
        for company_type in app.config.get('COMPANY_TYPES', []):
            if company_type['id'] == company['company_type']:
                if company_type.get('wire_must'):
                    query['bool']['must'].append(company_type['wire_must'])
                if company_type.get('wire_must_not'):
                    query['bool']['must_not'].append(
                        company_type['wire_must_not'])

    planning_items_should = []
    for product in products:
        if product.get('query'):
            query['bool']['should'].append(query_string(product['query']))
            if product.get('planning_item_query') and not events_only:
                # form the query for the agenda planning items
                planning_items_should.append(
                    planning_items_query_string(
                        product.get('planning_item_query')))

    if planning_items_should:
        query['bool']['should'].append(
            nested_query('planning_items', {
                'bool': {
                    'should': planning_items_should,
                    'minimum_should_match': 1
                }
            },
                         name='products'))

    query['bool']['minimum_should_match'] = 1

    wire_time_limit_days = get_setting('wire_time_limit_days')
    if company and not is_admin(user) and not company.get(
            'archive_access', False) and wire_time_limit_days:
        query['bool']['must'].append({
            'range': {
                'versioncreated': {
                    'gte': 'now-%dd/d' % int(wire_time_limit_days),
                }
            }
        })

    if not query['bool']['should']:
        abort(403, gettext('Your company doesn\'t have any products defined.'))
Example #9
0
    def get_matching_topics(self, item_id, topics, users, companies):
        """ Returns a list of topic ids matching to the given item_id

        :param item_id: item id to be tested against all topics
        :param topics: list of topics
        :param users: user_id, user dictionary
        :param companies: company_id, company dictionary
        :return:
        """

        query = {
            'bool': {
                'must_not': [
                    {
                        'term': {
                            'type': 'composite'
                        }
                    },
                    {
                        'constant_score': {
                            'filter': {
                                'exists': {
                                    'field': 'nextversion'
                                }
                            }
                        }
                    },
                ],
                'must': [{
                    'term': {
                        '_id': item_id
                    }
                }],
                'should': []
            }
        }
        aggs = {'topics': {'filters': {'filters': {}}}}

        queried_topics = []
        # get all section filters
        section_filters = get_resource_service(
            'section_filters').get_section_filters_dict()

        for topic in topics:
            search = SearchQuery()

            user = users.get(str(topic['user']))
            if not user:
                continue

            search.user = user
            search.is_admin = is_admin(user)
            search.company = companies.get(str(user.get('company', '')))

            search.query = deepcopy(query)
            search.query['bool']['must'] = [{'term': {'_id': item_id}}]
            search.section = topic.get('topic_type')

            self.prefill_search_products(search)

            topic_filter = {'bool': {'must': []}}

            if topic.get('query'):
                topic_filter['bool']['must'].append(
                    query_string(topic['query']))

            if topic.get('created'):
                topic_filter['bool']['must'].append(
                    self.versioncreated_range(
                        dict(created_from=topic['created'].get('from'),
                             created_to=topic['created'].get('to'),
                             timezone_offset=topic.get('timezone_offset',
                                                       '0'))))

            if topic.get('filter'):
                topic_filter['bool']['must'] += self._filter_terms(
                    topic['filter'])

            # for now even if there's no active company matching for the user
            # continuing with the search
            try:
                self.validate_request(search)
                self.apply_section_filter(search, section_filters)
                self.apply_company_filter(search)
                self.apply_time_limit_filter(search)
                self.apply_products_filter(search)
            except Forbidden:
                logger.info(
                    'Notification for user:{} and topic:{} is skipped'.format(
                        user.get('_id'), topic.get('_id')))
                continue

            aggs['topics']['filters']['filters'][str(
                topic['_id'])] = topic_filter
            queried_topics.append(topic)

        source = {'query': query}
        source['aggs'] = aggs
        source['size'] = 0

        req = ParsedRequest()
        req.args = {'source': json.dumps(source)}
        topic_matches = []

        try:
            search_results = self.internal_get(req, None)

            for topic in queried_topics:
                if search_results.hits['aggregations']['topics']['buckets'][
                        str(topic['_id'])]['doc_count'] > 0:
                    topic_matches.append(topic['_id'])

        except Exception as exc:
            logger.error('Error in get_matching_topics for query: {}'.format(
                json.dumps(source)),
                         exc,
                         exc_info=True)

        return topic_matches
Example #10
0
    def featured(self, req, lookup, featured):
        """Return featured items.

        :param ParsedRequest req: The parsed in request instance from the endpoint
        :param dict lookup: The parsed in lookup dictionary from the endpoint
        :param dict featured: list featured items
        """

        user = get_user()
        company = get_user_company(user)
        if is_events_only_access(user, company):
            abort(403)

        if not featured or not featured.get('items'):
            return ListCursor([])

        query = _agenda_query()
        get_resource_service('section_filters').apply_section_filter(query, self.section)
        planning_items_query = nested_query(
            'planning_items',
            {
                'bool': {'must': [{'terms': {'planning_items.guid': featured['items']}}]}
            },
            name='featured'
        )
        if req.args.get('q'):
            query['bool']['must'].append(query_string(req.args['q']))
            planning_items_query['nested']['query']['bool']['must'].append(planning_items_query_string(req.args['q']))

        query['bool']['must'].append(planning_items_query)

        source = {'query': query}
        set_post_filter(source, req)
        source['size'] = len(featured['items'])
        source['from'] = req.args.get('from', 0, type=int)
        if not source['from']:
            source['aggs'] = aggregations

        if company and not is_admin(user) and company.get('events_only', False):
            # no adhoc planning items and remove planning items and coverages fields
            query['bool']['must'].append({'exists': {'field': 'event'}})
            _remove_fields(source, PLANNING_ITEMS_FIELDS)

        internal_req = ParsedRequest()
        internal_req.args = {'source': json.dumps(source)}
        cursor = self.internal_get(internal_req, lookup)

        docs_by_id = {}
        for doc in cursor.docs:
            for p in (doc.get('planning_items') or []):
                docs_by_id[p.get('guid')] = doc

            # make the items display on the featured day,
            # it's used in ui instead of dates.start and dates.end
            doc.update({
                '_display_from': featured['display_from'],
                '_display_to': featured['display_to'],
            })

        docs = []
        agenda_ids = set()
        for _id in featured['items']:
            if docs_by_id.get(_id) and docs_by_id.get(_id).get('_id') not in agenda_ids:
                docs.append(docs_by_id.get(_id))
                agenda_ids.add(docs_by_id.get(_id).get('_id'))

        cursor.docs = docs
        return cursor
Example #11
0
def is_events_only_access(user, company):
    if user and company and not is_admin(user):
        return company.get('events_only', False)
    return False