def delete_inactive_users(): user_auto_delete = docassemble.base.config.daconfig.get('user auto delete', {}) if not isinstance(user_auto_delete, dict): sys.stderr.write("Error in configuration for user auto delete\n") return if not user_auto_delete.get('enable', True): return try: cutoff_days = int(user_auto_delete.get('inactive days', 0)) assert cutoff_days >= 0 except: sys.stderr.write("Error in configuration for user auto delete\n") return if cutoff_days == 0: return delete_shared = bool(user_auto_delete.get('delete shared', False)) role_ids = {} for item in Role.query.all(): role_ids[item.name] = item.id roles = user_auto_delete.get('privileges', ['user']) if isinstance(roles, str): roles = [roles] if not isinstance(roles, list): sys.stderr.write("Error in configuration for user auto delete\n") return search_roles = set() for item in roles: if not isinstance(item, str): sys.stderr.write("Error in configuration for user auto delete: invalid privilege\n") return if item not in role_ids: sys.stderr.write("Error in configuration for user auto delete: unknown privilege" + repr(item) + "\n") return if item == 'cron': sys.stderr.write("Error in configuration for user auto delete: invalid privilege\n") return search_roles.add(role_ids[item]) filters = [] for item in search_roles: filters.append(UserRoles.role_id == item) cutoff_date = datetime.datetime.utcnow() - dateutil.relativedelta.relativedelta(days=cutoff_days) default_date = datetime.datetime(2020, 2, 24, 0, 0) candidates = [] for item in db.session.execute(select(UserModel.id, UserModel.last_login).join(UserRoles, UserModel.id == UserRoles.user_id).where(or_(*filters))).all(): if item.last_login is None: the_date = default_date else: the_date = item.last_login if the_date < cutoff_date: candidates.append(item.id) for user_id in candidates: last_interview = db.session.execute(select(UserDictKeys.user_id, db.func.max(UserDict.modtime).label('last_activity')).join(UserDict, and_(UserDictKeys.filename == UserDict.filename, UserDictKeys.key == UserDict.key)).where(UserDictKeys.user_id == user_id).group_by(UserDictKeys.user_id)).first() if last_interview is not None and last_interview.last_activity > cutoff_date: continue sys.stderr.write("delete_inactive_users: deleting %d\n" % (user_id,)) user_interviews(user_id=user_id, secret=None, exclude_invalid=False, action='delete_all', delete_shared=delete_shared, admin=True) docassemble.webapp.backend.delete_user_data(user_id, r, r_user)
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