diff --git a/requirements.txt b/requirements.txt index 3cb02071..f271a34e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,3 +15,4 @@ filetype setproctitle tqdm opencc +dnspython diff --git a/users/templates/users/data.html b/users/templates/users/data.html index 26a22124..540a7a33 100644 --- a/users/templates/users/data.html +++ b/users/templates/users/data.html @@ -196,13 +196,33 @@
-
{% trans 'Mastodon/Pleroma社交关系数据' %}
+
{% trans '更新社交关系数据' %}
{% csrf_token %} 上次更新时间 {{ user.mastodon_last_refresh }}
- 为了正确展示短评和评论,NeoDB会缓存你的关注、屏蔽和静音列表。如果你刚刚更新过帐户的上锁状态、增减过关注、静音或屏蔽,希望立即生效,可以点击这里立刻更新;这类信息也会每天自动同步。 + 为了正确高效的展示短评和评论,NeoDB会缓存你在联邦网络的关注、屏蔽和静音列表。如果你刚刚更新过帐户的上锁状态、增减过关注、静音或屏蔽,希望立即生效,可以点击这里立刻更新;这类信息也会每天自动同步。 +
+
+
+
+
+
+ +
+
+
+
{% trans '替换社交账号' %}
+
+
+ {% csrf_token %} +
输入新社交账号所在的实例域名 + + +
+
+ 替换后可使用新的联邦网络身份来登录NeoDB和控制数据可见性,已有的标记评论收藏单等数据不受影响。
@@ -217,9 +237,11 @@
{% csrf_token %} -
输入完整的 用户名@实例名 以确认删除 + +
+
删除将无法撤销
diff --git a/users/urls.py b/users/urls.py index 4b61fa32..eeb8cd06 100644 --- a/users/urls.py +++ b/users/urls.py @@ -6,6 +6,7 @@ urlpatterns = [ path('login/', login, name='login'), path('register/', register, name='register'), path('connect/', connect, name='connect'), + path('reconnect/', reconnect, name='reconnect'), path('data/', data, name='data'), path('data/export_reviews', export_reviews, name='export_reviews'), path('data/export_marks', export_marks, name='export_marks'), diff --git a/users/views.py b/users/views.py index b6597b82..c5a53601 100644 --- a/users/views.py +++ b/users/views.py @@ -25,6 +25,7 @@ from movies.forms import MovieMarkStatusTranslator from music.forms import MusicMarkStatusTranslator from games.forms import GameMarkStatusTranslator from mastodon.models import MastodonApplication +from mastodon.api import verify_account from django.conf import settings from urllib.parse import quote import django_rq @@ -42,6 +43,30 @@ from collection.models import Collection # Views ######################################## +def swap_login(request, token, site): + del request.session['swap_login'] + del request.session['swap_domain'] + code, data = verify_account(site, token) + current_user = request.user + if code == 200 and data is not None: + username = data['username'] + if username == current_user.username and site == current_user.mastodon_site: + messages.add_message(request, messages.ERROR, _(f'该身份 {username}@{site} 与当前账号相同。')) + else: + try: + existing_user = User.objects.get(username=username, mastodon_site=site) + messages.add_message(request, messages.ERROR, _(f'该身份 {username}@{site} 已被用于其它账号。')) + except ObjectDoesNotExist: + current_user.username = username + current_user.mastodon_site = site + current_user.mastodon_token = token + current_user.save(update_fields=['username', 'mastodon_site', 'mastodon_token']) + django_rq.get_queue('mastodon').enqueue(refresh_mastodon_data_task, current_user, token) + messages.add_message(request, messages.INFO, _(f'账号身份已更新为 {username}@{site}。')) + else: + messages.add_message(request, messages.ERROR, _('连接联邦网络获取身份信息失败。')) + return redirect(reverse('users:data')) + # no page rendered @mastodon_request_included @@ -57,7 +82,8 @@ def OAuth2_login(request): except ObjectDoesNotExist: return HttpResponseBadRequest("Mastodon site not registered") if token: - # oauth is completed when token aquired + if request.session.get('swap_login', False) and request.user.is_authenticated: # swap login for existing user + return swap_login(request, token, site) user = authenticate(request, token=token, site=site) if user: auth_login(request, user, token) @@ -113,7 +139,8 @@ def login(request): def connect(request): if not settings.MASTODON_ALLOW_ANY_SITE: return redirect(reverse("users:login")) - login_domain = request.GET.get('domain').strip().lower().split('//')[-1].split('/')[0].split('@')[-1] + login_domain = request.session['swap_domain'] if request.session.get('swap_login') else request.GET.get('domain') + login_domain = login_domain.strip().lower().split('//')[-1].split('/')[0].split('@')[-1] domain = get_instance_domain(login_domain) app = MastodonApplication.objects.filter(domain_name=domain).first() if app is None: @@ -151,6 +178,18 @@ def connect(request): resp.set_cookie("mastodon_domain", domain) return resp + +@mastodon_request_included +@login_required +def reconnect(request): + if request.method == 'POST': + request.session['swap_login'] = True + request.session['swap_domain'] = request.POST['domain'] + return connect(request) + else: + return HttpResponseBadRequest() + + @mastodon_request_included @login_required def logout(request):