diff --git a/config/settings.py b/config/settings.py index 5a79664..2ed6734 100644 --- a/config/settings.py +++ b/config/settings.py @@ -178,4 +178,4 @@ CRISPY_TEMPLATE_PACK = 'bootstrap4' LOGIN_URL = 'login' LOGOUT_URL = 'logout' -LOGIN_REDIRECT_URL = 'home' +LOGIN_REDIRECT_URL = 'profile' diff --git a/config/urls.py b/config/urls.py index b64b45e..f0c3811 100644 --- a/config/urls.py +++ b/config/urls.py @@ -30,6 +30,7 @@ urlpatterns = [ path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'), path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'), path('profile/', user_views.profile, name='profile'), + path('profile/password/', user_views.password, name='password'), path('oauth/', include('social_django.urls', namespace='social')), diff --git a/news/views.py b/news/views.py index afba160..287642e 100644 --- a/news/views.py +++ b/news/views.py @@ -1,4 +1,5 @@ from django.shortcuts import render +from users.models import Profile # Create your views here. @@ -6,4 +7,7 @@ def about (request): return render (request, 'news/about.html') def home (request): + if request.user.is_authenticated and Profile.objects.filter(user=request.user).count() < 1: + Profile.objects.create(user=request.user).save() + return render (request, 'news/home.html') diff --git a/users/signals.py b/users/signals.py index cb32c48..c0d507c 100644 --- a/users/signals.py +++ b/users/signals.py @@ -3,11 +3,17 @@ from django.contrib.auth.models import User from django.dispatch import receiver from .models import Profile +#from social_auth.signals import socialauth_registered + + @receiver(post_save, sender=User) def create_profile(sender, instance, created, **kwargs): if created: + print ("CREATED") Profile.objects.create(user=instance) + @receiver(post_save, sender=User) def save_profile(sender, instance, **kwargs): + print ("SAVED") instance.profile.save() diff --git a/users/templates/users/password.html b/users/templates/users/password.html new file mode 100644 index 0000000..2458c16 --- /dev/null +++ b/users/templates/users/password.html @@ -0,0 +1,13 @@ +{% extends 'news/base.html' %} +{% load crispy_forms_tags %} +{% block content %} + <h2>Change Password</h2> + {% if not user.has_usable_password %} + <p style="color: red">You have not defined a password yet.</p> + {% endif %} + <form method="post"> + {% csrf_token %} + {{ form|crispy }} + <button type="submit">Save changes</button> + </form> +{% endblock %} diff --git a/users/templates/users/profile.html b/users/templates/users/profile.html index ecbc3b1..503ee53 100644 --- a/users/templates/users/profile.html +++ b/users/templates/users/profile.html @@ -9,6 +9,58 @@ <p class="text-secondary">{{ user.email }}</p> </div> </div> + + <h2>Settings</h2> + + <h3>GitHub</h3> + {% if github_login %} + <p>Connected as <a href="https://github.com/{{ github_login.extra_data.login }}/" target="_blank">{{ github_login.extra_data.login }}</a></p> + {% if can_disconnect %} + <form method="post" action="{% url 'social:disconnect' 'github' %}"> + {% csrf_token %} + <button type="submit">Disconnect from GitHub</button> + </form> + {% else %} + <button type="button" disabled>Disconnect from GitHub</button> + <p style="color: red">You must <a href="{% url 'password' %}">define a password</a> for your account before disconnecting from Github.</p> + {% endif %} + {% else %} + <a href="{% url 'social:begin' 'github' %}">Connect to GitHub</a> + {% endif %} + + <h3>Google</h3> + {% if google_login %} + <p>Connected as <a href="https://google.com/{{ google_login.extra_data.access_token.screen_name }}/" target="_blank">@{{ google_login.extra_data.access_token.screen_name }}</a></p> + {% if can_disconnect %} + <form method="post" action="{% url 'social:disconnect' 'google-oauth2' %}"> + {% csrf_token %} + <button type="submit">Disconnect from Google</button> + </form> + {% else %} + <button type="button" disabled>Disconnect from Google</button> + <p style="color: red">You must <a href="{% url 'password' %}">define a password</a> for your account before disconnecting from Google.</p> + {% endif %} + {% else %} + <a href="{% url 'social:begin' 'google-oauth2' %}">Connect to Google</a> + {% endif %} + + <h3>Facebook</h3> + {% if facebook_login %} + <p>Connected as <a href="https://facebook.com/{{ facebook_login.extra_data.id }}/" target="_blank">{{ facebook_login.extra_data.id }}</a></p> + {% if can_disconnect %} + <form method="post" action="{% url 'social:disconnect' 'facebook' %}"> + {% csrf_token %} + <button type="submit">Disconnect from Facebook</button> + </form> + {% else %} + <button type="button" disabled>Disconnect from Facebook</button> + <p style="color: red">You must <a href="{% url 'password' %}">define a password</a> for your account before disconnecting from Facebook.</p> + {% endif %} + {% else %} + <a href="{% url 'social:begin' 'facebook' %}">Connect to Facebook</a> + {% endif %} + + <form method="post" enctype="multipart/form-data"> {% csrf_token %} <fieldset class="form-group"> diff --git a/users/views.py b/users/views.py index 73fbd06..4be60fd 100644 --- a/users/views.py +++ b/users/views.py @@ -1,8 +1,15 @@ from django.shortcuts import render, redirect from django.contrib import messages +from django.contrib.auth import update_session_auth_hash, login, authenticate from django.contrib.auth.decorators import login_required + +from django.contrib.auth.forms import AdminPasswordChangeForm, PasswordChangeForm, UserCreationForm from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm +from social_django.models import UserSocialAuth +from .models import Profile + + def register(request): if request.method == 'POST': form = UserRegisterForm(request.POST) @@ -18,6 +25,32 @@ def register(request): @login_required def profile(request): + + user = request.user + + if Profile.objects.filter(user=user).count() < 1: + Profile.objects.create(user=user).save() + + if user.has_usable_password() is False: + return redirect ('password') + + try: + github_login = user.social_auth.get(provider='github') + except UserSocialAuth.DoesNotExist: + github_login = None + + try: + google_login = user.social_auth.get(provider='google-oauth2') + except UserSocialAuth.DoesNotExist: + google_login = None + + try: + facebook_login = user.social_auth.get(provider='facebook') + except UserSocialAuth.DoesNotExist: + facebook_login = None + + can_disconnect = (user.social_auth.count() > 1 or user.has_usable_password()) + if request.method == "POST": userForm = UserUpdateForm(request.POST, instance=request.user) profileForm = ProfileUpdateForm(request.POST, @@ -35,7 +68,31 @@ def profile(request): context = { 'userForm': userForm, - 'profileForm': profileForm + 'profileForm': profileForm, + 'github_login': github_login, + 'google_login': google_login, + 'facebook_login': facebook_login, + 'can_disconnect': can_disconnect, } return render(request, 'users/profile.html', context) + +@login_required +def password(request): + if request.user.has_usable_password(): + PasswordForm = PasswordChangeForm + else: + PasswordForm = AdminPasswordChangeForm + + if request.method == 'POST': + form = PasswordForm(request.user, request.POST) + if form.is_valid(): + form.save() + update_session_auth_hash(request, form.user) + messages.success(request, 'Your password was successfully updated!') + return redirect('profile') + else: + messages.error(request, 'Please correct the error below.') + else: + form = PasswordForm(request.user) + return render(request, 'users/password.html', {'form': form})