Beispiel #1
0
def delete_privilege(id):
    role = Role.query.filter_by(id=id).first()
    user_role = Role.query.filter_by(name='user').first()
    if role is None or role.name in [
            'user', 'admin', 'developer', 'advocate', 'cron'
    ]:
        flash(word('The role could not be deleted.'), 'error')
    else:
        for user in db.session.query(UserModel).options(
                db.joinedload('roles')):
            roles_to_remove = list()
            for the_role in user.roles:
                if the_role.name == role.name:
                    roles_to_remove.append(the_role)
            if len(roles_to_remove) > 0:
                for the_role in roles_to_remove:
                    user.roles.remove(the_role)
                if len(user.roles) == 0:
                    user.roles.append(user_role)
        db.session.commit()
        db.session.delete(role)
        db.session.commit()
        flash(word('The role ' + role.name + ' was deleted.'), 'success')
        #docassemble.webapp.daredis.clear_user_cache()
    return redirect(url_for('privilege_list'))
Beispiel #2
0
def delete_privilege(id):
    setup_translation()
    if not id:
        flash(word('The role could not be deleted.'), 'error')
        return redirect(url_for('privilege_list'))
    role = db.session.execute(select(Role).filter_by(id=id)).scalar_one()
    user_role = db.session.execute(select(Role).filter_by(name='user')).scalar_one()
    if user_role is None or role is None or role.name in ['user', 'admin', 'developer', 'advocate', 'cron', 'trainer']:
        flash(word('The role could not be deleted.'), 'error')
    else:
        for user in db.session.execute(select(UserModel).options(db.joinedload(UserModel.roles))).unique().scalars():
            roles_to_remove = []
            for the_role in user.roles:
                if the_role.name == role.name:
                    roles_to_remove.append(the_role)
            if len(roles_to_remove) > 0:
                for the_role in roles_to_remove:
                    user.roles.remove(the_role)
                if len(user.roles) == 0:
                    user.roles.append(user_role)
        db.session.commit()
        db.session.delete(role)
        db.session.commit()
        flash(word('The role ' + role.name + ' was deleted.'), 'success')
        #docassemble.webapp.daredis.clear_user_cache()
    return redirect(url_for('privilege_list'))
Beispiel #3
0
def get_person(user_id, cache):
    if user_id in cache:
        return cache[user_id]
    for record in UserModel.query.options(db.joinedload('roles')).filter_by(id=user_id):
        cache[record.id] = record
        return record
    return None
Beispiel #4
0
def user_list():
    users = list()
    for user in db.session.query(UserModel).options(db.joinedload('roles')).order_by(UserModel.id):
        if user.nickname == 'cron':
            continue
        role_names = [y.name for y in user.roles]
        if 'admin' in role_names:
            high_priv = 'admin'
        elif 'developer' in role_names:
            high_priv = 'developer'
        elif 'advocate' in role_names:
            high_priv = 'advocate'
        elif 'trainer' in role_names:
            high_priv = 'trainer'
        else:
            high_priv = 'user'
        name_string = ''
        if user.first_name:
            name_string += text_type(user.first_name) + " "
        if user.last_name:
            name_string += text_type(user.last_name)
        if name_string:
            name_string = text_type(name_string)
        active_string = ''
        if user.email is None:
            user_indicator = user.nickname
        else:
            user_indicator = user.email
        if user.active:
            is_active = True
        else:
            is_active = False
        users.append(dict(name=name_string, email=user_indicator, active=is_active, id=user.id, high_priv=high_priv))
    return render_template('users/userlist.html', version_warning=None, bodyclass='daadminbody', page_title=word('User List'), tab_title=word('User List'), users=users)
