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
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.'))
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
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)
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)
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)
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')))
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.'))
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
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
def is_events_only_access(user, company): if user and company and not is_admin(user): return company.get('events_only', False) return False