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'))
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'))
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
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)
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
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))
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
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
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
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")