Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
DEBUG=True

SECRET_KEY=""

DB_NAME=""
DB_USER=""
DB_PASSWORD=""
DB_HOST=""
DB_PORT=""


# Path to Flask application (root dir)
GOODMAP_BASE_DIR="/home/andrey/Workspace/Freelance/goodmap/"
# Path from Flask application (root dir) to JSON file
GOODMAP_PATH_TO_JSON="tests/e2e_tests/e2e_test_data.json"
# /home/andrey/Workspace/Freelance/goodmap/tests/e2e_tests/e2e_test_data.json
141 changes: 141 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Django #
*.log
*.pot
*.pyc
__pycache__
db.sqlite3
media

# Backup files #
*.bak

# If you are using PyCharm #
# User-specific stuff
.idea/


# AWS User-specific
.idea/**/aws.xml

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# File-based project format
*.iws

# IntelliJ
out/

# JIRA plugin
atlassian-ide-plugin.xml

# Python #
*.py[cod]
*$py.class

# Distribution / packaging
.Python build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib64/
parts/
sdist/
var/
wheels/
*.whl
*.egg-info/
.installed.cfg
*.egg
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
.pytest_cache/
nosetests.xml
coverage.xml
*.cover
.hypothesis/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery
celerybeat-schedule.*

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# mkdocs documentation
/site

# mypy
.mypy_cache/

# Sublime Text #
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
*.sublime-workspace
*.sublime-project

# sftp configuration file
sftp-config.json

# Package control specific files Package
Control.last-run
Control.ca-list
Control.ca-bundle
Control.system-ca-bundle
GitHub.sublime-settings

# Visual Studio Code #
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history


custom/migrations/*
authorization/migrations/*
configuration/migrations/*
locations/migrations/*
locations/views/locations.json
13 changes: 13 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
stages:
- merge

merge_dev_to_main:
stage: merge
only:
- dev
script:
- git config user.email "your_email@example.com"
- git config user.name "Your Name"
- git checkout main
- git merge --no-ff dev
- git push origin main
2 changes: 0 additions & 2 deletions README.md

This file was deleted.

Empty file added README.txt
Empty file.
Empty file added authorization/__init__.py
Empty file.
2 changes: 2 additions & 0 deletions authorization/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .permission_admin import *
from .custom_user_admin import *
23 changes: 23 additions & 0 deletions authorization/admin/custom_user_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from authorization.models.custom_user import CustomUser


@admin.register(CustomUser)
class CustomUserAdmin(UserAdmin):
model = CustomUser
list_display = ('email', 'first_name', 'last_name', 'role', 'is_staff', 'date_joined', 'last_login')
list_filter = ('is_staff', 'is_active', 'role')
fieldsets = (
(None, {'fields': ('email', 'password', 'first_name', 'last_name', 'role')}),
('Permissions', {'fields': ('is_staff', 'is_active')}),
('Important dates', {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'first_name', 'last_name', 'role', 'password1', 'password2', 'is_staff', 'is_active')}
),
)
search_fields = ('email', 'first_name', 'last_name')
ordering = ('email',)
8 changes: 8 additions & 0 deletions authorization/admin/permission_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.contrib import admin
from authorization.models import Permission


@admin.register(Permission)
class PermissionAdmin(admin.ModelAdmin):
list_display = ['name', 'codename']
fields = ['name']
6 changes: 6 additions & 0 deletions authorization/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class AuthorizationConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'authorization'
2 changes: 2 additions & 0 deletions authorization/forms/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .auth_form import *
from .role_form import *
21 changes: 21 additions & 0 deletions authorization/forms/auth_form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django import forms
from django.contrib.auth import authenticate
from django.contrib.auth.forms import AuthenticationForm
from django.utils.translation import gettext_lazy as _


class CustomAuthenticationForm(AuthenticationForm):
username = forms.EmailField(label=_("Email"), widget=forms.TextInput(attrs={'autofocus': True}))

def clean(self):
email = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')

if email is not None and password:
self.user_cache = authenticate(self.request, username=email, password=password)
if self.user_cache is None:
raise self.get_invalid_login_error()
else:
self.confirm_login_allowed(self.user_cache)

return self.cleaned_data
19 changes: 19 additions & 0 deletions authorization/forms/role_form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from django import forms

from authorization.models import Role, PermissionChoices, Permission


class RoleForm(forms.ModelForm):
permissions = forms.ModelMultipleChoiceField(
queryset=Permission.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=False
)

class Meta:
model = Role
fields = ['name', 'permissions']

def __init__(self, *args, **kwargs):
super(RoleForm, self).__init__(*args, **kwargs)
self.fields['permissions'].widget.attrs.update({'class': 'form-check-input'})
44 changes: 44 additions & 0 deletions authorization/forms/user_edit_form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from django import forms
from django.contrib.auth.forms import UserChangeForm

from authorization.models import CustomUser


class EditUserForm(UserChangeForm):
password1 = forms.CharField(
label="Password",
widget=forms.PasswordInput,
required=False # Сделаем поле необязательным
)
password2 = forms.CharField(
label="Password confirmation",
widget=forms.PasswordInput,
required=False # Сделаем поле необязательным
)

class Meta:
model = CustomUser
fields = ['first_name', 'last_name', 'email', 'role']
widgets = {
'email': forms.EmailInput(attrs={'readonly': 'readonly'}),
}

def clean(self):
cleaned_data = super().clean()
password1 = cleaned_data.get("password1")
password2 = cleaned_data.get("password2")

if password1 or password2: # Если есть хоть одно поле не пустое
if password1 != password2:
raise forms.ValidationError("Passwords do not match.")
return cleaned_data

def save(self, commit=True):
user = super().save(commit=False)
password = self.cleaned_data.get("password1")
if password: # Теперь меняем пароль только если оба поля совпадают
user.set_password(password)
if commit:
user.save()
return user

2 changes: 2 additions & 0 deletions authorization/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .custom_user import *
from .roles import *
56 changes: 56 additions & 0 deletions authorization/models/custom_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.utils.translation import gettext_lazy as _
from django.utils import timezone


class CustomUserManager(BaseUserManager):
def create_user(self, email, first_name, last_name, password=None, **extra_fields):
if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
user = self.model(email=email, first_name=first_name, last_name=last_name, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user

def create_superuser(self, email, first_name, last_name, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)

if extra_fields.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))

return self.create_user(email, first_name, last_name, password, **extra_fields)


class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(_('first name'), max_length=30, blank=False)
last_name = models.CharField(_('last name'), max_length=30, blank=False)
role = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('role'))
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
last_login = models.DateTimeField(_('last login'), default=timezone.now, blank=True, null=True)

created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

objects = CustomUserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']

def __str__(self):
return self.email

def get_full_name(self):
return f'{self.first_name} {self.last_name}'

def has_role_permission(self, perm_codename):
if self.is_superuser:
return True
return self.role.permissions.filter(codename=perm_codename).exists() if self.role else False
Loading