From a26784cd98c33d62330816eec64185fde253cd96 Mon Sep 17 00:00:00 2001 From: Arthur-TRT Date: Tue, 29 Mar 2022 11:02:07 +0200 Subject: [PATCH] First version of 42Oauth --- .../migrations/0008_auto_20220329_1034.py | 23 +++++++ src/accounts/models.py | 2 + src/accounts/templates/accounts/edit.html | 17 ++++- src/accounts/urls.py | 9 ++- src/accounts/views/connection.py | 66 ++++++++++++++++--- src/ctfs/templates/challenges | 2 +- 6 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 src/accounts/migrations/0008_auto_20220329_1034.py diff --git a/src/accounts/migrations/0008_auto_20220329_1034.py b/src/accounts/migrations/0008_auto_20220329_1034.py new file mode 100644 index 0000000..0578d14 --- /dev/null +++ b/src/accounts/migrations/0008_auto_20220329_1034.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.11 on 2022-03-29 08:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0007_auto_20220123_1704'), + ] + + operations = [ + migrations.AddField( + model_name='userprofileinfo', + name='intra42_campus', + field=models.CharField(blank=True, max_length=50, null=True), + ), + migrations.AddField( + model_name='userprofileinfo', + name='intra42_id', + field=models.CharField(blank=True, max_length=20, null=True, unique=True), + ), + ] diff --git a/src/accounts/models.py b/src/accounts/models.py index b82988e..5f8a869 100644 --- a/src/accounts/models.py +++ b/src/accounts/models.py @@ -12,6 +12,8 @@ class UserProfileInfo(models.Model): last_submission_date = models.DateTimeField('Last Submission Date', default=timezone.now) token = models.CharField(max_length=200, blank=True) discord_id = models.CharField(max_length=20, null=True, blank=True, unique=True) + intra42_id = models.CharField(max_length=20, null=True, blank=True, unique=True) + intra42_campus = models.CharField(max_length=50, null=True, blank=True) member = models.BooleanField(default=False) member_since = models.DateTimeField('Member since', default=timezone.now) member_until = models.DateTimeField('Member until', default=timezone.now) diff --git a/src/accounts/templates/accounts/edit.html b/src/accounts/templates/accounts/edit.html index 0e1c474..2af6d04 100644 --- a/src/accounts/templates/accounts/edit.html +++ b/src/accounts/templates/accounts/edit.html @@ -60,6 +60,21 @@ {% endif %} +
+ {% if user.userprofileinfo.intra42_id|length > 0 %} +
+ {%csrf_token%} + +
+ {% else %} +
+ {%csrf_token%} + +
+ {% endif %} +
@@ -87,4 +102,4 @@ -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/src/accounts/urls.py b/src/accounts/urls.py index abf5ec9..47c07e3 100644 --- a/src/accounts/urls.py +++ b/src/accounts/urls.py @@ -10,8 +10,11 @@ urlpatterns = [ path('edit/', views.edit, name='edit'), path('logout/', views.out, name='out'), path('rank/', views.rank, name='rank'), - path('connections/connect/discord', views.connection.connect, name='connections-connect-discord'), - path('connections/connect/discord/authorize', views.connection.authorize, name='connections-connect-discord-authorize'), - path('connections/disconnect/discord', views.connection.disconnect, name='connections-disconnect-discord'), + path('connections/connect/discord', views.connection.connect_discord, name='connections-connect-discord'), + path('connections/connect/discord/authorize', views.connection.authorize_discord, name='connections-connect-discord-authorize'), + path('connections/disconnect/discord', views.connection.disconnect_discord, name='connections-disconnect-discord'), + path('connections/connect/intra42', views.connection.connect_intra42, name='connections-connect-intra42'), + path('connections/connect/intra42/authorize', views.connection.authorize_intra42, name='connections-connect-intra42-authorize'), + path('connections/disconnect/intra42', views.connection.disconnect_intra42, name='connections-disconnect-intra42'), path('delete_account/', views.delete_account, name='delete_account'), ] diff --git a/src/accounts/views/connection.py b/src/accounts/views/connection.py index 1dc3642..624ed85 100644 --- a/src/accounts/views/connection.py +++ b/src/accounts/views/connection.py @@ -7,9 +7,12 @@ from django.shortcuts import redirect from django.contrib.sites.models import Site import os -oauth = OAuth() +from local_settings import API42_SECRET, API42_UID -oauth.register( +oauth_discord = OAuth() +oauth_intra42 = OAuth() + +oauth_discord.register( name='discord', client_id=os.getenv('OAUTH2_DISCORD_CLIENT_ID'), client_secret=os.getenv('OAUTH2_DISCORD_CLIENT_SECRET'), @@ -19,26 +22,73 @@ oauth.register( api_base_url='https://discord.com/api/' ) +oauth_intra42.register( + name='intra42', + client_id=API42_UID, + client_secret=API42_SECRET, + access_token_url='https://api.intra.42.fr/oauth/token', + authorize_url='https://api.intra.42.fr/oauth/authorize', + #client_kwargs={'scope': 'identify'}, + api_base_url='https://api.intra.42.fr/' +) + @login_required @require_POST -def connect(request): +def connect_intra42(request): + if request.user.userprofileinfo.intra42_id: + return bad_request(request, "Already connected") + site = Site.objects.get_current() + redirect_uri = reverse('accounts:connections-connect-intra42-authorize') + redirect_uri = "https://" + site.domain + redirect_uri[3:] # remove language code + print(redirect_uri) + return oauth_intra42.intra42.authorize_redirect(request, redirect_uri) + +@login_required +def authorize_intra42(request): + if request.user.userprofileinfo.intra42_id: + return bad_request(request, "Already connected") + try: + token = oauth_intra42.intra42.authorize_access_token(request) + except: + return redirect('accounts:edit') + response = oauth_intra42.intra42.get('v2/me', token=token) + response = response.json() + intra42_id = response['id'] + request.user.userprofileinfo.intra42_id = intra42_id + request.user.userprofileinfo.save() + return redirect('accounts:edit') + +@login_required +@require_POST +def disconnect_intra42(request): + if not request.user.userprofileinfo.intra42_id: + return bad_request(request, "Already disconnected") + request.user.userprofileinfo.intra42_id = None + request.user.userprofileinfo.intra42_campus = None + request.user.userprofileinfo.save() + return redirect('accounts:edit') + + +@login_required +@require_POST +def connect_discord(request): if request.user.userprofileinfo.discord_id: return bad_request(request, "Already connected") site = Site.objects.get_current() redirect_uri = reverse('accounts:connections-connect-discord-authorize') redirect_uri = "https://" + site.domain + redirect_uri[3:] # remove language code print(redirect_uri) - return oauth.discord.authorize_redirect(request, redirect_uri) + return oauth_discord.discord.authorize_redirect(request, redirect_uri) @login_required -def authorize(request): +def authorize_discord(request): if request.user.userprofileinfo.discord_id: return bad_request(request, "Already connected") try: - token = oauth.discord.authorize_access_token(request) + token = oauth_discord.discord.authorize_access_token(request) except: return redirect('accounts:edit') - response = oauth.discord.get('users/@me', token=token) + response = oauth_discord.discord.get('users/@me', token=token) response = response.json() discord_id = response['id'] request.user.userprofileinfo.discord_id = discord_id @@ -47,7 +97,7 @@ def authorize(request): @login_required @require_POST -def disconnect(request): +def disconnect_discord(request): if not request.user.userprofileinfo.discord_id: return bad_request(request, "Already disconnected") request.user.userprofileinfo.discord_id = None diff --git a/src/ctfs/templates/challenges b/src/ctfs/templates/challenges index 18fac39..5c7b599 160000 --- a/src/ctfs/templates/challenges +++ b/src/ctfs/templates/challenges @@ -1 +1 @@ -Subproject commit 18fac3978d21dc824bcffa2bc960aa2bf6b4abd9 +Subproject commit 5c7b5995fe12c0ed1bb10f97e56ec89377c98b54