Exemplo n.º 1
0
def route_modify(user_id):
    """ Change details about the current user """

    # only accept form data
    if request.method != 'POST':
        return redirect(url_for('main.route_profile'))

    # security check
    if g.user.user_id != user_id:
        flash('Unable to modify a different user', 'danger')
        return redirect(url_for('main.route_dashboard'))
    if g.user.auth_type == 'local+locked':
        flash('Unable to change user as account locked', 'danger')
        return redirect(url_for('main.route_dashboard'))
    if g.user.auth_type == 'oauth':
        flash('Unable to change OAuth-only user', 'danger')
        return redirect(url_for('main.route_dashboard'))
    user = db.session.query(User).filter(User.user_id == user_id).first()

    # verify name
    if 'display_name' in request.form:
        display_name = request.form['display_name']
        if len(display_name) < 3:
            flash('Failed to modify profile: Name invalid', 'warning')
            return redirect(url_for('main.route_profile'), 302)
        user.display_name = display_name

    # get the new human_user_id if specified
    if 'human_user' in request.form and request.form['human_user']:
        username = request.form['human_user']
        human_user = db.session.query(User).\
                            filter(User.username == username).first()
        if not human_user:
            flash(
                'Failed to modify profile: Human user %s not found' % username,
                'warning')
            return redirect(url_for('main.route_profile'), 302)
        user.human_user_id = human_user.user_id

    # unchecked checkbuttons are not included in the form data
    for key in [
            'notify-demote-failures', 'notify-promote', 'notify-upload-vendor',
            'notify-upload-affiliate', 'notify-non-public',
            'notify-server-error'
    ]:
        if key in request.form:
            if not user.get_action(key):
                user.actions.append(UserAction(value=key))
        else:
            action = user.get_action(key)
            if action:
                user.actions.remove(action)

    # save to database
    user.mtime = datetime.datetime.utcnow()
    db.session.commit()
    flash('Updated profile', 'info')
    return redirect(url_for('main.route_profile'))
