added oauth, made users work!

This commit is contained in:
Rushil Umaretiya 2020-08-15 04:01:49 -04:00
parent 00bc85a64f
commit 623516ffbe
15 changed files with 333 additions and 7 deletions

View File

@ -28,16 +28,64 @@ DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = []
# Auth Backends
AUTHENTICATION_BACKENDS = (
'social_core.backends.github.GithubOAuth2',
'social_core.backends.twitter.TwitterOAuth',
'social_core.backends.facebook.FacebookOAuth2',
'social_core.backends.google.GoogleOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
# Google
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '276763390631-57q8fea2cuubpit2cobm0nnp5kn9c9uh.apps.googleusercontent.com'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 'zFaVWK5rFfPJSKEVAtTylUTQ'
# Twitter
# Github
SOCIAL_AUTH_GITHUB_KEY = "364c7ecdda1e3a1a264d"
SOCIAL_AUTH_GITHUB_SECRET = "1703d5f908e72e38b1968a02f2cce1702f29aa01"
# Facebook
SOCIAL_AUTH_FACEBOOK_KEY = "759711064826583"
SOCIAL_AUTH_FACEBOOK_SECRET = "649724ff5b05d25c747df28152e700b4"
# Social Auth
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.get_username',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
)
SOCIAL_AUTH_STRATEGY = 'social_django.strategy.DjangoStrategy'
SOCIAL_AUTH_STORAGE = 'social_django.models.DjangoStorage'
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
'news.apps.NewsConfig', 'news.apps.NewsConfig',
'users.apps.UsersConfig',
'crispy_forms',
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'social_django',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -48,6 +96,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'social_django.middleware.SocialAuthExceptionMiddleware',
] ]
ROOT_URLCONF = 'config.urls' ROOT_URLCONF = 'config.urls'
@ -63,6 +112,8 @@ TEMPLATES = [
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
'social_django.context_processors.backends',
'social_django.context_processors.login_redirect',
], ],
}, },
}, },
@ -106,7 +157,7 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC' TIME_ZONE = 'America/New_York'
USE_I18N = True USE_I18N = True
@ -119,3 +170,12 @@ USE_TZ = True
# https://docs.djangoproject.com/en/3.0/howto/static-files/ # https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/' STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
CRISPY_TEMPLATE_PACK = 'bootstrap4'
LOGIN_URL = 'login'
LOGOUT_URL = 'logout'
LOGIN_REDIRECT_URL = 'home'

View File

@ -13,11 +13,29 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path 1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.conf.urls import url
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from django.contrib.auth import views as auth_views
from users import views as user_views
urlpatterns = [ urlpatterns = [
path('', include('news.urls')),
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('register/', user_views.register, name='register'),
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('oauth/', include('social_django.urls', namespace='social')),
path('', include('news.urls')),
] ]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -36,10 +36,10 @@
<div class="navbar-nav"> <div class="navbar-nav">
{% if user.is_authenticated %} {% if user.is_authenticated %}
<a class="nav-item nav-link" href="">New Chirp</a> <a class="nav-item nav-link" href="">New Chirp</a>
<a class="nav-item nav-link" href="">{{ user.username }}</a> <a class="nav-item nav-link" href="{% url 'profile' %}">{{ user.username }}</a>
<a class="nav-item nav-link" href="">Logout</a> <a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>
{% else %} {% else %}
<a class="nav-item nav-link" href="">Login</a> <a class="nav-item nav-link" href="{% url 'login' %}">Login</a>
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -47,6 +47,8 @@
</nav> </nav>
</header> </header>
<img src="{% static 'news/css/res/image.png' %}" alt="">
<main role="main" class="container"> <main role="main" class="container">
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">

View File

@ -1,3 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import Profile
# Register your models here. # Register your models here.
admin.site.register(Profile)

26
users/forms.py Normal file
View File

@ -0,0 +1,26 @@
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email']
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['profile_pic']

View File

@ -0,0 +1,25 @@
# Generated by Django 3.1 on 2020-08-15 06:28
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('image', models.ImageField(default='default.jpg', upload_to='profile_pics')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1 on 2020-08-15 07:00
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.RenameField(
model_name='profile',
old_name='image',
new_name='pfp',
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1 on 2020-08-15 07:02
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('users', '0002_auto_20200815_0300'),
]
operations = [
migrations.RenameField(
model_name='profile',
old_name='pfp',
new_name='profile_pic',
),
]

View File

@ -1,3 +1,25 @@
from django.db import models from django.db import models
# Create your models here. # Create your models here.
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.profile_pic.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.profile_pic.path)

13
users/signals.py Normal file
View File

@ -0,0 +1,13 @@
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()

View File

@ -0,0 +1,28 @@
{% extends "news/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Log In</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Login</button>
<small class="text-muted ml-2">
<a href="">Forgot Password?</a>
</small>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted">
Need An Account? <a class="ml-2" href="{% url 'register' %}">Sign Up Now</a>
</small>
</div>
</div>
<a href="{% url 'social:begin' 'google-oauth2' %}">Login with Google</a>
<a href="{% url 'social:begin' 'github' %}">Login with GitHub</a><br>
<a href="{% url 'social:begin' 'facebook' %}">Login with Facebook</a>
{% endblock content %}

View File

@ -0,0 +1,9 @@
{% extends "news/base.html" %}
{% block content %}
<h2>You have been logged out</h2>
<div class="border-top pt-2">
<small class="text-muted text-large">
<a href="{% url 'login' %}">Log In Again</a>
</small>
</div>
{% endblock content %}

View File

@ -0,0 +1,25 @@
{% extends "news/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ user.profile.profile_pic.url }}">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">{{ user.email }}</p>
</div>
</div>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4"> Your profile </legend>
{{ userForm|crispy}}
{{ profileForm|crispy }}
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-outline-info">Update</button>
</div>
</form>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,22 @@
{% extends "news/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Join Today</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Sign Up</button>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted">
Already Have An Account? <a class="ml-2" href="{% url 'login' %}">Sign In</a>
</small>
</div>
</div>
{% endblock content %}
© 2020 GitHub, Inc.

View File

@ -1,3 +1,41 @@
from django.shortcuts import render from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
# Create your views here. def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
@login_required
def profile(request):
if request.method == "POST":
userForm = UserUpdateForm(request.POST, instance=request.user)
profileForm = ProfileUpdateForm(request.POST,
request.FILES,
instance=request.user.profile)
if userForm.is_valid() and profileForm.is_valid():
userForm.save()
profileForm.save()
messages.success(request, "Your account has been updated!")
return redirect('profile')
else:
userForm = UserUpdateForm(instance=request.user)
profileForm = ProfileUpdateForm(instance=request.user.profile)
context = {
'userForm': userForm,
'profileForm': profileForm
}
return render(request, 'users/profile.html', context)