Skip to content

Commit

Permalink
google OIDC. Auth refactoring (#6)
Browse files Browse the repository at this point in the history
* google oAuth2 integration
  • Loading branch information
bandirom authored Apr 15, 2024
1 parent 0b4ccbc commit 20cbf48
Show file tree
Hide file tree
Showing 81 changed files with 1,155 additions and 442 deletions.
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ concurrency:


jobs:

build:
name: "Build dev image"
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ redis-*.tgz
db.sqlite3
.secrets.env
*.spec
.secrets.env
71 changes: 49 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,37 @@
* Swagger in Django Admin Panel
* Ready for deploy by one click
* Separated configuration for dev and prod (requirements and settings)
* CI/CD: GitHub Actions/GitlabCI
* CI/CD: GitHub Actions
* Redefined default User model (main.models.py)
* MailHog, Jaeger, RabbitMQ integrations
* Mailpit, Jaeger, RabbitMQ integrations
* Multi-stage build for prod versions
* PostgreSql Backup

### How to use:

#### Clone the repo or click "Use this template" button:

git clone https://github.com/bandirom/django-blog.git

```shell
git clone https://github.com/bandirom/django-blog.git
```


#### Before running add your superuser email/password and project name in docker/prod/env/.data.env file

[email protected]
SUPERUSER_PASSWORD=secretp@ssword
PROJECT_TITLE=MyProject
```dotenv
[email protected]
SUPERUSER_PASSWORD=secretp@ssword
PROJECT_TITLE=MyProject
```

#### Run the local develop server:

docker-compose up -d --build
docker-compose logs -f
```shell
docker-compose up -d --build
docker-compose logs -f
```

##### Server will bind 8000 port. You can get access to server by browser [http://localhost:8008](http://localhost:8008)
##### Server will run on 8000 port. You can get access to server by browser [http://localhost:8000](http://localhost:8000)

Run django commands through exec:
```shell
Expand All @@ -47,21 +53,40 @@ docker-compose exec web python manage.py makemigrations
docker-compose exec web python manage.py shell
```

##### For testing mail backend you can use MailHog service
docker-compose -f docker-compose.yml -f docker/modules/mailhog.yml up -d --build
Get access to the container
```shell
docker-compose exec web sh
```

##### For run mail smtp for local development you can use Mailpit service

* Run Mailpit
```shell
docker-compose -f docker/modules/mailpit.yml up -d
```

<b>Don't forget to set SMTP mail backend in settings</b>

```dotenv
# docker/dev/env/.email.env
EMAIL_HOST=mailpit_hostname
```
Where `mailpit_hostname` is
* `docker.host.internal` for Window and macOS
* `gateway-host` for Linux OS

---

### Production environment

If your server under LoadBalancer with SSL/TLS certificate you could run simple `prod.yml` configuration

docker-compose -f prod.yml up -d --build
If your server under LoadBalancer or nginx with SSL/TLS certificate you can run `prod.yml` configuration

```shell
docker-compose -f prod.yml up -d --build
```

#### For set https connection you should have a domain name
<b> In prod.certbot.yml: </b>
**In prod.certbot.yml:**

Change the envs:
CERTBOT_EMAIL: your real email
Expand All @@ -70,10 +95,12 @@ Change the envs:

To set https for 2 and more nginx servers:

ENVSUBST_VARS: API UI
API: api.domain.com
UI: domain.com

Run command:
```dotenv
ENVSUBST_VARS: API
API: api.your-domain.com
```

docker-compose -f prod.yml -f prod.certbot.yml up -d --build
Run command:
```shell
docker-compose -f prod.yml -f prod.certbot.yml up -d --build
```
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ services:
- redis_data:/data
networks:
- separated_network
logging:
driver: none
healthcheck:
test: [ "CMD", "redis-cli","ping" ]
interval: 1m20s
Expand Down
3 changes: 1 addition & 2 deletions docker/dev/env/.email.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
EMAIL_HOST=gateway-host
EMAIL_HOST=host.docker.internal
EMAIL_PORT=1025
EMAIL_USE_TLS=0
EMAIL_USE_SSL=0
DEFAULT_FROM_EMAIL="Localhost <[email protected]>"
EMAIL_HOST_USER
EMAIL_HOST_PASSWORD
EMAIL_BACKEND=smtp
6 changes: 3 additions & 3 deletions docker/dev/env/.env
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ HEALTH_CHECK_URL=/application/health/
ENABLE_SILK=1
ENABLE_DEBUG_TOOLBAR=0
ENABLE_SENTRY=0
FRONTEND_URL=http://192.168.59.111:8008
BACKEND_URL=http://192.168.59.111:8008
FRONTEND_URL=http://localhost:8008
BACKEND_URL=http://localhost:8008

CHAT_PROXY=http://192.168.59.111:8005/init/
CHAT_PROXY=http://localhost:8005/init/
9 changes: 0 additions & 9 deletions docker/modules/mailhog.yml

This file was deleted.

15 changes: 15 additions & 0 deletions docker/modules/mailpit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SMTP Server for mail testing

services:
mailpit:
image: axllent/mailpit
restart: unless-stopped
ports:
- target: 1025
published: 1025
protocol: tcp
mode: host
- target: 8025
published: 8025
protocol: tcp
mode: host
8 changes: 0 additions & 8 deletions docker/prod/env/.email.env

This file was deleted.

8 changes: 8 additions & 0 deletions docker/prod/env/.env
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,11 @@ FRONTEND_URL=https://blog.jollymanager.com
BACKEND_URL=https://blog.jollymanager.com
CHAT_PROXY=https://chat.jollymanager.com/init/
JWT_COOKIE_DOMAIN=.jollymanager.com

EMAIL_HOST
EMAIL_PORT
EMAIL_USE_TLS=0
EMAIL_USE_SSL=0
DEFAULT_FROM_EMAIL
EMAIL_HOST_USER
EMAIL_HOST_PASSWORD
6 changes: 0 additions & 6 deletions prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ x-variables: &variables

services:
blog:
build:
context: .
dockerfile: docker/prod/web/Dockerfile
image: bandirom/blog:${APP_VERSION:-latest}
volumes:
- redis_socket:/redis_socket
Expand Down Expand Up @@ -33,9 +30,6 @@ services:
extra_hosts:
- "gateway-host:172.17.0.1"
celery:
build:
context: .
dockerfile: docker/prod/web/Dockerfile
image: bandirom/blog:${APP_VERSION:-latest}
entrypoint: ""
command: celery -A src worker --beat -l info
Expand Down
File renamed without changes.
72 changes: 72 additions & 0 deletions web/api/email_service/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Optional, TypedDict

from django.contrib.auth import get_user_model
from django.utils.translation import get_language

from main.tasks import send_information_email

if TYPE_CHECKING:
from main.models import UserType


User: 'UserType' = get_user_model()


class EmailSendData(TypedDict):
subject: str
template_name: str
language: str
to_email: str
context: dict
from_email: Optional[str]
file_path_attachments: Optional[str]


class BaseEmailService(ABC):
def __init__(self, user: Optional[User] = None, language: Optional[str] = None, from_email: Optional[str] = None):
self._user = user
self._locale: str = language or get_language()
self.from_email = from_email

@property
def locale(self) -> str:
return self._locale

@property
def user(self) -> User:
assert self._user, 'User object were not provided'
return self._user

@property
@abstractmethod
def template_name(self) -> str:
"""Template email path"""

@property
def to_email(self) -> str:
return self.user.email

def email_context(self, **kwargs) -> dict:
"""Provide dict with data for email template rendering"""
return {}

@property
@abstractmethod
def email_subject(self) -> str:
"""Provide email subject"""

def get_email_data(self, **kwargs) -> EmailSendData:
return {
'subject': self.email_subject,
'template_name': self.template_name,
'language': self.locale,
'to_email': self.to_email,
'context': self.email_context(**kwargs),
'from_email': self.from_email,
'file_path_attachments': None,
}

def send_email(self, **kwargs):
kwargs: dict = self.get_email_data(**kwargs)
return send_information_email.apply_async(kwargs=kwargs)
18 changes: 18 additions & 0 deletions web/api/email_service/password_reset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from django.conf import settings
from django.utils.translation import gettext_lazy as _

from api.email_service.base import BaseEmailService


class PasswordResetService(BaseEmailService):
template_name = 'emails/password_reset.html'

@property
def email_subject(self) -> str:
return _('Blog password reset')

def email_context(self, reset_url: str, **kwargs) -> dict:
return {
'full_name': self.user.full_name,
'reset_url': reset_url,
}
17 changes: 17 additions & 0 deletions web/api/email_service/sign_up.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.utils.translation import gettext_lazy as _

from api.email_service.base import BaseEmailService


class SignUpEmailService(BaseEmailService):
template_name = 'emails/verify_email.html'

@property
def email_subject(self) -> str:
return _('Blog register confirmation email')

def email_context(self, activate_url: str, **kwargs) -> dict:
return {
'full_name': self.user.full_name,
'activate_url': activate_url,
}
38 changes: 0 additions & 38 deletions web/api/email_services.py

This file was deleted.

2 changes: 0 additions & 2 deletions web/api/v1/actions/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ class FollowSerializer(serializers.Serializer):


class UserFollowSerializer(serializers.ModelSerializer):
"""For list of user following and followers"""

profile_url = serializers.URLField(source='get_absolute_url')

follow = serializers.BooleanField()
Expand Down
Loading

0 comments on commit 20cbf48

Please sign in to comment.