Beispiel #5
0
def user_list():
    setup_translation()
    page = request.args.get('page', None)
    if page:
        try:
            page = int(page) - 1
            assert page >= 0
        except:
            page = 0
    else:
        page = 0
    users = list()
    user_query = select(UserModel).options(db.joinedload(UserModel.roles)).where(and_(UserModel.nickname != 'cron', not_(UserModel.social_id.like('disabled$%')))).order_by(UserModel.id)
    if page > 0:
        user_query = user_query.offset(PAGINATION_LIMIT*page)
    user_query = user_query.limit(PAGINATION_LIMIT_PLUS_ONE)
    results_in_query = 0
    there_are_more = False
    for user in db.session.execute(user_query).unique().scalars():
        results_in_query += 1
        if results_in_query == PAGINATION_LIMIT_PLUS_ONE:
            there_are_more = True
            break
        role_names = [y.name for y in user.roles]
        if 'admin' in role_names:
            high_priv = 'admin'
        elif 'developer' in role_names:
            high_priv = 'developer'
        elif 'advocate' in role_names:
            high_priv = 'advocate'
        elif 'trainer' in role_names:
            high_priv = 'trainer'
        else:
            high_priv = 'user'
        name_string = ''
        if user.first_name:
            name_string += str(user.first_name) + " "
        if user.last_name:
            name_string += str(user.last_name)
        if name_string:
            name_string = str(name_string)
        active_string = ''
        if user.email is None:
            user_indicator = user.nickname
        else:
            user_indicator = user.email
        if user.active:
            is_active = True
        else:
            is_active = False
        users.append(dict(name=name_string, email=user_indicator, active=is_active, id=user.id, high_priv=high_priv))
    if there_are_more:
        next_page = page + 2
    else:
        next_page = None
    prev_page = page
    response = make_response(render_template('users/userlist.html', version_warning=None, bodyclass='daadminbody', page_title=word('User List'), tab_title=word('User List'), users=users, prev_page=prev_page, next_page=next_page), 200)
    response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0'
    return response
Beispiel #6
0
def edit_user_profile_page(id):
    user = UserModel.query.options(db.joinedload('roles')).filter_by(id=id).first()
    the_tz = user.timezone if user.timezone else get_default_timezone()
    if user is None:
        abort(404)
    if 'disable_mfa' in request.args and int(request.args['disable_mfa']) == 1:
        user.otp_secret = None
        db.session.commit()
        #docassemble.webapp.daredis.clear_user_cache()
        return redirect(url_for('edit_user_profile_page', id=id))
    if 'reset_email_confirmation' in request.args and int(request.args['reset_email_confirmation']) == 1:
        user.confirmed_at = None
        db.session.commit()
        #docassemble.webapp.daredis.clear_user_cache()
        return redirect(url_for('edit_user_profile_page', id=id))
    the_role_id = list()
    for role in user.roles:
        the_role_id.append(text_type(role.id))
    if len(the_role_id) == 0:
        the_role_id = [text_type(Role.query.filter_by(name='user').first().id)]
    form = EditUserProfileForm(request.form, obj=user, role_id=the_role_id)
    if request.method == 'POST' and form.cancel.data:
        flash(word('The user profile was not changed.'), 'success')
        return redirect(url_for('user_list'))
    if user.social_id.startswith('local$'):
        form.role_id.choices = [(r.id, r.name) for r in db.session.query(Role).filter(Role.name != 'cron').order_by('name')]
        privileges_note = None
    else:
        form.role_id.choices = [(r.id, r.name) for r in db.session.query(Role).filter(and_(Role.name != 'cron', Role.name != 'admin')).order_by('name')]
        privileges_note = word("Note: only users with e-mail/password accounts can be given admin privileges.")
    form.timezone.choices = [(x, x) for x in sorted([tz for tz in pytz.all_timezones])]
    form.timezone.default = the_tz
    if text_type(form.timezone.data) == 'None' or text_type(form.timezone.data) == '':
        form.timezone.data = the_tz
    if user.otp_secret is None:
        form.uses_mfa.data = False
    else:
        form.uses_mfa.data = True
    admin_id = Role.query.filter_by(name='admin').first().id
    if request.method == 'POST' and form.validate(user.id, admin_id):
        form.populate_obj(user)
        roles_to_remove = list()
        the_role_id = list()
        for role in user.roles:
            roles_to_remove.append(role)
        for role in roles_to_remove:
            user.roles.remove(role)
        for role in Role.query.order_by('id'):
            if role.id in form.role_id.data:
                user.roles.append(role)
                the_role_id.append(role.id)
        db.session.commit()
        #docassemble.webapp.daredis.clear_user_cache()
        flash(word('The information was saved.'), 'success')
        return redirect(url_for('user_list'))
    form.role_id.default = the_role_id
    confirmation_feature = True if user.id > 2 else False
    return render_template('users/edit_user_profile_page.html', version_warning=None, page_title=word('Edit User Profile'), tab_title=word('Edit User Profile'), form=form, confirmation_feature=confirmation_feature, privileges_note=privileges_note, is_self=(user.id == current_user.id))
