mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2024-11-24 19:23:44 +03:00
added oauth, health checks, new blog and user features
This commit is contained in:
parent
bf8e191a65
commit
9b2cf1656b
17
akarpov/blog/migrations/0002_alter_comment_options.py
Normal file
17
akarpov/blog/migrations/0002_alter_comment_options.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 4.0.8 on 2022-11-23 09:23
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('blog', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='comment',
|
||||
options={'ordering': ['-rating', '-created']},
|
||||
),
|
||||
]
|
|
@ -98,7 +98,7 @@ def __str__(self):
|
|||
return f"{self.author.username}'s comment on {self.post.title}"
|
||||
|
||||
class Meta:
|
||||
ordering = ["-rating"]
|
||||
ordering = ["-rating", "-created"]
|
||||
|
||||
|
||||
class CommentRating(models.Model):
|
||||
|
|
|
@ -19,7 +19,14 @@ def post_on_save(sender, instance: Post, **kwargs):
|
|||
{"image_cropped"}
|
||||
):
|
||||
if instance.image:
|
||||
crop_model_image.delay(instance.pk, "blog", "Post")
|
||||
crop_model_image.apply_async(
|
||||
kwargs={
|
||||
"pk": instance.pk,
|
||||
"app_label": "blog",
|
||||
"model_name": "Post",
|
||||
},
|
||||
countdown=10,
|
||||
)
|
||||
else:
|
||||
instance.image_cropped = None
|
||||
instance.save()
|
||||
|
@ -74,4 +81,11 @@ def post_rating_delete(sender, instance: PostRating, **kwargs):
|
|||
def post_on_create(sender, instance: Post, created, **kwargs):
|
||||
if created:
|
||||
if instance.image:
|
||||
crop_model_image.delay(instance.pk, "blog", "Post")
|
||||
crop_model_image.apply_async(
|
||||
kwargs={
|
||||
"pk": instance.pk,
|
||||
"app_label": "blog",
|
||||
"model_name": "Post",
|
||||
},
|
||||
countdown=10,
|
||||
)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
{% load i18n %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load socialaccount %}
|
||||
|
||||
{% block head_title %}{% translate "Signup" %}{% endblock %}
|
||||
|
||||
|
@ -16,6 +17,9 @@
|
|||
{% if redirect_field_value %}
|
||||
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
|
||||
{% endif %}
|
||||
<div class="row mb-2">
|
||||
<a href="{% provider_login_url 'github' %}"><i class="bi bi-github btn"></i></a>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="submit">{% translate "Sign Up" %} »</button>
|
||||
</form>
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
{% csrf_token %}
|
||||
<div>
|
||||
<label for="textarea" class="form-label">write your comments</label>
|
||||
<textarea name="body" class="form-control" id="textarea" rows="3"></textarea>
|
||||
<textarea name="body" maxlength="100" class="form-control" id="textarea" rows="3"></textarea>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-secondary mt-2" type="submit">Send</button>
|
||||
</form>
|
||||
|
@ -95,7 +95,7 @@
|
|||
<p class="mb-1">
|
||||
{{ comment.author.username }} <span class="small">- {{ comment.created | naturaltime }}</span>
|
||||
</p>
|
||||
<button class="btn btn-outline-primary"><i class="bi bi-reply"></i><span class="small"> reply</span></button>
|
||||
<!--<button class="btn btn-outline-primary"><i class="bi bi-reply"></i><span class="small"> reply</span></button> -->
|
||||
</div>
|
||||
<p class="small mb-0">
|
||||
{{ comment.body }}
|
||||
|
|
21
akarpov/templates/socialaccount/login.html
Normal file
21
akarpov/templates/socialaccount/login.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block head_title %}{% trans "Sign In" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if process == "connect" %}
|
||||
<h1>{% blocktrans with provider.name as provider %}Connect {{ provider }}{% endblocktrans %}</h1>
|
||||
|
||||
<p>{% blocktrans with provider.name as provider %}You are about to connect a new third party account from {{ provider }}.{% endblocktrans %}</p>
|
||||
{% else %}
|
||||
<h1>{% blocktrans with provider.name as provider %}Sign In Via {{ provider }}{% endblocktrans %}</h1>
|
||||
|
||||
<p>{% blocktrans with provider.name as provider %}You are about to sign in using a third party account from {{ provider }}.{% endblocktrans %}</p>
|
||||
{% endif %}
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<button class="btn btn-success" type="submit">{% trans "Continue" %}</button>
|
||||
</form>
|
||||
{% endblock %}
|
52
akarpov/templates/socialaccount/providers/connections.html
Normal file
52
akarpov/templates/socialaccount/providers/connections.html
Normal file
|
@ -0,0 +1,52 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block head_title %}{% trans "Account Connections" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{% trans "Account Connections" %}</h1>
|
||||
|
||||
{% if form.accounts %}
|
||||
<p>{% blocktrans %}You can sign in to your account using any of the following third party accounts:{% endblocktrans %}</p>
|
||||
|
||||
|
||||
<form method="post" action="{% url 'socialaccount_connections' %}">
|
||||
{% csrf_token %}
|
||||
|
||||
<fieldset>
|
||||
{% if form.non_field_errors %}
|
||||
<div id="errorMsg">{{ form.non_field_errors }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% for base_account in form.accounts %}
|
||||
{% with base_account.get_provider_account as account %}
|
||||
<div>
|
||||
<label for="id_account_{{ base_account.id }}">
|
||||
<input id="id_account_{{ base_account.id }}" type="radio" name="account" value="{{ base_account.id }}"/>
|
||||
<span class="socialaccount_provider {{ base_account.provider }} {{ account.get_brand.id }}">{{account.get_brand.name}}</span>
|
||||
{{ account }}
|
||||
</label>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
|
||||
<div>
|
||||
<button type="submit">{% trans 'Remove' %}</button>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
|
||||
</form>
|
||||
|
||||
{% else %}
|
||||
<p>{% trans 'You currently have no social network accounts connected to this account.' %}</p>
|
||||
{% endif %}
|
||||
|
||||
<h2>{% trans 'Add a 3rd Party Account' %}</h2>
|
||||
|
||||
<ul class="socialaccount_providers">
|
||||
{% include "socialaccount/snippets/provider_list.html" with process="connect" %}
|
||||
</ul>
|
||||
|
||||
{% include "socialaccount/snippets/login_extra.html" %}
|
||||
|
||||
{% endblock %}
|
21
akarpov/templates/socialaccount/snippets/provider_list.html
Normal file
21
akarpov/templates/socialaccount/snippets/provider_list.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
{% load socialaccount %}
|
||||
|
||||
{% get_providers as socialaccount_providers %}
|
||||
|
||||
{% for provider in socialaccount_providers %}
|
||||
{% if provider.id == "openid" %}
|
||||
{% for brand in provider.get_brands %}
|
||||
<li>
|
||||
<a title="{{brand.name | lower}}"
|
||||
class="socialaccount_provider {{provider.id}} {{brand.id}}"
|
||||
href="{% provider_login_url provider.id openid=brand.openid_url process=process %}"
|
||||
><i class="bi bi-{{ brand.name }}"></i>{{brand.name}}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<li>
|
||||
<i class="bi bi-{{provider.name | lower}}"></i>
|
||||
<a title="{{provider.name}}" class="socialaccount_provider {{provider.id}}"
|
||||
href="{% provider_login_url provider.id process=process scope=scope auth_params=auth_params %}">{{provider.name}}</a>
|
||||
</li>
|
||||
{% endfor %}
|
|
@ -35,10 +35,20 @@
|
|||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'users:update' %}">
|
||||
<a href="{% url 'account_email' %}">
|
||||
<i class="bi bi-envelope"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'account_reset_password' %}">
|
||||
<i class="bi bi-key"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'socialaccount_connections' %}">
|
||||
<i class="bi bi-person-add"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
|
|
@ -15,7 +15,14 @@ def on_change(sender, instance: User, **kwargs):
|
|||
{"image_cropped"}
|
||||
):
|
||||
if instance.image:
|
||||
crop_model_image.delay(instance.pk, "users", "User")
|
||||
crop_model_image.apply_async(
|
||||
kwargs={
|
||||
"pk": instance.pk,
|
||||
"app_label": "users",
|
||||
"model_name": "User",
|
||||
},
|
||||
countdown=10,
|
||||
)
|
||||
else:
|
||||
instance.image_cropped = None
|
||||
instance.save()
|
||||
|
@ -25,4 +32,12 @@ def on_change(sender, instance: User, **kwargs):
|
|||
def post_on_create(sender, instance: User, created, **kwargs):
|
||||
if created:
|
||||
if instance.image:
|
||||
crop_model_image.delay(instance.pk, "users", "User")
|
||||
if instance.image:
|
||||
crop_model_image.apply_async(
|
||||
kwargs={
|
||||
"pk": instance.pk,
|
||||
"app_label": "users",
|
||||
"model_name": "User",
|
||||
},
|
||||
countdown=10,
|
||||
)
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
"django.contrib.admin",
|
||||
"django.forms",
|
||||
]
|
||||
|
||||
THIRD_PARTY_APPS = [
|
||||
"crispy_forms",
|
||||
"crispy_bootstrap5",
|
||||
|
@ -82,13 +83,34 @@
|
|||
"colorfield",
|
||||
]
|
||||
|
||||
HEALTH_CHECKS = [
|
||||
"health_check", # required
|
||||
"health_check.db", # stock Django health checkers
|
||||
"health_check.cache",
|
||||
"health_check.storage",
|
||||
"health_check.contrib.celery",
|
||||
"health_check.contrib.celery_ping",
|
||||
"health_check.contrib.migrations",
|
||||
"health_check.contrib.psutil", # disk and memory utilization
|
||||
"health_check.contrib.redis",
|
||||
]
|
||||
|
||||
ALL_AUTH_PROVIDERS = [
|
||||
"allauth.socialaccount.providers.github",
|
||||
# "allauth.socialaccount.providers.google",
|
||||
# "allauth.socialaccount.providers.telegram",
|
||||
# "allauth.socialaccount.providers.yandex",
|
||||
]
|
||||
|
||||
LOCAL_APPS = [
|
||||
"akarpov.users",
|
||||
"akarpov.blog",
|
||||
# Your stuff: custom apps go here
|
||||
]
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
|
||||
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
|
||||
INSTALLED_APPS = (
|
||||
DJANGO_APPS + THIRD_PARTY_APPS + HEALTH_CHECKS + ALL_AUTH_PROVIDERS + LOCAL_APPS
|
||||
)
|
||||
|
||||
# MIGRATIONS
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -284,6 +306,7 @@
|
|||
CELERY_TASK_SOFT_TIME_LIMIT = 60
|
||||
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#beat-scheduler
|
||||
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"
|
||||
|
||||
# django-allauth
|
||||
# ------------------------------------------------------------------------------
|
||||
ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", True)
|
||||
|
@ -291,6 +314,9 @@
|
|||
ACCOUNT_AUTHENTICATION_METHOD = "username"
|
||||
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||
ACCOUNT_EMAIL_REQUIRED = True
|
||||
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True
|
||||
ACCOUNT_LOGIN_ON_PASSWORD_RESET = True
|
||||
SOCIALACCOUNT_EMAIL_VERIFICATION = False
|
||||
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
||||
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||
|
@ -301,6 +327,23 @@
|
|||
SOCIALACCOUNT_ADAPTER = "akarpov.users.adapters.SocialAccountAdapter"
|
||||
# https://django-allauth.readthedocs.io/en/latest/forms.html
|
||||
SOCIALACCOUNT_FORMS = {"signup": "akarpov.users.forms.UserSocialSignupForm"}
|
||||
SOCIALACCOUNT_PROVIDERS = {
|
||||
"github": {
|
||||
"SCOPE": [
|
||||
"user",
|
||||
"read:org",
|
||||
],
|
||||
},
|
||||
"google": {
|
||||
"SCOPE": [
|
||||
"profile",
|
||||
"email",
|
||||
],
|
||||
"AUTH_PARAMS": {
|
||||
"access_type": "online",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# django-rest-framework
|
||||
# -------------------------------------------------------------------------------
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
path(
|
||||
"about/", TemplateView.as_view(template_name="pages/about.html"), name="about"
|
||||
),
|
||||
path("health/", include("health_check.urls")),
|
||||
# Django Admin, use {% url 'admin:index' %}
|
||||
path(settings.ADMIN_URL, admin.site.urls),
|
||||
# User management
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pytz==2022.6 # https://github.com/stub42/pytz
|
||||
psutil==5.9.4
|
||||
python-slugify==6.1.2 # https://github.com/un33k/python-slugify
|
||||
Pillow==9.3.0 # https://github.com/python-pillow/Pillow
|
||||
argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi
|
||||
|
@ -12,6 +13,7 @@ flower==1.2.0 # https://github.com/mher/flower
|
|||
# Django
|
||||
# ------------------------------------------------------------------------------
|
||||
django==4.0.8 # pyup: < 4.1 # https://www.djangoproject.com/
|
||||
django-health-check==3.17.0
|
||||
django-environ==0.9.0 # https://github.com/joke2k/django-environ
|
||||
django-model-utils==4.2.0 # https://github.com/jazzband/django-model-utils
|
||||
django-allauth==0.51.0 # https://github.com/pennersr/django-allauth
|
||||
|
|
Loading…
Reference in New Issue
Block a user