def get(self, recid): from invenio.legacy.bibdocfile.api import BibRecDocs from invenio.legacy.search_engine import check_user_can_view_record record = get_record(recid) if not record: abort(404) auth_code, _ = check_user_can_view_record(current_user, recid) if auth_code: abort(401) ids = [recid] for k in ['rel_dataset', 'rel_software']: ids.extend([int(r) for r in record.get(k, [])]) files = [] for recid in ids: record_files = BibRecDocs(recid).list_latest_files( list_hidden=False) files.extend( map( lambda f: { 'id': f.docid, 'name': '%s%s' % (f.name, f.format), 'url': url_for('recordfileresource', recid=recid, fileid=f.docid), }, filter(lambda f: not f.is_icon(), record_files)) ) return files
def get(self, record_id): from invenio.legacy.search_engine import record_exists, \ check_user_can_view_record # Get output format output_format = self.get_output_format() # Check record's existence record_status = record_exists(record_id) if record_status == 0: raise RecordNotFoundError( message="Record {} does not exist.".format(record_id), ) elif record_status == -1: raise RecordDeletedError( message="Record {} was deleted.".format(record_id), ) # Check record's access (auth_code, auth_mesg) = check_user_can_view_record( current_user, record_id ) if auth_code == 1: raise RecordForbiddenViewError( message="Access to record {} is forbidden.".format(record_id), ) # Return record with requested output format. result = format_record(recID=record_id, of=output_format) return (result, 200)
def get(self, recid): from invenio.legacy.bibdocfile.api import BibRecDocs from invenio.legacy.search_engine import check_user_can_view_record record = get_record(recid) if not record: abort(404) auth_code, _ = check_user_can_view_record(current_user, recid) if auth_code: abort(401) ids = [recid] for k in ['rel_dataset', 'rel_software']: ids.extend([int(r) for r in record.get(k, [])]) files = [] for recid in ids: record_files = BibRecDocs(recid).list_latest_files( list_hidden=False) files.extend( map( lambda f: { 'id': f.docid, 'name': '%s%s' % (f.name, f.format), 'url': url_for( 'recordfileresource', recid=recid, fileid=f.docid), }, filter(lambda f: not f.is_icon(), record_files))) return files
def __call__(self, req, form): argd = wash_search_urlargd(form) argd['recid'] = self.recid if self.format is not None: argd['of'] = self.format req.argd = argd uid = getUid(req) if uid == -1: return page_not_authorized(req, "../", text="You are not authorized to view this record.", navmenuid='search') elif uid > 0: pref = get_user_preferences(uid) try: if 'rg' not in form: # fetch user rg preference only if not overridden via URL argd['rg'] = int(pref['websearch_group_records']) except (KeyError, ValueError): pass # Check if the record belongs to a restricted primary # collection. If yes, redirect to the authenticated URL. user_info = collect_user_info(req) (auth_code, auth_msg) = check_user_can_view_record(user_info, self.recid) if argd['rg'] > CFG_WEBSEARCH_MAX_RECORDS_IN_GROUPS and acc_authorize_action(req, 'runbibedit')[0] != 0: argd['rg'] = CFG_WEBSEARCH_MAX_RECORDS_IN_GROUPS #check if the user has rights to set a high wildcard limit #if not, reduce the limit set by user, with the default one if CFG_WEBSEARCH_WILDCARD_LIMIT > 0 and (argd['wl'] > CFG_WEBSEARCH_WILDCARD_LIMIT or argd['wl'] == 0): if acc_authorize_action(req, 'runbibedit')[0] != 0: argd['wl'] = CFG_WEBSEARCH_WILDCARD_LIMIT # only superadmins can use verbose parameter for obtaining debug information if not isUserSuperAdmin(user_info): argd['verbose'] = 0 if auth_code and user_info['email'] == 'guest': cookie = mail_cookie_create_authorize_action(VIEWRESTRCOLL, {'collection' : guess_primary_collection_of_a_record(self.recid)}) target = CFG_SITE_SECURE_URL + '/youraccount/login' + \ make_canonical_urlargd({'action': cookie, 'ln' : argd['ln'], 'referer' : CFG_SITE_SECURE_URL + req.unparsed_uri}, {}) return redirect_to_url(req, target, norobot=True) elif auth_code: return page_not_authorized(req, "../", \ text=auth_msg, \ navmenuid='search') # mod_python does not like to return [] in case when of=id: out = perform_request_search(req, **argd) if isinstance(out, intbitset): return out.fastdump() elif out == []: return str(out) else: return out
def get_latest_linkbacks_to_accessible_records(rg, linkbacks, user_info): result = [] for linkback in linkbacks: (auth_code, auth_msg) = check_user_can_view_record(user_info, linkback[2]) # pylint: disable=W0612 if not auth_code: result.append(linkback) if len(result) == rg: break return result
def validate_user_can_see_bibrec(dummy_form, field): """ Check if user has rights to view bibrec """ if field.data: from invenio.legacy.search_engine import check_user_can_view_record (auth_code, msg) = check_user_can_view_record(current_user, field.data) if auth_code > 0: raise validators.ValidationError( _('Unauthorized to view record: ')+msg)
def check_user_can_view_linkbacks(user_info, recid): """ Check if the user is authorized to view linkbacks for a given recid. Returns the same type as acc_authorize_action """ # check user cannot view the record itself (auth_code, auth_msg) = check_user_can_view_record(user_info, recid) if auth_code: return (auth_code, auth_msg) # check if user can view the linkbacks record_primary_collection = guess_primary_collection_of_a_record(recid) return acc_authorize_action(user_info, 'viewlinkbacks', authorized_if_no_roles=True, collection=record_primary_collection)
def acl_pre_authorized_hook(self, user_info, action, is_authorized): """Check access rights to the records that the document belong to. Depending on the value of :const:`~.config.RECORD_DOCUMENT_VIEWRESTR_POLICY` this hook will check if the user has rights over *ALL* the records that the document belong to or just *ANY*. :param user_info: an instance of :class:`~invenio.ext.login.legacy_user.UserInfo` (default: :class:`flask_login.current_user`) :param action: partial name of the action to be performed, for example `viewrestr` :param is_authorized: Current authorization value. :return: New authorization value or `is_authorized` if nothing has change. See :class:`~invenio.modules.access.bases.AclFactory:Acl` """ #FIXME: once this method is refactorized this import should be updated from invenio.legacy.search_engine import check_user_can_view_record if is_authorized[0] != 0: return is_authorized if cfg['RECORD_DOCUMENT_VIEWRESTR_POLICY'] == 'ANY' and \ not any([check_user_can_view_record(user_info, recid)[0] == 0 for recid in self.get('recids', [])]): return (1, 'You must be authorized to view at least on record that' 'this document belong to') elif cfg['RECORD_DOCUMENT_VIEWRESTR_POLICY'] != 'ANY' and \ not all([check_user_can_view_record(user_info, recid)[0] == 0 for recid in self.get('recids', [])]): return (1, 'You must be authorized to view all the records that' 'this document belong to') return is_authorized
def acl_pre_authorized_hook(self, user_info, action, is_authorized): """Check access rights to the records that the document belong to. Depending on the value of :const:`~.config.RECORD_DOCUMENT_VIEWRESTR_POLICY` this hook will check if the user has rights over *ALL* the records that the document belong to or just *ANY*. :param user_info: an instance of :class:`~invenio.ext.login.legacy_user.UserInfo` (default: :class:`flask.ext.login.current_user`) :param action: partial name of the action to be performed, for example `viewrestr` :param is_authorized: Current authorization value. :return: New authorization value or `is_authorized` if nothing has change. See :class:`~invenio.modules.access.bases.AclFactory:Acl` """ #FIXME: once this method is refactorized this import should be updated from invenio.legacy.search_engine import check_user_can_view_record if is_authorized[0] != 0: return is_authorized if cfg['RECORD_DOCUMENT_VIEWRESTR_POLICY'] == 'ANY' and \ not any([check_user_can_view_record(user_info, recid)[0] == 0 for recid in self.get('recids', [])]): return (1, 'You must be authorized to view at least on record that' 'this document belong to') elif cfg['RECORD_DOCUMENT_VIEWRESTR_POLICY'] != 'ANY' and \ not all([check_user_can_view_record(user_info, recid)[0] == 0 for recid in self.get('recids', [])]): return (1, 'You must be authorized to view all the records that' 'this document belong to') return is_authorized
def decorated(recid, *args, **kwargs): from invenio.modules.access.mailcookie import \ mail_cookie_create_authorize_action from invenio.modules.access.local_config import VIEWRESTRCOLL from invenio.legacy.search_engine import guess_primary_collection_of_a_record, \ check_user_can_view_record from invenio.legacy.websearch.adminlib import get_detailed_page_tabs,\ get_detailed_page_tabs_counts from invenio.b2share.modules.main.utils import check_fresh_record # ensure recid to be integer recid = int(recid) from invenio.legacy.search_engine import record_exists, get_merged_recid if record_exists(recid) == 0: # record doesn't exist, abort so it doesn't get incorrectly cached abort(apache.HTTP_NOT_FOUND) # The record is gone! if check_fresh_record(current_user, recid): return render_template('record_waitforit.html', recid=recid) g.collection = collection = Collection.query.filter( Collection.name == guess_primary_collection_of_a_record(recid)).\ one() (auth_code, auth_msg) = check_user_can_view_record(current_user, recid) # only superadmins can use verbose parameter for obtaining debug information if not current_user.is_super_admin and 'verbose' in kwargs: kwargs['verbose'] = 0 if auth_code and current_user.is_guest: cookie = mail_cookie_create_authorize_action(VIEWRESTRCOLL, { 'collection': g.collection.name}) url_args = {'action': cookie, 'ln': g.ln, 'referer': request.url} flash(_("Authorization failure"), 'error') return redirect(url_for('webaccount.login', **url_args)) elif auth_code: flash(auth_msg, 'error') abort(apache.HTTP_UNAUTHORIZED) from invenio.modules.records.api import get_record from invenio.legacy.search_engine import record_exists, get_merged_recid # check if the current record has been deleted # and has been merged, case in which the deleted record # will be redirect to the new one record_status = record_exists(recid) merged_recid = get_merged_recid(recid) if record_status == -1 and merged_recid: return redirect(url_for('record.metadata', recid=merged_recid)) elif record_status == -1: abort(apache.HTTP_GONE) # The record is gone! g.bibrec = Bibrec.query.get(recid) record = get_record(recid) if record is None: return render_template('404.html') title = record.get(cfg.get('RECORDS_BREADCRUMB_TITLE_KEY'), '') # b = [(_('Home'), '')] + collection.breadcrumbs()[1:] # b += [(title, 'record.metadata', dict(recid=recid))] # current_app.config['breadcrumbs_map'][request.endpoint] = b g.record_tab_keys = [] tabs = [] counts = get_detailed_page_tabs_counts(recid) for k, v in iteritems(get_detailed_page_tabs(collection.id, recid, g.ln)): t = {} b = 'record' if k == '': k = 'metadata' if k == 'comments' or k == 'reviews': b = 'comments' if k == 'linkbacks': b = 'weblinkback' k = 'index' t['key'] = b + '.' + k t['count'] = counts.get(k.capitalize(), -1) t.update(v) tabs.append(t) if v['visible']: g.record_tab_keys.append(b+'.'+k) if cfg.get('CFG_WEBLINKBACK_TRACKBACK_ENABLED'): @register_template_context_processor def trackback_context(): from invenio.legacy.weblinkback.templates import get_trackback_auto_discovery_tag return dict(headerLinkbackTrackbackLink=get_trackback_auto_discovery_tag(recid)) def _format_record(recid, of='hd', user_info=current_user, *args, **kwargs): from invenio.modules.formatter import format_record return format_record(recid, of, user_info=user_info, *args, **kwargs) @register_template_context_processor def record_context(): from invenio.modules.comments.api import get_mini_reviews from invenio.legacy.bibdocfile.api import BibRecDocs all_files = [f for f in BibRecDocs(recid, human_readable=True).list_latest_files(list_hidden=False) \ if not f.is_icon()] files = [f for f in all_files if f.is_restricted(current_user)[0] == 0] has_private_files = len(files) < len(all_files) return dict(recid=recid, record=record, tabs=tabs, title=title, get_mini_reviews=get_mini_reviews, collection=collection, format_record=_format_record, has_private_files=has_private_files, files=files ) pre_template_render.send( "%s.%s" % (blueprint.name, f.__name__), recid=recid, ) return f(recid, *args, **kwargs)
def decorated(recid, *args, **kwargs): from invenio.legacy.search_engine import \ guess_primary_collection_of_a_record, \ check_user_can_view_record # ensure recid to be integer recid = int(recid) g.bibrec = Bibrec.query.get(recid) record = get_record(recid) if record is None: return render_template('404.html') g.collection = collection = Collection.query.filter( Collection.name == guess_primary_collection_of_a_record(recid)).\ one() (auth_code, auth_msg) = check_user_can_view_record(current_user, recid) # only superadmins can use verbose parameter for obtaining debug # information if not current_user.is_super_admin and 'verbose' in kwargs: kwargs['verbose'] = 0 if auth_code: flash(auth_msg, 'error') abort(apache.HTTP_UNAUTHORIZED) from invenio.legacy.search_engine import record_exists, \ get_merged_recid # check if the current record has been deleted # and has been merged, case in which the deleted record # will be redirect to the new one record_status = record_exists(recid) merged_recid = get_merged_recid(recid) if record_status == -1 and merged_recid: return redirect(url_for('record.metadata', recid=merged_recid)) elif record_status == -1: abort(apache.HTTP_GONE) # The record is gone! title = record.get(cfg.get('RECORDS_BREADCRUMB_TITLE_KEY'), '') tabs = [] def _format_record(recid, of='hd', user_info=current_user, *args, **kwargs): from invenio.modules.formatter import format_record return format_record(recid, of, user_info=user_info, *args, **kwargs) @register_template_context_processor def record_context(): from invenio.modules.comments.api import get_mini_reviews return dict(recid=recid, record=record, tabs=tabs, title=title, get_mini_reviews=get_mini_reviews, collection=collection, format_record=_format_record ) pre_template_render.send( "%s.%s" % (blueprint.name, f.__name__), recid=recid, ) return f(recid, *args, **kwargs)
def decorated(recid, *args, **kwargs): from invenio.modules.access.mailcookie import mail_cookie_create_authorize_action from invenio.modules.access.local_config import VIEWRESTRCOLL from invenio.legacy.search_engine import guess_primary_collection_of_a_record, check_user_can_view_record # ensure recid to be integer recid = int(recid) g.collection = collection = Collection.query.filter( Collection.name == guess_primary_collection_of_a_record(recid) ).one() (auth_code, auth_msg) = check_user_can_view_record(current_user, recid) # only superadmins can use verbose parameter for obtaining debug # information if not current_user.is_super_admin and "verbose" in kwargs: kwargs["verbose"] = 0 if auth_code and current_user.is_guest: cookie = mail_cookie_create_authorize_action(VIEWRESTRCOLL, {"collection": g.collection.name}) url_args = {"action": cookie, "ln": g.ln, "referer": request.url} flash(_("Authorization failure"), "error") return redirect(url_for("webaccount.login", **url_args)) elif auth_code: flash(auth_msg, "error") abort(apache.HTTP_UNAUTHORIZED) from invenio.legacy.search_engine import record_exists, get_merged_recid # check if the current record has been deleted # and has been merged, case in which the deleted record # will be redirect to the new one record_status = record_exists(recid) merged_recid = get_merged_recid(recid) if record_status == -1 and merged_recid: return redirect(url_for("record.metadata", recid=merged_recid)) elif record_status == -1: abort(apache.HTTP_GONE) # The record is gone! g.bibrec = Bibrec.query.get(recid) record = get_record(recid) if record is None: return render_template("404.html") title = record.get(cfg.get("RECORDS_BREADCRUMB_TITLE_KEY"), "") tabs = [] if cfg.get("CFG_WEBLINKBACK_TRACKBACK_ENABLED"): @register_template_context_processor def trackback_context(): from invenio.legacy.weblinkback.templates import get_trackback_auto_discovery_tag return {"headerLinkbackTrackbackLink": get_trackback_auto_discovery_tag(recid)} def _format_record(recid, of="hd", user_info=current_user, *args, **kwargs): from invenio.modules.formatter import format_record return format_record(recid, of, user_info=user_info, *args, **kwargs) @register_template_context_processor def record_context(): from invenio.modules.comments.api import get_mini_reviews return dict( recid=recid, record=record, tabs=tabs, title=title, get_mini_reviews=get_mini_reviews, collection=collection, format_record=_format_record, ) pre_template_render.send("%s.%s" % (blueprint.name, f.__name__), recid=recid) return f(recid, *args, **kwargs)
def getfile(req, form): args = wash_urlargd(form, bibdocfile_templates.files_default_urlargd) ln = args['ln'] _ = gettext_set_language(ln) uid = getUid(req) user_info = collect_user_info(req) verbose = args['verbose'] if verbose >= 1 and not isUserSuperAdmin(user_info): # Only SuperUser can see all the details! verbose = 0 if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE > 1: return page_not_authorized(req, "/%s/%s" % (CFG_SITE_RECORD, self.recid), navmenuid='submit') if record_exists(self.recid) < 1: msg = "<p>%s</p>" % _("Requested record does not seem to exist.") return warning_page(msg, req, ln) if record_empty(get_record(self.recid).legacy_create_recstruct()): msg = "<p>%s</p>" % _("Requested record does not seem to have been integrated.") return warning_page(msg, req, ln) (auth_code, auth_message) = check_user_can_view_record(user_info, self.recid) if auth_code and user_info['email'] == 'guest': cookie = mail_cookie_create_authorize_action(VIEWRESTRCOLL, {'collection' : guess_primary_collection_of_a_record(self.recid)}) target = CFG_SITE_SECURE_URL + '/youraccount/login' + \ make_canonical_urlargd({'action': cookie, 'ln' : ln, 'referer' : \ CFG_SITE_SECURE_URL + user_info['uri']}, {}) return redirect_to_url(req, target, norobot=True) elif auth_code: return page_not_authorized(req, "../", \ text = auth_message) readonly = CFG_ACCESS_CONTROL_LEVEL_SITE == 1 # From now on: either the user provided a specific file # name (and a possible version), or we return a list of # all the available files. In no case are the docids # visible. try: bibarchive = BibRecDocs(self.recid) except InvenioBibDocFileError: register_exception(req=req, alert_admin=True) msg = "<p>%s</p><p>%s</p>" % ( _("The system has encountered an error in retrieving the list of files for this document."), _("The error has been logged and will be taken in consideration as soon as possible.")) return warning_page(msg, req, ln) if bibarchive.deleted_p(): req.status = apache.HTTP_GONE return warning_page(_("Requested record does not seem to exist."), req, ln) docname = '' docformat = '' version = '' warn = '' if filename: # We know the complete file name, guess which docid it # refers to ## TODO: Change the extension system according to ext.py from setlink ## and have a uniform extension mechanism... docname = file_strip_ext(filename) docformat = filename[len(docname):] if docformat and docformat[0] != '.': docformat = '.' + docformat if args['subformat']: docformat += ';%s' % args['subformat'] else: docname = args['docname'] if not docformat: docformat = args['format'] if args['subformat']: docformat += ';%s' % args['subformat'] if not version: version = args['version'] ## Download as attachment is_download = False if args['download']: is_download = True # version could be either empty, or all or an integer try: int(version) except ValueError: if version != 'all': version = '' display_hidden = isUserSuperAdmin(user_info) if version != 'all': # search this filename in the complete list of files for doc in bibarchive.list_bibdocs(): if docname == bibarchive.get_docname(doc.id): try: try: docfile = doc.get_file(docformat, version) except InvenioBibDocFileError as msg: req.status = apache.HTTP_NOT_FOUND if not CFG_INSPIRE_SITE and req.headers_in.get('referer'): ## There must be a broken link somewhere. ## Maybe it's good to alert the admin register_exception(req=req, alert_admin=True) warn += write_warning(_("The format %(x_form)s does not exist for the given version: %(x_vers)s", x_form=cgi.escape(docformat), x_vers=cgi.escape(str(msg)))) break (auth_code, auth_message) = docfile.is_restricted(user_info) if auth_code != 0 and not is_user_owner_of_record(user_info, self.recid): if CFG_BIBDOCFILE_ICON_SUBFORMAT_RE.match(get_subformat_from_format(docformat)): return stream_restricted_icon(req) if user_info['email'] == 'guest': cookie = mail_cookie_create_authorize_action('viewrestrdoc', {'status' : docfile.get_status()}) target = CFG_SITE_SECURE_URL + '/youraccount/login' + \ make_canonical_urlargd({'action': cookie, 'ln' : ln, 'referer' : \ CFG_SITE_SECURE_URL + user_info['uri']}, {}) redirect_to_url(req, target) else: req.status = apache.HTTP_UNAUTHORIZED warn += write_warning(_("This file is restricted: ") + str(auth_message)) break if not docfile.hidden_p(): if not readonly: ip = str(req.remote_ip) doc.register_download(ip, docfile.get_version(), docformat, uid, self.recid) try: return docfile.stream(req, download=is_download) except InvenioBibDocFileError as msg: register_exception(req=req, alert_admin=True) req.status = apache.HTTP_INTERNAL_SERVER_ERROR warn += write_warning(_("An error has happened in trying to stream the request file.")) else: req.status = apache.HTTP_UNAUTHORIZED warn += write_warning(_("The requested file is hidden and can not be accessed.")) except InvenioBibDocFileError as msg: register_exception(req=req, alert_admin=True) if docname and docformat and not warn: req.status = apache.HTTP_NOT_FOUND warn += write_warning(_("Requested file does not seem to exist.")) # filelist = bibarchive.display("", version, ln=ln, verbose=verbose, display_hidden=display_hidden) filelist = bibdocfile_templates.tmpl_display_bibrecdocs(bibarchive, "", version, ln=ln, verbose=verbose, display_hidden=display_hidden) t = warn + bibdocfile_templates.tmpl_filelist( ln=ln, filelist=filelist) cc = guess_primary_collection_of_a_record(self.recid) cc_id = Collection.query.filter_by(name=cc).value('id') unordered_tabs = None # get_detailed_page_tabs(cc_id, self.recid, ln) ordered_tabs_id = [(tab_id, values['order']) for (tab_id, values) in iteritems(unordered_tabs)] ordered_tabs_id.sort(lambda x, y: cmp(x[1], y[1])) link_ln = '' if ln != CFG_SITE_LANG: link_ln = '?ln=%s' % ln tabs = [(unordered_tabs[tab_id]['label'], '%s/%s/%s/%s%s' % (CFG_SITE_URL, CFG_SITE_RECORD, self.recid, tab_id, link_ln), tab_id == 'files', unordered_tabs[tab_id]['enabled']) for (tab_id, dummy_order) in ordered_tabs_id if unordered_tabs[tab_id]['visible'] is True] tabs_counts = {} # get_detailed_page_tabs_counts(self.recid) top = webstyle_templates.detailed_record_container_top(self.recid, tabs, args['ln'], citationnum=tabs_counts['Citations'], referencenum=tabs_counts['References'], discussionnum=tabs_counts['Discussions']) bottom = webstyle_templates.detailed_record_container_bottom(self.recid, tabs, args['ln']) title, description, keywords = websearch_templates.tmpl_record_page_header_content(req, self.recid, args['ln']) return pageheaderonly(title=title, navtrail=create_navtrail_links(cc=cc, aas=0, ln=ln) + \ ''' > <a class="navtrail" href="%s/%s/%s">%s</a> > %s''' % \ (CFG_SITE_URL, CFG_SITE_RECORD, self.recid, title, _("Access to Fulltext")), description=description, keywords=keywords, uid=uid, language=ln, req=req, navmenuid='search', navtrail_append_title_p=0) + \ websearch_templates.tmpl_search_pagestart(ln) + \ top + t + bottom + \ websearch_templates.tmpl_search_pageend(ln) + \ pagefooteronly(language=ln, req=req)
def email_notify(alert, records, argstr): """Send the notification e-mail for a specific alert.""" if CFG_WEBALERT_DEBUG_LEVEL > 2: print("+" * 80 + '\n') uid = alert[0] user_info = collect_user_info(uid) frequency = alert[3] alert_name = alert[5] alert_description = alert[7] alert_recipient_email = alert[8] # set only by admin. Bypasses access-right checks. filtered_out_recids = [] # only set in debug mode if not alert_recipient_email: # Filter out records that user (who setup the alert) should # not see. This does not apply to external records (hosted # collections). filtered_records = ([], records[1]) for recid in records[0]: (auth_code, auth_msg) = check_user_can_view_record(user_info, recid) if auth_code == 0: filtered_records[0].append(recid) elif CFG_WEBALERT_DEBUG_LEVEL > 2: # only keep track of this in DEBUG mode filtered_out_recids.append(recid) else: # If admin has decided to send to some mailing-list, we cannot # verify that recipients have access to the records. So keep # all of them. filtered_records = records if len(filtered_records[0]) == 0: total_n_external_records = 0 for external_collection_results in filtered_records[1][0]: total_n_external_records += len(external_collection_results[1][0]) if total_n_external_records == 0: return msg = "" if CFG_WEBALERT_DEBUG_LEVEL > 2 and filtered_out_recids: print("-> these records have been filtered out, as user id %s did not have access:\n%s" % \ (uid, repr(filtered_out_recids))) if CFG_WEBALERT_DEBUG_LEVEL > 0: msg = "*** THIS MESSAGE WAS SENT IN DEBUG MODE ***\n\n" url = CFG_SITE_URL + "/search?" + argstr # Extract the pattern, the collection list, the current collection # and the sc (split collection) from the formatted query query = parse_qs(argstr) pattern = query.get('p', [''])[0] collection_list = query.get('c', []) current_collection = query.get('cc', ['']) sc = query.get('sc', ['1']) collections = calculate_desired_collection_list(collection_list, current_collection, int(sc[0])) msg += webalert_templates.tmpl_alert_email_body(alert_name, alert_description, url, filtered_records, pattern, collections, frequency, alert_use_basket_p(alert)) email = alert_recipient_email or get_email(uid) if email == 'guest': print("********************************************************************************") print("The following alert was not send, because cannot detect user email address:") print(" " + repr(argstr)) print("********************************************************************************") return if CFG_WEBALERT_DEBUG_LEVEL > 0: print("********************************************************************************") print(msg) print("********************************************************************************") if CFG_WEBALERT_DEBUG_LEVEL < 2: send_email(fromaddr=webalert_templates.tmpl_alert_email_from(), toaddr=email, subject=webalert_templates.tmpl_alert_email_title(alert_name), content=msg, header='', footer='', attempt_times=CFG_WEBALERT_SEND_EMAIL_NUMBER_OF_TRIES, attempt_sleeptime=CFG_WEBALERT_SEND_EMAIL_SLEEPTIME_BETWEEN_TRIES) if CFG_WEBALERT_DEBUG_LEVEL == 4: send_email(fromaddr=webalert_templates.tmpl_alert_email_from(), toaddr=CFG_SITE_ADMIN_EMAIL, subject=webalert_templates.tmpl_alert_email_title(alert_name), content=msg, header='', footer='', attempt_times=CFG_WEBALERT_SEND_EMAIL_NUMBER_OF_TRIES, attempt_sleeptime=CFG_WEBALERT_SEND_EMAIL_SLEEPTIME_BETWEEN_TRIES)
def get(self): # Temporarily disable search until fully tested. abort(405) from invenio.legacy.search_engine import perform_request_search, \ record_exists, check_user_can_view_record given_mimetype = request.headers.get('Accept', 'application/json') output_format = self.mimetypes.get(given_mimetype) if output_format is None: raise RecordUnsuppotedMediaTypeError( message="Output format {} is not supported.".format( given_mimetype )) # get URL parameters query = request.args.get('query', '') sort_field = request.args.get('sort_field', 'title') sort_order = request.args.get('sort_order', 'a') page = int(request.args.get('page', 1)) per_page = int(request.args.get('per_page', 5)) if page < 0: raise RecordError( message="Invalid page {}".format(page), status=400 ) if per_page < 0: raise RecordError( message="Invalid per_page {}".format(per_page), status=400 ) rec_ids = perform_request_search(p=query, sf=sort_field, so=sort_order, of='id') rec_ids_to_keep = [] for recid in rec_ids: if record_exists(recid) > 0: (auth_code, auth_mesg) = check_user_can_view_record( current_user, recid) if auth_code == 0: rec_ids_to_keep.append(recid) records_in_requested_format = [] if rec_ids_to_keep: for recid in rec_ids_to_keep: result = format_record(recID=recid, of=output_format) records_in_requested_format.append(result) records_to_return = [] headers = {} if records_in_requested_format: p = pagination.RestfulPagination( page=page, per_page=per_page, total_count=len(records_in_requested_format) ) if (page > p.pages): raise RecordError( message="Invalid page {}".format(page), status=400 ) records_to_return = p.slice(records_in_requested_format) kwargs = {} kwargs['endpoint'] = request.endpoint kwargs['args'] = request.args link_header = p.link_header(**kwargs) headers[link_header[0]] = link_header[1] return (json.dumps(records_to_return), 200, headers)
def add_records_to_basket(records, basket_id): """Add the given records to the given baskets""" index = 0 owner_uid = get_basket_owner_id(basket_id) # We check that the owner of the recipient basket would be allowed # to view the records. This does not apply to external records # (hosted collections). user_info = collect_user_info(owner_uid) filtered_records = ([], records[1]) filtered_out_recids = [] # only set in debug mode for recid in records[0]: (auth_code, auth_msg) = check_user_can_view_record(user_info, recid) if auth_code == 0: filtered_records[0].append(recid) elif CFG_WEBALERT_DEBUG_LEVEL > 2: # only keep track of this in DEBUG mode filtered_out_recids.append(recid) nrec = len(filtered_records[0]) index += nrec if index > CFG_WEBALERT_MAX_NUM_OF_RECORDS_IN_ALERT_EMAIL: index = CFG_WEBALERT_MAX_NUM_OF_RECORDS_IN_ALERT_EMAIL if nrec > 0: nrec_to_add = nrec < index and nrec or index if CFG_WEBALERT_DEBUG_LEVEL > 0: print("-> adding %i records into basket %s: %s" % (nrec_to_add, basket_id, filtered_records[0][:nrec_to_add])) if nrec > nrec_to_add: print("-> not added %i records into basket %s: %s due to maximum limit restrictions." % (nrec - nrec_to_add, basket_id, filtered_records[0][nrec_to_add:])) try: if CFG_WEBALERT_DEBUG_LEVEL == 0: add_to_basket(owner_uid, filtered_records[0][:nrec_to_add], 0, basket_id) else: print(' NOT ADDED, DEBUG LEVEL > 0') except Exception: register_exception() if CFG_WEBALERT_DEBUG_LEVEL > 2 and filtered_out_recids: print("-> these records have been filtered out, as user id %s did not have access:\n%s" % \ (owner_uid, repr(filtered_out_recids))) if index < CFG_WEBALERT_MAX_NUM_OF_RECORDS_IN_ALERT_EMAIL: for external_collection_results in filtered_records[1][0]: nrec = len(external_collection_results[1][0]) # index_tmp: the number of maximum allowed records to be added to # the basket for the next collection. index_tmp = CFG_WEBALERT_MAX_NUM_OF_RECORDS_IN_ALERT_EMAIL - index index += nrec if index > CFG_WEBALERT_MAX_NUM_OF_RECORDS_IN_ALERT_EMAIL: index = CFG_WEBALERT_MAX_NUM_OF_RECORDS_IN_ALERT_EMAIL if nrec > 0 and index_tmp > 0: nrec_to_add = nrec < index_tmp and nrec or index_tmp if CFG_WEBALERT_DEBUG_LEVEL > 0: print("-> adding %s external records (collection \"%s\") into basket %s: %s" % (nrec_to_add, external_collection_results[0], basket_id, external_collection_results[1][0][:nrec_to_add])) if nrec > nrec_to_add: print("-> not added %s external records (collection \"%s\") into basket %s: %s due to maximum limit restriction" % (nrec - nrec_to_add, external_collection_results[0], basket_id, external_collection_results[1][0][nrec_to_add:])) try: if CFG_WEBALERT_DEBUG_LEVEL == 0: collection_id = get_collection_id(external_collection_results[0]) added_items = add_to_basket(owner_uid, external_collection_results[1][0][:nrec_to_add], collection_id, basket_id) format_external_records(added_items, of="xm") else: print(' NOT ADDED, DEBUG LEVEL > 0') except Exception: register_exception() elif nrec > 0 and CFG_WEBALERT_DEBUG_LEVEL > 0: print("-> not added %s external records (collection \"%s\") into basket %s: %s due to maximum limit restriction" % (nrec, external_collection_results[0], basket_id, external_collection_results[1][0])) elif CFG_WEBALERT_DEBUG_LEVEL > 0: for external_collection_results in filtered_records[1][0]: nrec = len(external_collection_results[1][0]) if nrec > 0: print("-> not added %i external records (collection \"%s\") into basket %s: %s due to maximum limit restrictions" % (nrec, external_collection_results[0], basket_id, external_collection_results[1][0]))
def decorated(recid, *args, **kwargs): from invenio.modules.access.mailcookie import \ mail_cookie_create_authorize_action from invenio.modules.access.local_config import VIEWRESTRCOLL from invenio.legacy.search_engine import \ guess_primary_collection_of_a_record, \ check_user_can_view_record from invenio.b2share.modules.main.utils import check_fresh_record # ensure recid to be integer recid = int(recid) from invenio.legacy.search_engine import record_exists, get_merged_recid if record_exists(recid) == 0: # record doesn't exist, abort so it doesn't get incorrectly cached abort(apache.HTTP_NOT_FOUND) # The record is gone! if check_fresh_record(current_user, recid): return render_template('record_waitforit.html', recid=recid) g.collection = collection = Collection.query.filter( Collection.name == guess_primary_collection_of_a_record(recid)).\ one() (auth_code, auth_msg) = check_user_can_view_record(current_user, recid) # only superadmins can use verbose parameter for obtaining debug # information if not current_user.is_super_admin and 'verbose' in kwargs: kwargs['verbose'] = 0 if auth_code and current_user.is_guest: cookie = mail_cookie_create_authorize_action( VIEWRESTRCOLL, {'collection': g.collection.name}) url_args = {'action': cookie, 'ln': g.ln, 'referer': request.url} flash(_("Authorization failure"), 'error') return redirect(url_for('webaccount.login', **url_args)) elif auth_code: flash(auth_msg, 'error') abort(apache.HTTP_UNAUTHORIZED) from invenio.legacy.search_engine import record_exists, \ get_merged_recid # check if the current record has been deleted # and has been merged, case in which the deleted record # will be redirect to the new one record_status = record_exists(recid) merged_recid = get_merged_recid(recid) if record_status == -1 and merged_recid: return redirect(url_for('record.metadata', recid=merged_recid)) elif record_status == -1: abort(apache.HTTP_GONE) # The record is gone! g.bibrec = Bibrec.query.get(recid) record = get_record(recid) if record is None: return render_template('404.html') title = record.get(cfg.get('RECORDS_BREADCRUMB_TITLE_KEY'), '') tabs = [] if cfg.get('CFG_WEBLINKBACK_TRACKBACK_ENABLED'): @register_template_context_processor def trackback_context(): from invenio.legacy.weblinkback.templates import \ get_trackback_auto_discovery_tag return { 'headerLinkbackTrackbackLink': get_trackback_auto_discovery_tag(recid) } def _format_record(recid, of='hd', user_info=current_user, *args, **kwargs): from invenio.modules.formatter import format_record return format_record(recid, of, user_info=user_info, *args, **kwargs) @register_template_context_processor def record_context(): from invenio.modules.comments.api import get_mini_reviews from invenio.legacy.bibdocfile.api import BibRecDocs all_files = [f for f in BibRecDocs(recid, human_readable=True).list_latest_files(list_hidden=False) \ if not f.is_icon()] files = [ f for f in all_files if f.is_restricted(current_user)[0] == 0 ] has_private_files = len(files) < len(all_files) return dict(recid=recid, record=record, tabs=tabs, title=title, get_mini_reviews=get_mini_reviews, collection=collection, format_record=_format_record, has_private_files=has_private_files, files=files) pre_template_render.send( "%s.%s" % (blueprint.name, f.__name__), recid=recid, ) return f(recid, *args, **kwargs)
def __call__(self, req, form): argd = wash_search_urlargd(form) argd['recid'] = self.recid argd['tab'] = self.tab # do we really enter here ? if self.format is not None: argd['of'] = self.format req.argd = argd uid = getUid(req) if uid == -1: return page_not_authorized(req, "../", text="You are not authorized to view this record.", navmenuid='search') elif uid > 0: pref = get_user_preferences(uid) try: if 'rg' not in form: # fetch user rg preference only if not overridden via URL argd['rg'] = int(pref['websearch_group_records']) except (KeyError, ValueError): pass user_info = collect_user_info(req) (auth_code, auth_msg) = check_user_can_view_record(user_info, self.recid) if argd['rg'] > CFG_WEBSEARCH_MAX_RECORDS_IN_GROUPS and acc_authorize_action(req, 'runbibedit')[0] != 0: argd['rg'] = CFG_WEBSEARCH_MAX_RECORDS_IN_GROUPS #check if the user has rights to set a high wildcard limit #if not, reduce the limit set by user, with the default one if CFG_WEBSEARCH_WILDCARD_LIMIT > 0 and (argd['wl'] > CFG_WEBSEARCH_WILDCARD_LIMIT or argd['wl'] == 0): if acc_authorize_action(req, 'runbibedit')[0] != 0: argd['wl'] = CFG_WEBSEARCH_WILDCARD_LIMIT # only superadmins can use verbose parameter for obtaining debug information if not isUserSuperAdmin(user_info): argd['verbose'] = 0 if auth_code and user_info['email'] == 'guest': cookie = mail_cookie_create_authorize_action(VIEWRESTRCOLL, {'collection' : guess_primary_collection_of_a_record(self.recid)}) target = CFG_SITE_SECURE_URL + '/youraccount/login' + \ make_canonical_urlargd({'action': cookie, 'ln' : argd['ln'], 'referer' : CFG_SITE_SECURE_URL + req.unparsed_uri}, {}) return redirect_to_url(req, target, norobot=True) elif auth_code: return page_not_authorized(req, "../", \ text=auth_msg, \ navmenuid='search') from invenio.legacy.search_engine import record_exists, get_merged_recid # check if the current record has been deleted # and has been merged, case in which the deleted record # will be redirect to the new one record_status = record_exists(argd['recid']) merged_recid = get_merged_recid(argd['recid']) if record_status == -1 and merged_recid: url = CFG_SITE_URL + '/' + CFG_SITE_RECORD + '/%s?ln=%s' url %= (str(merged_recid), argd['ln']) redirect_to_url(req, url) elif record_status == -1: req.status = apache.HTTP_GONE ## The record is gone! # mod_python does not like to return [] in case when of=id: out = perform_request_search(req, **argd) if isinstance(out, intbitset): return out.fastdump() elif out == []: return str(out) else: return out
def decorated(recid, *args, **kwargs): from invenio.modules.access.mailcookie import \ mail_cookie_create_authorize_action from invenio.modules.access.local_config import VIEWRESTRCOLL from invenio.legacy.search_engine import \ guess_primary_collection_of_a_record, \ check_user_can_view_record # ensure recid to be integer recid = int(recid) g.collection = collection = Collection.query.filter( Collection.name == guess_primary_collection_of_a_record(recid)).\ one() g.bibrec = Bibrec.query.get(recid) record = get_record(recid) if record is None: return render_template('404.html') (auth_code, auth_msg) = check_user_can_view_record(current_user, recid) # only superadmins can use verbose parameter for obtaining debug # information if not current_user.is_super_admin and 'verbose' in kwargs: kwargs['verbose'] = 0 if auth_code: flash(auth_msg, 'error') abort(apache.HTTP_UNAUTHORIZED) from invenio.legacy.search_engine import record_exists, \ get_merged_recid # check if the current record has been deleted # and has been merged, case in which the deleted record # will be redirect to the new one record_status = record_exists(recid) merged_recid = get_merged_recid(recid) if record_status == -1 and merged_recid: return redirect(url_for('record.metadata', recid=merged_recid)) elif record_status == -1: abort(apache.HTTP_GONE) # The record is gone! title = record.get(cfg.get('RECORDS_BREADCRUMB_TITLE_KEY'), '') tabs = [] if cfg.get('CFG_WEBLINKBACK_TRACKBACK_ENABLED'): @register_template_context_processor def trackback_context(): from invenio.legacy.weblinkback.templates import \ get_trackback_auto_discovery_tag return { 'headerLinkbackTrackbackLink': get_trackback_auto_discovery_tag(recid) } def _format_record(recid, of='hd', user_info=current_user, *args, **kwargs): from invenio.modules.formatter import format_record return format_record(recid, of, user_info=user_info, *args, **kwargs) @register_template_context_processor def record_context(): from invenio.modules.comments.api import get_mini_reviews return dict(recid=recid, record=record, tabs=tabs, title=title, get_mini_reviews=get_mini_reviews, collection=collection, format_record=_format_record) pre_template_render.send( "%s.%s" % (blueprint.name, f.__name__), recid=recid, ) return f(recid, *args, **kwargs)
def getfile(req, form): args = wash_urlargd(form, bibdocfile_templates.files_default_urlargd) ln = args['ln'] _ = gettext_set_language(ln) uid = getUid(req) user_info = collect_user_info(req) verbose = args['verbose'] if verbose >= 1 and not isUserSuperAdmin(user_info): # Only SuperUser can see all the details! verbose = 0 if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE > 1: return page_not_authorized(req, "/%s/%s" % (CFG_SITE_RECORD, self.recid), navmenuid='submit') if record_exists(self.recid) < 1: msg = "<p>%s</p>" % _( "Requested record does not seem to exist.") return warning_page(msg, req, ln) if record_empty(self.recid): msg = "<p>%s</p>" % _( "Requested record does not seem to have been integrated.") return warning_page(msg, req, ln) (auth_code, auth_message) = check_user_can_view_record(user_info, self.recid) if auth_code and user_info['email'] == 'guest': if webjournal_utils.is_recid_in_released_issue(self.recid): # We can serve the file pass else: cookie = mail_cookie_create_authorize_action( VIEWRESTRCOLL, { 'collection': guess_primary_collection_of_a_record(self.recid) }) target = CFG_SITE_SECURE_URL + '/youraccount/login' + \ make_canonical_urlargd({'action': cookie, 'ln' : ln, 'referer' : \ CFG_SITE_SECURE_URL + user_info['uri']}, {}) return redirect_to_url(req, target, norobot=True) elif auth_code: if webjournal_utils.is_recid_in_released_issue(self.recid): # We can serve the file pass else: return page_not_authorized(req, "../", \ text = auth_message) readonly = CFG_ACCESS_CONTROL_LEVEL_SITE == 1 # From now on: either the user provided a specific file # name (and a possible version), or we return a list of # all the available files. In no case are the docids # visible. try: bibarchive = BibRecDocs(self.recid) except InvenioBibDocFileError: register_exception(req=req, alert_admin=True) msg = "<p>%s</p><p>%s</p>" % ( _("The system has encountered an error in retrieving the list of files for this document." ), _("The error has been logged and will be taken in consideration as soon as possible." )) return warning_page(msg, req, ln) if bibarchive.deleted_p(): req.status = apache.HTTP_GONE return warning_page( _("Requested record does not seem to exist."), req, ln) docname = '' docformat = '' version = '' warn = '' if filename: # We know the complete file name, guess which docid it # refers to ## TODO: Change the extension system according to ext.py from setlink ## and have a uniform extension mechanism... docname = file_strip_ext(filename) docformat = filename[len(docname):] if docformat and docformat[0] != '.': docformat = '.' + docformat if args['subformat']: docformat += ';%s' % args['subformat'] else: docname = args['docname'] if not docformat: docformat = args['format'] if args['subformat']: docformat += ';%s' % args['subformat'] if not version: version = args['version'] ## Download as attachment is_download = False if args['download']: is_download = True # version could be either empty, or all or an integer try: int(version) except ValueError: if version != 'all': version = '' display_hidden = isUserSuperAdmin(user_info) if version != 'all': # search this filename in the complete list of files for doc in bibarchive.list_bibdocs(): if docname == bibarchive.get_docname(doc.id): try: try: docfile = doc.get_file(docformat, version) except InvenioBibDocFileError as msg: req.status = apache.HTTP_NOT_FOUND if not CFG_INSPIRE_SITE and req.headers_in.get( 'referer'): ## There must be a broken link somewhere. ## Maybe it's good to alert the admin register_exception(req=req, alert_admin=True) warn += write_warning( _("The format %(x_form)s does not exist for the given version: %(x_vers)s", x_form=cgi.escape(docformat), x_vers=cgi.escape(str(msg)))) break (auth_code, auth_message) = docfile.is_restricted(user_info) if auth_code != 0 and not is_user_owner_of_record( user_info, self.recid): if CFG_BIBDOCFILE_ICON_SUBFORMAT_RE.match( get_subformat_from_format(docformat)): return stream_restricted_icon(req) if user_info['email'] == 'guest': cookie = mail_cookie_create_authorize_action( 'viewrestrdoc', {'status': docfile.get_status()}) target = CFG_SITE_SECURE_URL + '/youraccount/login' + \ make_canonical_urlargd({'action': cookie, 'ln' : ln, 'referer' : \ CFG_SITE_SECURE_URL + user_info['uri']}, {}) redirect_to_url(req, target) else: req.status = apache.HTTP_UNAUTHORIZED warn += write_warning( _("This file is restricted: ") + str(auth_message)) break if not docfile.hidden_p(): if not readonly: ip = str(req.remote_ip) doc.register_download( ip, docfile.get_version(), docformat, uid, self.recid) try: return docfile.stream(req, download=is_download) except InvenioBibDocFileError as msg: register_exception(req=req, alert_admin=True) req.status = apache.HTTP_INTERNAL_SERVER_ERROR warn += write_warning( _("An error has happened in trying to stream the request file." )) else: req.status = apache.HTTP_UNAUTHORIZED warn += write_warning( _("The requested file is hidden and can not be accessed." )) except InvenioBibDocFileError as msg: register_exception(req=req, alert_admin=True) # Prevent leaking of restricted file names req.status = apache.HTTP_NOT_FOUND return if docname and docformat and not warn: req.status = apache.HTTP_NOT_FOUND warn += write_warning( _("Requested file does not seem to exist.")) # filelist = bibarchive.display("", version, ln=ln, verbose=verbose, display_hidden=display_hidden) filelist = bibdocfile_templates.tmpl_display_bibrecdocs( bibarchive, "", version, ln=ln, verbose=verbose, display_hidden=display_hidden) t = warn + bibdocfile_templates.tmpl_filelist(ln=ln, filelist=filelist) cc = guess_primary_collection_of_a_record(self.recid) unordered_tabs = get_detailed_page_tabs(get_colID(cc), self.recid, ln) ordered_tabs_id = [(tab_id, values['order']) for (tab_id, values) in iteritems(unordered_tabs)] ordered_tabs_id.sort(lambda x, y: cmp(x[1], y[1])) link_ln = '' if ln != CFG_SITE_LANG: link_ln = '?ln=%s' % ln tabs = [ (unordered_tabs[tab_id]['label'], '%s/%s/%s/%s%s' % (CFG_SITE_URL, CFG_SITE_RECORD, self.recid, tab_id, link_ln), tab_id == 'files', unordered_tabs[tab_id]['enabled']) for (tab_id, dummy_order) in ordered_tabs_id if unordered_tabs[tab_id]['visible'] is True ] tabs_counts = get_detailed_page_tabs_counts(self.recid) top = webstyle_templates.detailed_record_container_top( self.recid, tabs, args['ln'], citationnum=tabs_counts['Citations'], referencenum=tabs_counts['References'], discussionnum=tabs_counts['Discussions']) bottom = webstyle_templates.detailed_record_container_bottom( self.recid, tabs, args['ln']) title, description, keywords = websearch_templates.tmpl_record_page_header_content( req, self.recid, args['ln']) return pageheaderonly(title=title, navtrail=create_navtrail_links(cc=cc, aas=0, ln=ln) + \ ''' > <a class="navtrail" href="%s/%s/%s">%s</a> > %s''' % \ (CFG_SITE_URL, CFG_SITE_RECORD, self.recid, title, _("Access to Fulltext")), description=description, keywords=keywords, uid=uid, language=ln, req=req, navmenuid='search', navtrail_append_title_p=0) + \ websearch_templates.tmpl_search_pagestart(ln) + \ top + t + bottom + \ websearch_templates.tmpl_search_pageend(ln) + \ pagefooteronly(language=ln, req=req)