Beispiel #7
0
def user_list():
    users = list()
    for user in db.session.query(UserModel).options(
            db.joinedload('roles')).order_by(UserModel.id):
        if user.nickname == 'cron' or user.social_id.startswith('disabled$'):
            continue
        role_names = [y.name for y in user.roles]
        if 'admin' in role_names:
            high_priv = 'admin'
        elif 'developer' in role_names:
            high_priv = 'developer'
        elif 'advocate' in role_names:
            high_priv = 'advocate'
        elif 'trainer' in role_names:
            high_priv = 'trainer'
        else:
            high_priv = 'user'
        name_string = ''
        if user.first_name:
            name_string += text_type(user.first_name) + " "
        if user.last_name:
            name_string += text_type(user.last_name)
        if name_string:
            name_string = text_type(name_string)
        active_string = ''
        if user.email is None:
            user_indicator = user.nickname
        else:
            user_indicator = user.email
        if user.active:
            is_active = True
        else:
            is_active = False
        users.append(
            dict(name=name_string,
                 email=user_indicator,
                 active=is_active,
                 id=user.id,
                 high_priv=high_priv))
    response = make_response(
        render_template('users/userlist.html',
                        version_warning=None,
                        bodyclass='daadminbody',
                        page_title=word('User List'),
                        tab_title=word('User List'),
                        users=users), 200)
    response.headers[
        'Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0'
    return response
Beispiel #8
0
def edit_user_profile_page(id):
    setup_translation()
    is_admin = bool(current_user.has_roles('admin'))
    if is_admin:
        can_edit_privileges = True
        can_delete = True
        can_edit_user_active_status = True
    else:
        can_edit_privileges = current_user.can_do('edit_user_privileges')
        can_delete = current_user.can_do('delete_user') and current_user.can_do('access_sessions') and current_user.can_do('edit_sessions')
        can_edit_user_active_status = current_user.can_do('edit_user_active_status')
    if not id:
        flash(word('The user account did not exit.'), 'danger')
        return redirect(url_for('user_list'))
    user = db.session.execute(select(UserModel).options(db.joinedload(UserModel.roles)).filter_by(id=id)).unique().scalar_one()
    if not user:
        flash(word('The user account did not exit.'), 'danger')
        return redirect(url_for('user_list'))
    if not is_admin:
        protected_user = False
        for role in user.roles:
            if role.name in ('admin', 'developer', 'advocate'):
                protected_user = True
                break
        if protected_user:
            flash(word('You do not have sufficient privileges to edit this user.'), 'danger')
            return redirect(url_for('user_list'))
    the_tz = user.timezone if user.timezone else get_default_timezone()
    if user is None or user.social_id.startswith('disabled$'):
        return redirect(url_for('user_list'))
    if 'disable_mfa' in request.args and int(request.args['disable_mfa']) == 1:
        user.otp_secret = None
        db.session.commit()
        #docassemble.webapp.daredis.clear_user_cache()
        return redirect(url_for('edit_user_profile_page', id=id))
    if 'reset_email_confirmation' in request.args and int(request.args['reset_email_confirmation']) == 1:
        user.confirmed_at = None
        db.session.commit()
        #docassemble.webapp.daredis.clear_user_cache()
        return redirect(url_for('edit_user_profile_page', id=id))
    if can_delete and daconfig.get('admin can delete account', True) and user.id != current_user.id:
        if 'delete_account' in request.args and int(request.args['delete_account']) == 1:
            server.user_interviews(user_id=id, secret=None, exclude_invalid=False, action='delete_all', delete_shared=False)
            delete_user_data(id, server.server_redis, server.server_redis_user)
            db.session.commit()
            flash(word('The user account was deleted.'), 'success')
            return redirect(url_for('user_list'))
        if 'delete_account_complete' in request.args and int(request.args['delete_account_complete']) == 1:
            server.user_interviews(user_id=id, secret=None, exclude_invalid=False, action='delete_all', delete_shared=True)
            delete_user_data(id, server.server_redis, server.server_redis_user)
            db.session.commit()
            flash(word('The user account was deleted.'), 'success')
            return redirect(url_for('user_list'))
    the_role_id = []
    for role in user.roles:
        the_role_id.append(role.id)
    if len(the_role_id) == 0:
        the_role_id = [db.session.execute(select(Role.id).filter_by(name='user')).scalar_one()]
    form = EditUserProfileForm(request.form, obj=user, role_id=the_role_id)
    if request.method == 'POST' and form.cancel.data:
        flash(word('The user profile was not changed.'), 'success')
        return redirect(url_for('user_list'))
    if user.social_id.startswith('local$') or daconfig.get('allow external auth with admin accounts', False):
        form.role_id.choices = [(r.id, r.name) for r in db.session.execute(select(Role.id, Role.name).where(Role.name != 'cron').order_by('name'))]
        privileges_note = None
    else:
        form.role_id.choices = [(r.id, r.name) for r in db.session.execute(select(Role.id, Role.name).where(and_(Role.name != 'cron', Role.name != 'admin')).order_by('name'))]
        privileges_note = word("Note: only users with e-mail/password accounts can be given admin privileges.")
    form.timezone.choices = [(x, x) for x in sorted(list(zoneinfo.available_timezones()))]
    form.timezone.default = the_tz
    if str(form.timezone.data) == 'None' or str(form.timezone.data) == '':
        form.timezone.data = the_tz
    form.uses_mfa.data = bool(user.otp_secret is not None)
    admin_id = db.session.execute(select(Role.id).filter_by(name='admin')).scalar_one()
    if request.method == 'POST' and form.validate(user.id, admin_id):
        if not can_edit_user_active_status:
            form.active.data = user.active
        form.populate_obj(user)
        if can_edit_privileges:
            roles_to_remove = []
            the_role_id = []
            for role in user.roles:
                if not is_admin and role.name in ('admin', 'developer', 'advocate'):
                    continue
                roles_to_remove.append(role)
            for role in roles_to_remove:
                user.roles.remove(role)
            for role in db.session.execute(select(Role).order_by('id')).scalars():
                if not is_admin and role.name in ('admin', 'developer', 'advocate'):
                    continue
                if role.id in form.role_id.data:
                    user.roles.append(role)
                    the_role_id.append(role.id)
        db.session.commit()
        flash(word('The information was saved.'), 'success')
        return redirect(url_for('user_list'))
    confirmation_feature = bool(user.id > 2)
    script = """
    <script>
      $(".dadeleteaccount").click(function(event){
        if (!confirm(""" + json.dumps(word("Are you sure you want to permanently delete this user's account?")) + """)){
          event.preventDefault();
          return false;
        }
      });
    </script>"""
    form.role_id.process_data(the_role_id)
    if user.active:
        form.active.default = 'checked'
    response = make_response(render_template('users/edit_user_profile_page.html', version_warning=None, page_title=word('Edit User Profile'), tab_title=word('Edit User Profile'), form=form, confirmation_feature=confirmation_feature, privileges_note=privileges_note, is_self=(user.id == current_user.id), extra_js=Markup(script), is_admin=is_admin, can_edit_privileges=can_edit_privileges, can_delete=can_delete, can_edit_user_active_status=can_edit_user_active_status), 200)
    response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0'
    return response
Beispiel #9
0
def edit_user_profile_page(id):
    user = UserModel.query.options(
        db.joinedload('roles')).filter_by(id=id).first()
    the_tz = user.timezone if user.timezone else get_default_timezone()
    if user is None or user.social_id.startswith('disabled$'):
        abort(404)
    if 'disable_mfa' in request.args and int(request.args['disable_mfa']) == 1:
        user.otp_secret = None
        db.session.commit()
        #docassemble.webapp.daredis.clear_user_cache()
        return redirect(url_for('edit_user_profile_page', id=id))
    if 'reset_email_confirmation' in request.args and int(
            request.args['reset_email_confirmation']) == 1:
        user.confirmed_at = None
        db.session.commit()
        #docassemble.webapp.daredis.clear_user_cache()
        return redirect(url_for('edit_user_profile_page', id=id))
    if daconfig.get('admin can delete account',
                    True) and user.id != current_user.id:
        if 'delete_account' in request.args and int(
                request.args['delete_account']) == 1:
            from docassemble.webapp.server import user_interviews, r, r_user
            from docassemble.webapp.backend import delete_user_data
            user_interviews(user_id=id,
                            secret=None,
                            exclude_invalid=False,
                            action='delete_all',
                            delete_shared=False)
            delete_user_data(id, r, r_user)
            db.session.commit()
            flash(word('The user account was deleted.'), 'success')
            return redirect(url_for('user_list'))
        if 'delete_account_complete' in request.args and int(
                request.args['delete_account_complete']) == 1:
            from docassemble.webapp.server import user_interviews, r, r_user
            from docassemble.webapp.backend import delete_user_data
            user_interviews(user_id=id,
                            secret=None,
                            exclude_invalid=False,
                            action='delete_all',
                            delete_shared=True)
            delete_user_data(id, r, r_user)
            db.session.commit()
            flash(word('The user account was deleted.'), 'success')
            return redirect(url_for('user_list'))
    the_role_id = list()
    for role in user.roles:
        the_role_id.append(text_type(role.id))
    if len(the_role_id) == 0:
        the_role_id = [text_type(Role.query.filter_by(name='user').first().id)]
    form = EditUserProfileForm(request.form, obj=user, role_id=the_role_id)
    if request.method == 'POST' and form.cancel.data:
        flash(word('The user profile was not changed.'), 'success')
        return redirect(url_for('user_list'))
    if user.social_id.startswith('local$'):
        form.role_id.choices = [(r.id, r.name)
                                for r in db.session.query(Role).filter(
                                    Role.name != 'cron').order_by('name')]
        privileges_note = None
    else:
        form.role_id.choices = [(r.id, r.name) for r in db.session.query(
            Role).filter(and_(Role.name != 'cron',
                              Role.name != 'admin')).order_by('name')]
        privileges_note = word(
            "Note: only users with e-mail/password accounts can be given admin privileges."
        )
    form.timezone.choices = [
        (x, x) for x in sorted([tz for tz in pytz.all_timezones])
    ]
    form.timezone.default = the_tz
    if text_type(form.timezone.data) == 'None' or text_type(
            form.timezone.data) == '':
        form.timezone.data = the_tz
    if user.otp_secret is None:
        form.uses_mfa.data = False
    else:
        form.uses_mfa.data = True
    admin_id = Role.query.filter_by(name='admin').first().id
    if request.method == 'POST' and form.validate(user.id, admin_id):
        form.populate_obj(user)
        roles_to_remove = list()
        the_role_id = list()
        for role in user.roles:
            roles_to_remove.append(role)
        for role in roles_to_remove:
            user.roles.remove(role)
        for role in Role.query.order_by('id'):
            if role.id in form.role_id.data:
                user.roles.append(role)
                the_role_id.append(role.id)
        db.session.commit()
        #docassemble.webapp.daredis.clear_user_cache()
        flash(word('The information was saved.'), 'success')
        return redirect(url_for('user_list'))
    form.role_id.default = the_role_id
    confirmation_feature = True if user.id > 2 else False
    script = """
    <script>
      $(".dadeleteaccount").click(function(event){
        if (!confirm(""" + json.dumps(
        word("Are you sure you want to permanently delete this user's account?"
             )) + """)){
          event.preventDefault();
          return false;
        }
      });
    </script>"""
    response = make_response(
        render_template('users/edit_user_profile_page.html',
                        version_warning=None,
                        page_title=word('Edit User Profile'),
                        tab_title=word('Edit User Profile'),
                        form=form,
                        confirmation_feature=confirmation_feature,
                        privileges_note=privileges_note,
                        is_self=(user.id == current_user.id),
                        extra_js=Markup(script)), 200)
    response.headers[
        'Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0'
    return response
Beispiel #10
0
def populate_tables(start_time=None):
    if start_time is None:
        start_time = time.time()
    sys.stderr.write("create_tables.populate_tables: starting after " +
                     str(time.time() - start_time) + "\n")
    UserManager(SQLAlchemyAdapter(db, UserModel, UserAuthClass=UserAuthModel),
                app)
    sys.stderr.write(
        "create_tables.populate_tables: obtained UserManager after " +
        str(time.time() - start_time) + "\n")
    result = {}
    admin_defaults = daconfig.get('default admin account', {})
    if 'email' not in admin_defaults:
        admin_defaults['email'] = os.getenv('DA_ADMIN_EMAIL',
                                            '*****@*****.**')
    if 'nickname' not in admin_defaults:
        admin_defaults['nickname'] = 'admin'
    if 'first_name' not in admin_defaults:
        admin_defaults['first_name'] = word('System')
    if 'last_name' not in admin_defaults:
        admin_defaults['last_name'] = word('Administrator')
    if 'password' not in admin_defaults:
        admin_defaults['password'] = os.getenv('DA_ADMIN_PASSWORD', 'password')
    cron_defaults = daconfig.get(
        'default cron account', {
            'nickname': 'cron',
            'email': '*****@*****.**',
            'first_name': 'Cron',
            'last_name': 'User'
        })
    cron_defaults['active'] = False
    user_role = get_role(db, 'user', result=result)
    admin_role = get_role(db, 'admin', result=result)
    cron_role = get_role(db, 'cron', result=result)
    get_role(db, 'customer', result=result)
    get_role(db, 'developer', result=result)
    get_role(db, 'advocate', result=result)
    get_role(db, 'trainer', result=result)
    if daconfig.get('fix user roles', False):
        sys.stderr.write(
            "create_tables.populate_tables: fixing user roles after " +
            str(time.time() - start_time) + "\n")
        to_fix = []
        for user in db.session.execute(
                select(UserModel).options(db.joinedload(
                    UserModel.roles))).scalars():
            if len(user.roles) == 0:
                to_fix.append(user)
        if len(to_fix) > 0:
            sys.stderr.write(
                "create_tables.populate_tables: found user roles to fix after "
                + str(time.time() - start_time) + "\n")
            for user in to_fix:
                user.roles.append(user_role)
            db.session.commit()
        sys.stderr.write(
            "create_tables.populate_tables: done fixing user roles after " +
            str(time.time() - start_time) + "\n")
    admin = get_user(db, admin_role, admin_defaults, result=result)
    cron = get_user(db, cron_role, cron_defaults, result=result)
    if admin.confirmed_at is None:
        admin.confirmed_at = datetime.datetime.now()
    if cron.confirmed_at is None:
        cron.confirmed_at = datetime.datetime.now()
    if result.get('changed', False):
        db.session.commit()
    sys.stderr.write(
        "create_tables.populate_tables: calling add_dependencies after " +
        str(time.time() - start_time) + "\n")
    add_dependencies(admin.id, start_time=start_time)
    sys.stderr.write(
        "create_tables.populate_tables: add_dependencies finished after " +
        str(time.time() - start_time) + "\n")
    git_packages = db.session.execute(
        select(Package).filter_by(type='git')).scalars().all()
    package_info_changed = False
    for package in git_packages:
        if package.name in [
                'docassemble', 'docassemble.base', 'docassemble.webapp',
                'docassemble.demo'
        ]:
            if package.giturl:
                package.giturl = None
                package_info_changed = True
            if package.gitsubdir:
                package.gitsubdir = None
                package_info_changed = True
            if package.type != 'pip':
                package.type = 'pip'
                package_info_changed = True
            if daconfig.get('stable version', False):
                if package.limitation != '<1.1.0':
                    package.limitation = '<1.1.0'
                    package_info_changed = True
    if package_info_changed:
        db.session.commit()
    sys.stderr.write("create_tables.populate_tables: ending after " +
                     str(time.time() - start_time) + "\n")