From b659e463d4a3030e2a23d6cfa850941a69020c24 Mon Sep 17 00:00:00 2001 From: Alan Roberts Date: Sun, 1 Sep 2024 10:21:15 -0400 Subject: [PATCH] adding admin level export as well --- app/templates/user/show_profile.html | 7 ++ app/user/routes.py | 140 +++++++++++++++++++-------- 2 files changed, 104 insertions(+), 43 deletions(-) diff --git a/app/templates/user/show_profile.html b/app/templates/user/show_profile.html index 14ca3598..46318018 100644 --- a/app/templates/user/show_profile.html +++ b/app/templates/user/show_profile.html @@ -220,6 +220,13 @@ {% endif %} +
+ {% if user_access('manage users', current_user.id) %} + + {% endif %} +
{% endif %} diff --git a/app/user/routes.py b/app/user/routes.py index 6d70f2de..abf7cb17 100644 --- a/app/user/routes.py +++ b/app/user/routes.py @@ -212,6 +212,71 @@ def remove_cover(): cache.delete_memoized(User.cover_image, current_user) return '
' + _('Banner removed!') + '
' +# export settings function. used in the /user/settings for a user to export their own settings +# used in the admin moderation /u//export_settings call to let admins +# export the user settings plus admin relevant settings +def export_user_settings(user, admin_request=False): + # make the empty dict + user_dict = {} + + # take the current_user already found + # add user's settings to the dict for output + user_dict['user_name'] = user.user_name + user_dict['alt_user_name'] = user.alt_user_name + user_dict['title'] = user.title + user_dict['email'] = user.email + user_dict['about'] = user.about + user_dict['about_html'] = user.about_html + user_dict['keywords'] = user.keywords + user_dict['matrix_user_id'] = user.matrix_user_id + user_dict['hide_nsfw'] = user.hide_nsfw + user_dict['hide_nsfl'] = user.hide_nsfl + user_dict['receive_message_mode'] = user.receive_message_mode + user_dict['bot'] = user.bot + user_dict['ignore_bots'] = user.ignore_bots + user_dict['default_sort'] = user.default_sort + user_dict['default_filter'] = user.default_filter + user_dict['theme'] = user.theme + user_dict['markdown_editor'] = user.markdown_editor + user_dict['interface_language'] = user.interface_language + user_dict['reply_collapse_threshold'] = user.reply_collapse_threshold + + # lemmy output compatibility + user_dict['display_name'] = user.user_name + user_dict['bio'] = user.about + user_dict['matrix_id'] = user.matrix_user_id + user_dict['bot_account'] = user.bot + user_dict['settings'] = { + "email": f"{user.email}", + "show_nsfw": user.hide_nsfw, + "theme": user.theme, + "default_sort_type": user.default_sort, + "default_listing_type": user.default_filter, + "interface_language": user.interface_language + } + + # get the user subscribed communities' ap_profile_id + user_subscribed_communities = [] + for c in user.communities(): + if c.ap_profile_id is None: + continue + else: + user_subscribed_communities.append(c.ap_profile_id) + user_dict['followed_communities'] = user_subscribed_communities + + # if this is an admin level export request + if admin_request: + user_dict['public_key'] = user.public_key + user_dict['private_key'] = user.private_key + + # setup the BytesIO buffer + buffer = BytesIO() + buffer.write(str(python_json.dumps(user_dict)).encode('utf-8')) + buffer.seek(0) + + # pass the buffer back to the calling function, so it can be given to the + # user for downloading + return buffer @bp.route('/user/settings', methods=['GET', 'POST']) @login_required @@ -231,50 +296,10 @@ def change_settings(): ] # seperate if to handle just the 'Export' button being clicked if form.export_settings.data and form.validate(): - # make the empty dict - user_dict = {} - - # take the current_user already found - # add user's settings to the dict for output - user_dict['user_name'] = user.user_name - user_dict['alt_user_name'] = user.alt_user_name - user_dict['title'] = user.title - user_dict['email'] = user.email - user_dict['about'] = user.about - # user_dict['about_html'] = user.about_html - user_dict['keywords'] = user.keywords - user_dict['matrix_user_id'] = user.matrix_user_id - user_dict['hide_nsfw'] = user.hide_nsfw - user_dict['hide_nsfl'] = user.hide_nsfl - # user_dict['public_key'] = user.public_key - # user_dict['private_key'] = user.private_key - user_dict['receive_message_mode'] = user.receive_message_mode - user_dict['bot'] = user.bot - user_dict['ignore_bots'] = user.ignore_bots - user_dict['default_sort'] = user.default_sort - user_dict['default_filter'] = user.default_filter - user_dict['theme'] = user.theme - user_dict['markdown_editor'] = user.markdown_editor - user_dict['interface_language'] = user.interface_language - user_dict['reply_collapse_threshold'] = user.reply_collapse_threshold - # user_dict['roles'] = user.roles - # user_dict['vote_privately'] = user.vote_privately - - # get the user subscribed communities' ap_profile_id - user_subscribed_communities = [] - for c in user.communities(): - if c.ap_profile_id is None: - continue - else: - user_subscribed_communities.append(c.ap_profile_id) - user_dict['followed_communities'] = user_subscribed_communities - - # setup the BytesIO buffer - buffer = BytesIO() - buffer.write(str(python_json.dumps(user_dict)).encode('utf-8')) - buffer.seek(0) + # get the user settings for this user + buffer = export_user_settings(user, admin_request=False) - # confirmation displated to user when the page loads up again + # confirmation displayed to user when the page loads up again flash(_l('Export Complete.')) # send the file to the user as a download @@ -563,6 +588,35 @@ def delete_profile(actor): goto = request.args.get('redirect') if 'redirect' in request.args else f'/u/{actor}' return redirect(goto) +@bp.route('/u//export_settings', methods=['GET']) +@login_required +def export_settings(actor): + if user_access('manage users', current_user.id): + actor = actor.strip() + user:User = User.query.filter_by(user_name=actor, deleted=False).first() + if user is None: + user = User.query.filter_by(ap_id=actor, deleted=False).first() + if user is None: + abort(404) + # get the user settings for this user + buffer = export_user_settings(user, admin_request=True) + + # send the file to the user as a download + # the as_attachment=True results in flask + # redirecting to the current page, so no + # url_for needed here + return send_file( + buffer, + download_name=f'{user.user_name}_piefed_settings.json', + as_attachment=True, + mimetype='application/json' + ) + + else: + abort(401) + + goto = request.args.get('redirect') if 'redirect' in request.args else f'/u/{actor}' + return redirect(goto) @bp.route('/instance//unblock', methods=['GET']) @login_required