Exemplo n.º 2
0
def route_modify_by_admin(user_id):
    """ Change details about the any user """

    # check exists
    user = db.session.query(User).filter(User.user_id == user_id).first()
    if not user:
        flash('No user matched!', 'danger')
        return redirect(url_for('main.route_dashboard'), 422)

    # security check
    if not user.vendor.check_acl('@manage-users'):
        flash('Permission denied: Unable to modify user as non-admin', 'danger')
        return redirect(url_for('main.route_dashboard'))
    if not g.user.check_acl('@admin') and 'vendor_id' in request.form:
        flash('Permission denied: Unable to modify group for user as non-admin', 'danger')
        return redirect(url_for('main.route_dashboard'))

    # user is being promoted, so check the manager already has this attribute
    if not user.check_acl('@vendor-manager') and 'vendor-manager' in request.form:
        if not g.user.check_acl('@add-action-vendor-manager'):
            flash('Permission denied: Unable to promote user to manager', 'danger')
            return redirect(url_for('main.route_dashboard'))
    if not user.check_acl('@researcher') and 'researcher' in request.form:
        if not g.user.check_acl('@add-action-researcher'):
            flash('Permission denied: Unable to promote user to researcher', 'danger')
            return redirect(url_for('main.route_dashboard'))
    if not user.check_acl('@analyst') and 'analyst' in request.form:
        if not g.user.check_acl('@add-action-analyst'):
            flash('Permission denied: Unable to promote user to analyst', 'danger')
            return redirect(url_for('main.route_dashboard'))
    if not user.check_acl('@qa') and 'qa' in request.form:
        if not g.user.check_acl('@add-action-qa'):
            flash('Permission denied: Unable to promote user to QA', 'danger')
            return redirect(url_for('main.route_dashboard'))
    if not user.check_acl('@approved-public') and 'approved-public' in request.form:
        if not g.user.check_acl('@add-action-approved-public'):
            flash('Permission denied: Unable to promote user to approved public', 'danger')
            return redirect(url_for('main.route_dashboard'))
    if not user.check_acl('@robot') and 'robot' in request.form:
        if not g.user.check_acl('@add-action-robot'):
            flash('Permission denied: Unable to mark user as robot', 'danger')
            return redirect(url_for('main.route_dashboard'))
    if not user.check_acl('@admin') and 'admin' in request.form:
        if not g.user.check_acl('@add-action-admin'):
            flash('Permission denied: Unable to mark user as admin', 'danger')
            return redirect(url_for('main.route_dashboard'))
    if not user.check_acl('@admin') and 'partner' in request.form:
        if not g.user.check_acl('@add-action-partner'):
            flash('Permission denied: Unable to mark user as partner', 'danger')
            return redirect(url_for('main.route_dashboard'))

    # set each optional thing in turn
    old_vendor = user.vendor
    for key in ['display_name', 'username', 'auth_type', 'vendor_id', 'auth_warning']:
        if key in request.form:
            value = request.form[key]
            if value == '':
                value = None
            setattr(user, key, value)

    # get the new human_user_id if specified
    if 'human_user' in request.form:
        username = request.form['human_user']
        if username:
            human_user = db.session.query(User).\
                                filter(User.username == username).first()
            if not human_user:
                flash('Failed to modify profile: Human user %s not found' % username, 'warning')
                return redirect(url_for('main.route_profile'), 302)
            user.human_user_id = human_user.user_id
        else:
            user.human_user_id = None

    # unchecked checkbuttons are not included in the form data
    for key in ['is_otp_enabled']:
        setattr(user, key, bool(key in request.form))
    for key in ['qa', 'analyst', 'vendor-manager', 'researcher',
                'approved-public', 'robot', 'admin', 'partner']:
        if key in request.form:
            if not user.get_action(key):
                user.actions.append(UserAction(value=key))
        else:
            action = user.get_action(key)
            if action:
                user.actions.remove(action)

    # password is optional, and hashed
    if 'password' in request.form and request.form['password']:
        user.password = request.form['password']

    # was disabled?
    if user.auth_type == 'disabled':
        if not user.dtime:
            user.dtime = datetime.datetime.utcnow()
    else:
        user.dtime = None

    user.mtime = datetime.datetime.utcnow()
    db.session.commit()

    # reparent any uploaded firmware
    is_dirty = False
    reparent = bool('reparent' in request.form)
    if old_vendor.vendor_id != user.vendor_id and reparent:
        for fw in db.session.query(Firmware).\
                    filter(Firmware.user_id == user.user_id):
            fw.vendor_id = user.vendor_id
            if fw.remote.name.startswith('embargo'):
                is_dirty = True
            fw.remote_id = user.vendor.remote.remote_id
        for ev in db.session.query(FirmwareEvent).\
                    filter(FirmwareEvent.user_id == user.user_id):
            ev.remote_id = user.vendor.remote.remote_id

    # fix event log
    if old_vendor.vendor_id != user.vendor_id:
        for ev in db.session.query(Event).\
                    filter(Event.user_id == user.user_id):
            ev.vendor_id = user.vendor_id

    # mark both remotes as dirty
    if is_dirty:
        user.vendor.remote.is_dirty = True
        old_vendor.remote.is_dirty = True
    db.session.commit()

    # send email
    if 'send_email' in request.form:
        if old_vendor.vendor_id != user.vendor_id:
            send_email("[LVFS] Your account has been moved",
                       user.email_address,
                       render_template('email-moved.txt',
                                       user=user,
                                       old_vendor=old_vendor,
                                       reparent=reparent))
        else:
            if user.auth_type == 'disabled':
                send_email("[LVFS] Your account has been disabled",
                           user.email_address,
                           render_template('email-disabled.txt', user=user))
            else:
                send_email("[LVFS] Your account has been updated",
                           user.email_address,
                           render_template('email-modify.txt', user=user))
        flash('Updated profile and sent a notification email to the user', 'info')
    else:
        flash('Updated profile', 'info')

    return redirect(url_for('users.route_admin', user_id=user_id))
def upgrade():
    op.create_table('user_actions',
                    sa.Column('user_action_id', sa.Integer(), nullable=False),
                    sa.Column('user_id', sa.Integer(), nullable=False),
                    sa.Column('ctime', sa.DateTime(), nullable=False),
                    sa.Column('value', sa.Text(), nullable=True),
                    sa.ForeignKeyConstraint(
                        ['user_id'],
                        ['users.user_id'],
                    ),
                    sa.PrimaryKeyConstraint('user_action_id'),
                    sa.UniqueConstraint('user_action_id'),
                    mysql_character_set='utf8mb4')

    for user in db.session.query(User):
        if user.unused_is_qa:
            user.actions.append(UserAction(value='qa'))
        if user.unused_is_robot:
            user.actions.append(UserAction(value='robot'))
        if user.unused_is_analyst:
            user.actions.append(UserAction(value='analyst'))
        if user.unused_is_vendor_manager:
            user.actions.append(UserAction(value='vendor-manager'))
        if user.unused_is_approved_public:
            user.actions.append(UserAction(value='approved-public'))
        if user.unused_is_admin:
            user.actions.append(UserAction(value='admin'))
        if user.unused_is_researcher:
            user.actions.append(UserAction(value='researcher'))
        if user.unused_notify_demote_failures:
            user.actions.append(UserAction(value='notify-demote-failures'))
        if user.unused_notify_server_error:
            user.actions.append(UserAction(value='notify-server-error'))
        if user.unused_notify_upload_vendor:
            user.actions.append(UserAction(value='notify-upload-vendor'))
        if user.unused_notify_upload_affiliate:
            user.actions.append(UserAction(value='notify-upload-affiliate'))
        if user.unused_notify_promote:
            user.actions.append(UserAction(value='notify-promote'))

    db.session.commit()