def validate_tag_name(dummy_form, field): """ Check validity of tag name """ max_len = cfg['CFG_TAGS_NAME_MAX_LENGTH'] max_char = cfg['CFG_TAGS_MAX_CHARACTER'] if field.data: suggested_silent = wash_tag_silent(field.data) suggested = wash_tag_blocking(suggested_silent) field.data = suggested_silent if suggested != suggested_silent: raise validators.ValidationError( _('Forbidden characters. Try ') + suggested + '.') if len(suggested) <= 0: raise validators.ValidationError( _('The name must contain valid characters.')) if len(suggested_silent) > max_len: raise validators.ValidationError( _('The name cannot exeed ') + str(max_len) + _(' characters.')) if max(ord(letter) for letter in suggested_silent) > max_char: raise validators.ValidationError( _('Forbidden character.'))
def check_for_software_updates(flash_message=False): """Check for a new release of Invenio. :return: True if you have latest version, else False if you need to upgrade or None if server was not reachable. """ from invenio.config import CFG_VERSION from invenio.base.i18n import _ try: find = re.compile('Invenio v[0-9]+.[0-9]+.[0-9]+(\-rc[0-9])?' ' is released') release_notes = 'https://raw.githubusercontent.com/' \ 'inveniosoftware/invenio/master/RELEASE-NOTES' webFile = urllib.request.urlopen(release_notes) temp = "" version = "" version1 = "" while 1: temp = webFile.readline() match1 = find.match(temp) try: version = match1.group() break except Exception: pass if not temp: break webFile.close() submatch = re.compile('[0-9]+.[0-9]+.[0-9]+(\-rc[0-9])?') version1 = submatch.search(version) web_version = version1.group().split(".") local_version = CFG_VERSION.split(".") if (web_version[0] > local_version[0] or web_version[0] == local_version[0] and web_version[1] > local_version[1] or web_version[0] == local_version[0] and web_version[1] == local_version[1] and web_version[2] > local_version[2]): if flash_message: flash(_('A newer version of Invenio is available for ' 'download. You may want to visit ' '<a href="%(wiki)s">%()s</a>', wiki='<a href=\"http://invenio-software.org/wiki/' '/Installation/Download'), 'warning') return False except Exception as e: print(e) if flash_message: flash(_('Cannot download or parse release notes ' 'from %(release_notes)s', release_notes=release_notes), 'error') return None return True
def formatoptions(self): if len(self._formatoptions): return [dict(f) for f in self._formatoptions] else: return [{'code': u'hb', 'name': _("HTML %(format)s", format=_("brief")), 'content_type': u'text/html', 'visibility': 1}]
def edit(name): """Edit.""" if name not in _USER_SETTINGS: flash(_('Invalid plugin name'), 'error') return redirect(url_for('.index')) plugin = _USER_SETTINGS[name]() form = None if request.method == 'POST': if plugin.form_builder: form = plugin.form_builder(request.form) if not form or form.validate(): if form: # use the form to interpret data settings_data = form.data else: # no form provided, save the POST request values settings_data = flatten_multidict(request.values) plugin.store(settings_data) plugin.save() flash(_('Data has been saved.'), 'success') return redirect(url_for('.index')) flash(_('Please, corrent errors.'), 'error') # get post data or load data from settings if not form and plugin.form_builder: form = plugin.build_form() return render_template(getattr(plugin, 'edit_template', '') or 'accounts/edit.html', plugin=plugin, form=form)
def new_member(group_id): """Add (invite) new member.""" group = Group.query.get_or_404(group_id) if group.can_invite_others(current_user): form = NewMemberForm() if form.validate_on_submit(): emails = filter(None, form.data['emails'].splitlines()) group.invite_by_emails(emails) flash(_('Requests sent!'), 'success') return redirect(url_for('.members', group_id=group.id)) return render_template( "groups/new_member.html", group=group, form=form ) flash( _( 'You cannot invite user or yourself (i.e. join) to the group ' '%(group_name)s', group_name=group.name ), 'error' ) return redirect(url_for('.index'))
def manage(group_id): """Manage your group.""" group = Group.query.get_or_404(group_id) form = GroupForm(request.form, obj=group) if form.validate_on_submit(): if group.can_edit(current_user): try: group.update(**form.data) flash(_('Group "%(name)s" was updated', name=group.name), 'success') except Exception as e: flash(str(e), 'error') return render_template( "groups/new.html", form=form, group=group, ) else: flash( _( 'You cannot edit group %(group_name)s', group_name=group.name ), 'error' ) return render_template( "groups/new.html", form=form, group=group, )
def format_element(bfo, as_label=False): ln = bfo.lang collections = bfo.fields("980__") # Loop over collection identifiers. First 980 entry that has a publication # type in subfield a is used. Subfield b denotes a subtype. # # Other non-publication type 980 entries include user collection # identifiers, and ZENODO specific identifiers like "curated". CFG_OPENAIRE_PUBTYPE_MAP = current_app.config["CFG_OPENAIRE_PUBTYPE_MAP"] for c in collections: try: collection = c.get("a") subcollection = c.get("b", None) name = _(dict(CFG_OPENAIRE_PUBTYPE_MAP)[collection]) query = "980__a:%s" % collection if subcollection: name = _(dict(CFG_OPENAIRE_PUBTYPE_MAP)[subcollection]) query = "980__b:%s" % subcollection if as_label: return """<a href="/search?p=%s" class="label label-inverse">%s</a>""" % (query, name) else: return name except KeyError: pass
def access(): """Access.""" try: mail = mail_cookie_check_mail_activation(request.values['mailcookie']) u = User.query.filter(User.email == mail).one() u.note = 1 try: db.session.commit() except SQLAlchemyError: db.session.rollback() flash(_('Authorization failled.'), 'error') redirect('/') if current_user.is_authenticated(): current_user.reload() flash(_('Your email address has been validated'), 'success') else: UserInfo(u.id).reload() flash( _('Your email address has been validated, and you can ' 'now proceed to sign-in.'), 'success' ) except Exception: current_app.logger.exception("Authorization failed.") flash(_('The authorization token is invalid.'), 'error') return redirect('/')
def register_admin(app, admin): """Called on app initialization to register administration interface.""" category = _('Quotas') admin.add_view(ResourceUsageAdmin( ResourceUsage, db.session, name=_('Resource Usage'), category=category))
def tag_edit(id_tag): """List of documents attached to this tag.""" id_user = current_user.get_id() tag = WtgTAG.query.get(id_tag) if not tag: flash(_('Invalid tag id'), "error") return redirect(url_for('.display_cloud')) if tag.id_user != id_user: flash(_('You are not authorized to view this tag'), "error") return redirect(url_for('.display_cloud')) form = EditTagForm(request.values, csrf_enabled=False, obj=tag) if form.validate_on_submit(): form.populate_obj(tag) name_count = db.session.query(WtgTAG).\ filter_by(id_user=id_user, name=tag.name).count() if name_count == 1: db.session.add(tag) db.session.commit() flash(_('Tag Successfully edited.'), 'success') else: flash(_('Tag name') + ' <strong>' + tag.name + '</strong> ' + _('is already in use.'), 'error') return dict(tag=tag, form=form)
def join(id_usergroup, id_user=None, status=None): """Join group.""" group = Usergroup.query.get_or_404(id_usergroup) id_user2join = id_user or current_user.get_id() user2join = User.query.get_or_404(id_user2join) form = UserJoinGroupForm() user_status = None if form.user_status and form.user_status.data: user_status = UserUsergroup.USER_STATUS['ADMIN'] try: group.join(user2join, status=user_status) except AccountSecurityError: flash(_( 'You have not enough right to ' 'add user "%(x_nickname)s" to the group "%(x_groupname)s"', x_nickname=user2join.nickname, x_groupname=group.name), "error") return redirect(url_for('.index')) except SQLAlchemyError: flash(_('User "%(x_nickname)s" can\'t join the group "%(x_groupname)s"', x_nickname=user2join.nickname, x_groupname=group.name), "error") if id_user: return redirect(url_for('.members', id_usergroup=id_usergroup)) else: return redirect(url_for('.index')) current_user.reload() flash(_('%(user)s join the group "%(name)s".', user='******'+user2join.nickname+'"' if id_user else "You", name=group.name), 'success') redirect_url = form.redirect_url.data or url_for('.index') return redirect(redirect_url)
def results(qid, p, of, so, rm): """ Generates results for cached query using POSTed filter. @param qid: query indentifier """ try: recIDsHitSet = get_current_user_records_that_can_be_displayed(qid) except KeyError: return 'KeyError' except: return _('Please reload the page') try: filter_data = json.loads(request.values.get('filter', '[]')) except: return _('Invalid filter data') @check_collection( name_getter=functools.partial(get_collection_name_from_cache, qid)) def make_results(collection): recids = faceted_results_filter(recIDsHitSet, filter_data, FACETS.elements) recids = sort_and_rank_records(recids, so=so, rm=rm, p=p) return response_formated_records( recids, collection, of, create_nearest_terms_box=_create_neareset_term_box, qid=qid) return make_results()
def validate_email(self, field): """Validate email.""" field.data = field.data.lower() if validate_email(field.data.lower()) != 1: raise validators.ValidationError( _("Supplied email address %(email)s is invalid.", email=field.data) ) # is email already taken? try: User.query.filter(User.email == field.data).one() raise validators.ValidationError( _("Supplied email address %(email)s already exists " "in the database.", email=field.data) ) except SQLAlchemyError: pass # if the email is changed we reset the password to a random one, such # that the user is forced to confirm the new email import random from webuser import updatePasswordUser updatePasswordUser(current_user['id'], int(random.random() * 1000000)) from flask import flash, url_for flash(_("Note that if you have changed your email address, you \ will have to <a href=%(link)s>reset</a> your password anew.", link=url_for('webaccount.lost')), 'warning')
def format_element(bfo, as_label=False, brief=False): ln = bfo.lang collections = bfo.fields('980__') # Loop over collection identifiers. First 980 entry that has a publication # type in subfield a is used. Subfield b denotes a subtype. # # Other non-publication type 980 entries include user collection # identifiers, and Zenodo specific identifiers like "curated". CFG_OPENAIRE_PUBTYPE_MAP = current_app.config['CFG_OPENAIRE_PUBTYPE_MAP'] for c in collections: try: collection = c.get('a') subcollection = c.get('b', None) name = _(dict(CFG_OPENAIRE_PUBTYPE_MAP)[collection]) query = "980__a:%s" % collection url = url_for('record.metadata', recid=bfo.recID) if subcollection: name = _(dict(CFG_OPENAIRE_PUBTYPE_MAP)[subcollection]) query = "980__b:%s" % subcollection if as_label: if brief: return """<a href="%s" class="label label-inverse">%s</a>""" % (url, name) else: return """<a href="/search?p=%s" class="label label-inverse">%s</a>""" % (query, name) else: return name except KeyError: pass
def approve(group_id, user_id): """Approve a user.""" membership = Membership.query.get_or_404((user_id, group_id)) group = membership.group if group.can_edit(current_user): try: membership.accept() except Exception as e: flash(str(e), 'error') return redirect(url_for('.requests', group_id=membership.group.id)) flash(_('%(user)s accepted to %(name)s group.', user=membership.user.email, name=membership.group.name), 'success') return redirect(url_for('.requests', group_id=membership.group.id)) flash( _( 'You cannot approve memberships for the group %(group_name)s', group_name=group.name ), 'error' ) return redirect(url_for('.index'))
def send_reset_password_email(email): """Reset password by sending a email with the unique link.""" expires_in = cfg.get('CFG_WEBSESSION_ADDRESS_ACTIVATION_EXPIRE_IN_DAYS') reset_key = EmailConfirmationSerializer( expires_in=timedelta(days=expires_in).total_seconds() ).create_token(email, {'email': email}) if not reset_key: raise AccountSecurityError( _('Something goes wrong when the cookie has been generated') ) email_text = render_template( 'accounts/email_reset_password.html', reset_key=reset_key, email=email ) return send_email( fromaddr=cfg['CFG_SITE_SUPPORT_EMAIL'], subject=_("Password reset request for %(website)s", website=cfg['CFG_SITE_URL']), toaddr=email, content=email_text )
def leave(group_id): """Leave group.""" group = Group.query.get_or_404(group_id) if group.can_leave(current_user): try: group.remove_member(current_user) except Exception as e: flash(str(e), "error") return redirect(url_for('.index')) flash( _( 'You have successfully left %(group_name)s group.', group_name=group.name ), 'success' ) return redirect(url_for('.index')) flash( _( 'You cannot leave the group %(group_name)s', group_name=group.name ), 'error' ) return redirect(url_for('.index'))
def resetpassword(reset_key): """Reset password form (loaded after asked new password).""" email = None try: email = mail_cookie_check_pw_reset(reset_key) except InvenioWebAccessMailCookieDeletedError: flash( _('This request for resetting a password has already been used.'), 'error' ) except InvenioWebAccessMailCookieError: flash(_('This request for resetting a password is not valid or is ' 'expired.'), 'error') if email is None or cfg['CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS'] >= 3: return redirect(url_for('webaccount.index')) form = ResetPasswordForm(request.values) if form.validate_on_submit(): password = request.values['password'] # change password user = User.query.filter_by(email=email).one() user.password = password db.session.merge(user) db.session.commit() # delete cookie mail_cookie_delete_cookie(reset_key) flash(_("The password was correctly reset."), 'success') return redirect(url_for('webaccount.index')) return render_template('accounts/resetpassword.html', form=form)
def inner(*args, **kwargs): try: return f(*args, **kwargs) except InvalidDepositionType: if request.is_xhr: abort(400) flash(_("Invalid deposition type."), 'danger') return redirect(url_for(endpoint)) except (DepositionDoesNotExists,): flash(_("Deposition does not exists."), 'danger') return redirect(url_for(endpoint)) except (DepositionNotDeletable,): flash(_("Deposition cannot be deleted."), 'danger') return redirect(url_for(endpoint)) except (InvalidDepositionAction, ): flash(_("Invalid action."), 'warning') return redirect(url_for(endpoint)) except (DraftDoesNotExists,): abort(400) except (FormDoesNotExists,): abort(400) except (UploadError,): abort(400) except (ForbiddenAction,): flash(_("Not allowed."), 'danger') return redirect(url_for(endpoint)) except (UploadError,): abort(400)
def formatoptions(self): """Return list of format options.""" if len(self._formatoptions): return [dict(f) for f in self._formatoptions] else: return [{'code': u'hb', 'name': _("HTML %(format)s", format=_("brief")), 'content_type': u'text/html'}]
def subscribe(recid): uid = current_user.get_id() subscription = CmtSUBSCRIPTION(id_bibrec=recid, id_user=uid, creation_time=datetime.now()) try: db.session.add(subscription) db.session.commit() flash(_("You have been successfully subscribed"), "success") except: flash(_("You are already subscribed"), "error") return redirect(url_for(".comments", recid=recid))
def validate_tag_exists(dummy_form, field): """ Check if id_tag matches a tag in database """ if field.data: try: field.data = int(field.data) except ValueError: raise validators.ValidationError(_('Tag ID must be an integer.')) if not db.session.query(WtgTAG).get(field.data): raise validators.ValidationError(_('Tag does not exist.'))
def access_request(recid=None): """Create an access request.""" record = get_record(recid) # Record must be in restricted access mode. if record.get('access_right') != 'restricted' or \ not record.get('access_conditions'): abort(404) # Record must have an owner and owner must still exists. try: record_owner = User.query.get_or_404(record['owner']['id']) except KeyError: abort(404) sender = None initialdata = dict() # Prepare initial form data if current_user.is_authenticated(): sender = current_user initialdata = dict( # FIXME: add full_name attribute to user accounts. full_name=" ".join([sender["family_name"], sender["given_names"]]), email=sender["email"], ) # Normal form validation form = AccessRequestForm(formdata=request.form, **initialdata) if form.validate_on_submit(): accreq = AccessRequest.create( recid=recid, receiver=record_owner, sender_full_name=form.data['full_name'], sender_email=form.data['email'], justification=form.data['justification'], sender=sender ) if accreq.status == RequestStatus.EMAIL_VALIDATION: flash(_( "Email confirmation needed: We have sent you an email to " "verify your address. Please check the email and follow the " "instructions to complete the access request."), category='info') else: flash(_("Access request submitted."), category='info') return redirect(url_for("record.metadata", recid=recid)) return render_template( 'accessrequests/access_request.html', record=record, form=form, )
def validate_expires_at(form, field): """Validate that date is in the future.""" if form.accept.data: if not field.data or date.today() >= field.data: raise validators.StopValidation(_( "Please provide a future date." )) if not field.data or date.today()+timedelta(days=365) < field.data: raise validators.StopValidation(_( "Please provide a date no more than 1 year into the future." ))
def notes(recid): """Note page.""" """View for the record notes extracted from comments""" if not cfg['ANNOTATIONS_NOTES_ENABLED']: return redirect(url_for('comments.comments', recid=recid)) from invenio.modules.access.local_config import VIEWRESTRCOLL from invenio.modules.access.mailcookie import \ mail_cookie_create_authorize_action from invenio.modules.comments.api import check_user_can_view_comments auth_code, auth_msg = check_user_can_view_comments(current_user, recid) if auth_code and current_user.is_guest: cookie = mail_cookie_create_authorize_action(VIEWRESTRCOLL, { 'collection': g.collection}) url_args = {'action': cookie, 'ln': g.ln, 'referer': request.referrer} flash(_("Authorization failure"), 'error') return redirect(url_for('webaccount.login', **url_args)) elif auth_code: flash(auth_msg, 'error') abort(401) from invenio.modules.annotations.api import get_annotations page = request.args.get('page', type=int) if cfg["ANNOTATIONS_PREVIEW_ENABLED"] and not request.is_xhr: # the notes will be requested again via AJAX notes = [] elif page is None or page == -1: notes = prepare_notes(get_annotations({"where.record": recid})) else: import re rgx = re.compile("^P\.([0-9]*?\,)*?" + str(page) + "(,|$|[_]\.*)") notes = prepare_notes(get_annotations({"where.marker": rgx, "where.record": recid})) if request.is_xhr: template = 'annotations/notes_fragment.html' else: template = 'annotations/notes.html' flash(_('This is a summary of all the comments that includes only the \ existing annotations. The full discussion is available \ <a href="' + url_for('comments.comments', recid=recid) + '">here</a>.'), "info(html_safe)") from invenio.utils.washers import wash_html_id return render_template(template, notes=notes, option='notes', get_note_title=get_note_title, note_is_collapsed=note_is_collapsed, get_original_comment=get_original_comment, wash_html_id=wash_html_id)
def report(recid, id): if CommentRights(id).can_perform_action(): CmtRECORDCOMMENT.query.filter(CmtRECORDCOMMENT.id == id).update( dict(nb_abuse_reports=CmtRECORDCOMMENT.nb_abuse_reports + 1), synchronize_session="fetch" ) log_comment_action(cfg["CFG_WEBCOMMENT_ACTION_CODE"]["REPORT_ABUSE"], id, recid) flash(_("Comment has been reported."), "success") else: flash(_("Comment has been already reported."), "error") return redirect(url_for("comments.comments", recid=recid))
def current_user_password_validator(form, field): """Validate password field if is the password of the user.""" id_user = current_user.get_id() if not id_user: raise validators.ValidationError( _("Nobody is currently logged-in.")) user = User.query.filter_by(id=id_user).one() if not user.verify_password(field.data): raise validators.ValidationError( _('The password inserted is not valid.') )
def report(recid, id): if CommentRights(id).can_perform_action(): CmtRECORDCOMMENT.query.filter(CmtRECORDCOMMENT.id == id).update(dict( nb_abuse_reports=CmtRECORDCOMMENT.nb_abuse_reports + 1), synchronize_session='fetch') log_comment_action(cfg['CFG_WEBCOMMENT_ACTION_CODE']['REPORT_ABUSE'], id, recid) flash(_('Comment has been reported.'), 'success') else: flash(_('Comment has been already reported.'), 'error') return redirect(url_for('comments.comments', recid=recid))
def delete_all(confirmed=0): """ Delete every message belonging a logged user. @param confirmed: 0 will produce a confirmation message. """ uid = current_user.get_id() if confirmed != 1: return render_template('messages/confirm_delete.html') if dbquery.delete_all_messages(uid): flash(_("Your mailbox has been emptied."), "info") else: flash(_("Could not empty your mailbox."), "warning") return redirect(url_for('.index'))
def add(msg_reply_id): from invenio.utils.mail import email_quote_txt uid = current_user.get_id() if msg_reply_id: if (dblayer.check_user_owns_message(uid, msg_reply_id) == 0): flash(_('Sorry, this message in not in your mailbox.'), "error") return redirect(url_for('.index')) else: try: m = dbquery.get_message(uid, msg_reply_id) message = MsgMESSAGE() message.sent_to_user_nicks = m.message.user_from.nickname \ or str(m.message.id_user_from) message.subject = _("Re:") + " " + m.message.subject message.body = email_quote_txt(m.message.body) form = AddMsgMESSAGEForm(request.form, obj=message) return render_template('messages/add.html', form=form) except db.sqlalchemy.orm.exc.NoResultFound: # The message exists in table user_msgMESSAGE # but not in table msgMESSAGE => table inconsistency flash(_('This message does not exist.'), "error") except: flash(_('Problem with loading message.'), "error") return redirect(url_for('.index')) form = AddMsgMESSAGEForm(request.values) if form.validate_on_submit(): m = MsgMESSAGE() form.populate_obj(m) m.id_user_from = uid m.sent_date = datetime.now() quotas = dblayer.check_quota(cfg['CFG_WEBMESSAGE_MAX_NB_OF_MESSAGES'] - 1) users = filter(lambda x: x.id in quotas, m.recipients) #m.recipients = m.recipients.difference(users)) for u in users: m.recipients.remove(u) if len(users) > 0: flash(_('Following users reached their quota %(quota)d messages: %(users)s', quota=cfg['CFG_WEBMESSAGE_MAX_NB_OF_MESSAGES'], users=', '.join([u.nickname for u in users])), "error") flash(_('Message has %(recipients)d valid recipients.', recipients=len(m.recipients)), "info") if len(m.recipients) == 0: flash(_('Message was not sent'), "info") else: if m.received_date is not None and m.received_date > datetime.now(): for um in m.sent_to_users: um.status = cfg['CFG_WEBMESSAGE_STATUS_CODE']['REMINDER'] else: m.received_date = datetime.now() try: db.session.add(m) db.session.commit() flash(_('Message was sent'), "info") return redirect(url_for('.index')) except: db.session.rollback() return render_template('messages/add.html', form=form)
class ChangePasswordForm(InvenioBaseForm): """Form to change password.""" current_password = PasswordField(_("Current password"), description=_("Your current password")) password = PasswordField( _("New password"), description=_("The password phrase may contain punctuation, " "spaces, etc.")) password2 = PasswordField(_("Confirm new password"), ) def validate_current_password(self, field): """Validate current password.""" from invenio.ext.login import authenticate if not authenticate(current_user['nickname'], field.data): raise validators.ValidationError(_("Password mismatch."))
class ChangeUserEmailSettingsForm(InvenioBaseForm): """Form to change user email settings.""" email = StringField(_("New email")) def validate_email(self, field): """Validate email.""" field.data = field.data.lower() if validate_email(field.data.lower()) != 1: raise validators.ValidationError( _("Supplied email address %(email)s is invalid.", email=field.data)) # is email already taken? try: User.query.filter(User.email == field.data).one() raise validators.ValidationError( _( "Supplied email address %(email)s already exists " "in the database.", email=field.data)) except SQLAlchemyError: pass # if the email is changed we reset the password to a random one, such # that the user is forced to confirm the new email import random from webuser import updatePasswordUser updatePasswordUser(current_user['id'], int(random.random() * 1000000)) from flask import flash, url_for flash( _("Note that if you have changed your email address, you \ will have to <a href=%(link)s>reset</a> your password anew.", link=url_for('webaccount.lost')), 'warning')
def authenticate(nickname_or_email=None, password=None, login_method='Local', remember=False): """ Find user identified by given information and login method. :param nickname_or_email: User nickname or email address :param password: Password used only in login methods that need it :param login_method: Login method (default: 'Local') :return: UserInfo """ from invenio.base.i18n import _ from invenio.ext.sqlalchemy import db from invenio.modules.accounts.models import User from sqlalchemy.orm.exc import NoResultFound where = [ db.or_(User.nickname == nickname_or_email, User.email == nickname_or_email) ] if login_method == 'Local' and password is not None: where.append(User.password == password) try: user = User.query.filter(*where).one() except NoResultFound: return None except Exception: return False if user.settings['login_method'] != login_method: flash( _( "You are not authorized to use '%(x_login_method)s' login " "method.", x_login_method=login_method), 'error') return False if user.note == '2': # account is not confirmed logout_user() flash( _("You have not yet confirmed the email address for the \ '%(login_method)s' authentication method.", login_method=login_method), 'warning') if remember: session.permanent = True return login_user(user.id, remember=remember)
class inspire_approval(object): """Class representing the approval action.""" name = _("Approve (INSPIRE)") url = url_for("holdingpen.resolve_action") def render_mini(self, obj): """Method to render the minified action.""" return render_template( 'workflows/actions/approval_mini.html', message=obj.get_action_message(), object=obj, resolve_url=self.url, ) def render(self, obj): """Method to render the action.""" return { "side": render_template( 'workflows/actions/approval_side.html', message=obj.get_action_message(), object=obj, resolve_url=self.url, ), "main": render_template( 'workflows/actions/approval_main.html', message=obj.get_action_message(), object=obj, resolve_url=self.url, ) } def resolve(self, bwo): """Resolve the action taken in the approval action.""" from flask import request value = request.form.get("value", None) bwo.remove_action() extra_data = bwo.get_extra_data() if value == 'accept': extra_data["approved"] = True bwo.set_extra_data(extra_data) bwo.save() bwo.continue_workflow(delayed=True) return { "message": "Record has been accepted!", "category": "success", } elif value == 'reject': extra_data["approved"] = False bwo.set_extra_data(extra_data) bwo.save() bwo.continue_workflow(delayed=True) return { "message": "Record has been rejected (deleted)", "category": "warning", }
class AddCmtRECORDCOMMENTForm(InvenioBaseForm): """Define form for writing new comment.""" title = StringField(_('Title')) body = TextAreaField(_('Message'), [ validators.length(0, 10000, message=_( "Your message is too long, please edit it. " "Maximum size allowed is %{length}i characters.", length=10000)) ]) in_reply_to_id_cmtRECORDCOMMENT = HiddenField(default=0) notes_howto = HOWTO pdf_page = HiddenField( validators=[validators.Optional(), validators.NumberRange()])
def repeat_email_validator(form, field): """Validate repeat email field.""" if form.email.short_name in form.errors or \ (form.email.data == current_user['email'] and field.data == ""): raise StopValidation() if field.data != form.email.data: raise ValidationError(_("Email addresses do not match."))
def validate_email(email): """Check whether wanted EMAIL address supplied by the user is valid. At the moment we just check whether it contains '@' and whether it doesn't contain blanks. We also check the email domain if CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN is set. """ CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN = current_app.config.get( 'CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN') if (email.find("@") <= 0) or (email.find(" ") > 0): raise validators.ValidationError( _("Supplied email address %(x_addr)s is invalid.", x_addr=email)) elif CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN: if not email.endswith(CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN): raise validators.ValidationError( _("Supplied email address %(x_addr)s is invalid.", x_addr=email))
def validate_identifier(self, field): """Validate field identifier.""" if field.data: field.data = field.data.lower() if Community.query.filter_by(id=field.data).first(): raise validators.ValidationError( _("The identifier already exists." " Please choose a different one."))
def __iter__(self): """Get all the output formats.""" from invenio.modules.formatter.models import Format formats = Format.query.filter_by(visibility=True).all() yield ('', _('Default')) for format_ in formats: yield (format_.code, format_.name)
def lost(): form = LostPasswordForm(request.values) if form.validate_on_submit(): if reset_password(request.values['email'], g.ln): flash( _('A password reset link has been sent to %(whom)s', whom=request.values['email']), 'success') return render_template('accounts/lost.html', form=form)
def update(id_collection): form = CollectionForm(request.form) if request.method == 'POST': # and form.validate(): collection = Collection.query.get_or_404(id_collection) form.populate_obj(collection) db.session.commit() flash(_('Collection was updated'), "info") return redirect(url_for('.index'))
def new(): """Create new group.""" form = GroupForm(request.form) if form.validate_on_submit(): try: group = Group.create(admins=[current_user], **form.data) group.add_member(current_user) flash(_('Group "%(name)s" created', name=group.name), 'success') return redirect(url_for(".index")) except IntegrityError: flash(_('Group creation failure'), 'error') return render_template( "groups/new.html", form=form, )
def delete_multi(bwolist): """Delete list of objects from the db.""" from ..utils import parse_bwids bwolist = parse_bwids(bwolist) for objectid in bwolist: delete_from_db(objectid) return jsonify( dict(category="success", message=_("Objects deleted successfully.")))
def menu_fixup(): item = current_menu.submenu('settings.profile') item.register( 'userprofile.index', _('%(icon)s Profile', icon='<i class="fa fa-user fa-fw"></i>'), order=0, active_when=lambda: request.endpoint.startswith("userprofile."), )
def wrap_nonpublic_note(field, **dummy_kwargs): """Proceedings box with tooltip.""" html = u'<div class="tooltip-wrapper" data-toggle="tooltip"' \ 'title="%s"><textarea %s></textarea></div>' % \ (_('Journal Information already exists'), html_params(id="nonpublic_note", class_="form-control nonpublic_note", name="nonpublic_note")) return HTMLString(html)
def skip_importdata(field, **dummy_kwargs): """Skip Import data button.""" html = u'<button %s>%s</button>' % \ (html_params(id="skipImportData", class_="btn btn-link", name="skipImportData", type="button"), _('Skip, and fill the form manually')) return HTMLString(html)
def search_within(self): """Collect search within options.""" default = [('', _('any field'))] found = [(o.field.code, o.field.name_ln) for o in self._search_within] if not found: found = [(f.name.replace(' ', ''), f.name_ln) for f in Field.query.filter(Field.name.in_( cfg['CFG_WEBSEARCH_SEARCH_WITHIN'])).all()] return default + sorted(found, key=itemgetter(1))
def lost(): """Lost password form for authenticated users.""" form = LostPasswordForm(request.form) if form.validate_on_submit(): email = request.values['email'] try: if send_reset_password_email(email=email): flash(_('A password reset link has been sent to %(whom)s', whom=email), 'success') else: flash(_('Error happen when the email was send. ' 'Please contact the administrator.'), 'error') except AccountSecurityError as e: flash(e, 'error') return render_template("accounts/settings/lost.html", form=form)
class LoginForm(Form): """Login Form.""" nickname = StringField( _("Nickname"), validators=[ DataRequired(message=_("Nickname not provided")), validate_nickname_or_email ]) password = PasswordField(_("Password")) remember = BooleanField(_("Remember Me")) referer = HiddenField() login_method = HiddenField() submit = SubmitField(_("Sign in")) def validate_login_method(self, field): """Validate login_method.""" field.data = wash_login_method(field.data)
def access(): try: mail = mail_cookie_check_mail_activation(request.values['mailcookie']) User.query.filter(User.email == mail).one().note = 1 try: db.session.commit() except: db.session.rollback() flash(_('Authorization failled.'), 'error') flash( _('Your email address has been validated, and you can now proceed ' 'to sign-in.'), 'success' ) except: current_app.logger.exception("Authorization failed.") flash(_('The authorization token is invalid.'), 'error') return redirect('/')
def leave(id_usergroup, id_user=None): """Leave user group. :param id_usergroup: Identifier of user group. """ group = Usergroup.query.get_or_404(id_usergroup) id_user2remove = id_user or current_user.get_id() user2remove = User.query.get_or_404(id_user2remove) try: group.leave(user2remove) except AccountSecurityError: flash( _( 'You have not enough right to ' 'remove user "%(x_nickname)s" from group "%(x_groupname)s"', x_nickname=user2remove.nickname, x_groupname=group.name), "error") return redirect(url_for('.index')) except IntegrityUsergroupError: flash( _( 'Sorry, user "%(x_nickname)s" can leave the group ' '"%(x_groupname)s" without admins, please delete the ' 'group if you want to leave.', x_nickname=user2remove.nickname, x_groupname=group.name), "error") return redirect(url_for('.index')) try: db.session.merge(group) db.session.commit() except SQLAlchemyError: db.session.rollback() raise current_user.reload() flash( _('%(user)s left the group "%(name)s".', user='******' + user2remove.nickname + '"' if id_user else "You", name=group.name), 'success') if id_user and id_user != current_user.get_id(): return redirect(url_for('.members', id_usergroup=id_usergroup)) else: return redirect(url_for('.index'))
def profile(): """Change password form for authenticated users.""" u = User.query.filter_by(id=current_user.get_id()).first() profile_form = ProfileForm(formdata=None, obj=u, prefix="profile") verification_form = VerificationForm(formdata=None, prefix="verification") password_form = ChangePasswordForm(formdata=None, prefix="password") form = request.form.get('submit', None) if form == 'password': password_form.process(formdata=request.form) if password_form.validate_on_submit(): new_password = password_form.data['password'] u.password = new_password db.session.merge(u) db.session.commit() flash(_("Password changed."), category="success") elif form == 'profile': profile_form.process(formdata=request.form) if profile_form.validate_on_submit(): changed_attrs = u.update_profile(profile_form.data) if 'email' in changed_attrs: flash(_("Profile updated. We have sent a verification email to" " %(email)s. Please check it.", email=u.email), category="success") elif changed_attrs: flash(_("Profile updated."), category="success") else: flash(_("No changes to profile."), category="success") elif form == 'verification': verification_form.process(formdata=request.form) if verification_form.validate_on_submit(): if u.verify_email(): flash(_("Verification email sent."), category="success") return render_template( "accounts/settings/profile.html", password_form=password_form, profile_form=profile_form, verification_form=verification_form, user=u, )
def importdata_button(field, **dummy_kwargs): """Import data button.""" html = u'<button %s data-target="%s">%s</button>' % \ (html_params(id="importData", class_="btn btn-success btn-large", name="importData", type="button"), '#myModal', _('Auto import')) return HTMLString(html)
def login(nickname=None, password=None, login_method=None, action='', remember=False, referer=None): """Login.""" if cfg.get('CFG_ACCESS_CONTROL_LEVEL_SITE') > 0: return abort(401) # page is not authorized if action: from invenio.modules.access.mailcookie import \ InvenioWebAccessMailCookieError, \ mail_cookie_check_authorize_action try: action, arguments = mail_cookie_check_authorize_action(action) except InvenioWebAccessMailCookieError: pass form = LoginForm(CombinedMultiDict([ ImmutableMultiDict({ 'referer': referer, 'login_method': 'Local' } if referer else {'login_method': 'Local'}), request.values ]), csrf_enabled=False) if request.method == "POST": try: if login_method == 'Local' and form.validate_on_submit() and \ authenticate(nickname, password, login_method=login_method, remember=remember): flash(_("You are logged in as %(nick)s.", nick=nickname), "success") return login_redirect(referer) else: flash(_("Invalid credentials."), "error") except Exception as e: current_app.logger.error('Exception during login process: %s', str(e)) flash(_("Problem with login."), "error") return render_template('accounts/login.html', form=form), 401
def delete(deposition_type=None, uuid=None): """Delete the whole deposition with uuid=uuid (including form drafts). After deletion it will redirect to the index page. """ deposition = Deposition.get(uuid, current_user, type=deposition_type) deposition.delete() flash(_('%(name)s deleted.', name=deposition.type.name), 'success') return redirect(url_for(".index"))
def send_reject_notification(request, message=None): """Receiver for request-rejected signal to send email notification.""" _send_notification( request.sender_email, _("Access request rejected"), "accessrequests/emails/rejected.tpl", request=request, record=get_record(request.recid), message=message, )
def delete(): """ Delete message specified by 'msgid' that belongs to logged user. """ uid = current_user.get_id() msgids = request.values.getlist('msgid', type=int) if len(msgids) <= 0: flash(_('Sorry, no valid message specified.'), "error") elif dbquery.check_user_owns_message(uid, msgids) < len(msgids): flash( _('Sorry, this message (#%(x_msg)s) is not in your mailbox.', x_msg=(str(msgids), )), "error") else: if dbquery.delete_message_from_user_inbox(uid, msgids) == 0: flash(_("The message could not be deleted."), "error") else: flash(_("The message was successfully deleted."), "info") return redirect(url_for('.index'))
def restart_record(objectid, start_point='continue_next'): """Restart the initial object in its workflow.""" bwobject = BibWorkflowObject.query.get_or_404(objectid) workflow = Workflow.query.filter( Workflow.uuid == bwobject.id_workflow).first() start_delayed(workflow.name, [bwobject.get_data()]) return jsonify( dict(category="success", message=_("Object restarted successfully.")))
class DynamicKnowledgeForm(KnowledgeForm): """Dynamic Knowledge form.""" output_tag = StringField(label="Field") search_expression = StringField(label="Expression") id_collection = SelectField( 'Collection', coerce=int, choices=LocalProxy(lambda: [(0, _('-None-'))] + [(c.id, c.name) for c in Collection.query.all()]))
def TranslationsForm(language_list_long, values): """Translation form.""" class _TranslationsForm(InvenioBaseForm): collection_id = HiddenField() for (lang, lang_long) in language_list_long: setattr(_TranslationsForm, lang, StringField(_(lang_long), default=values.get(lang, ''))) return _TranslationsForm