Beispiel #1
0
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.'))
Beispiel #2
0
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
Beispiel #3
0
 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}]
Beispiel #4
0
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)
Beispiel #5
0
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'))
Beispiel #6
0
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
Beispiel #8
0
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('/')
Beispiel #9
0
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))
Beispiel #10
0
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)
Beispiel #11
0
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)
Beispiel #12
0
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()
Beispiel #13
0
    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
Beispiel #15
0
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'))
Beispiel #16
0
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
    )
Beispiel #17
0
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'))
Beispiel #18
0
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)
Beispiel #19
0
 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)
Beispiel #20
0
 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'}]
Beispiel #21
0
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))
Beispiel #22
0
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.'))
Beispiel #23
0
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,
    )
Beispiel #24
0
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."
            ))
Beispiel #25
0
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)
Beispiel #26
0
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))
Beispiel #27
0
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.')
        )
Beispiel #28
0
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))
Beispiel #29
0
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'))
Beispiel #30
0
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)
Beispiel #31
0
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."))
Beispiel #32
0
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')
Beispiel #33
0
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)
Beispiel #34
0
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",
            }
Beispiel #35
0
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()])
Beispiel #36
0
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."))
Beispiel #37
0
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))
Beispiel #38
0
 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."))
Beispiel #39
0
    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)
Beispiel #40
0
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)
Beispiel #41
0
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'))
Beispiel #42
0
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,
    )
Beispiel #43
0
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.")))
Beispiel #44
0
 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."),
     )
Beispiel #45
0
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)
Beispiel #46
0
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)
Beispiel #47
0
 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))
Beispiel #48
0
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)
Beispiel #49
0
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)
Beispiel #50
0
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('/')
Beispiel #51
0
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'))
Beispiel #52
0
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,
    )
Beispiel #53
0
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)
Beispiel #54
0
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
Beispiel #55
0
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"))
Beispiel #56
0
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,
    )
Beispiel #57
0
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'))
Beispiel #58
0
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.")))
Beispiel #59
0
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()]))
Beispiel #60
0
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