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
  •  
  •  
  •  
21 changes: 21 additions & 0 deletions .gcloudignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This file specifies files that are *not* uploaded to Google Cloud
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
# $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:
.git
.gitignore
venv/
dev/

# Python pycache:
__pycache__/
# Ignored by the build system
/setup.cfg
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
Empty file added README.txt
Empty file.
26 changes: 26 additions & 0 deletions app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
runtime: python312

entrypoint: gunicorn --bind :$PORT problematy.wsgi:application

env_variables:
APPENGINE_URL: your_app_uri
SECRET_KEY: your_secret_key
DB_NAME: your_db_name
DB_USER: your_db_user
DB_PASSWORD: your_db_password
DB_HOST: your_db_host
DB_PORT: your_db_port
LOCATIONS_BLOB_FILEPATH: your_json_filepath
APPLICATION_BUCKET_NAME: your_bucket_name

handlers:
# This configures Google App Engine to serve the files in the app's static
# directory.
- url: /static
static_dir: static/

# This handler routes all requests not caught above to your main app. It is
# required when static routes are defined, but can be omitted (along with
# the entire handlers section) when there are no static files defined.
- url: /.*
script: auto
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 *
Loading