diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0d4799d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,29 @@ +*.pyc +*.pyo +*.mo +*.db +*.css.map +*.egg-info +*.sql.gz +*.sqlite3 +.cache +.env +.project +.idea +.pydevproject +.idea/workspace.xml +.DS_Store +.git/ +.sass-cache +.vagrant/ +__pycache__ +dist +docs +env +logs +src/{{ project_name }}/settings/local.py +src/node_modules +web/media +web/static/CACHE +stats +Dockerfile diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f86db45 --- /dev/null +++ b/.env.example @@ -0,0 +1,25 @@ +ACTRL_DEBUG=1 + +ACTRL_SECRET_KEY="v1i_fb\$_jf2#1v_lcsbu&eon4u-os0^px=s^iycegdycqy&5)6" +ACTRL_HOST="actrl.example.com" + +ACTRL_EMAIL_HOST="smtp.mail.ru" +ACTRL_EMAIL_PORT=2525 +ACTRL_EMAIL_TLS=1 +ACTRL_EMAIL_HOST_USER="djgr.02@mail.ru" +ACTRL_EMAIL_HOST_PASSWORD="djangogroup02" +ACTRL_FROM_EMAIL="djgr.02@mail.ru" +ACTRL_SERVER_EMAIL="djgr.02@mail.ru" + +ENG_CROLE_ID=360005209000 +LA_CROLE_ID=360005208980 +EMPL_GROUP="Поддержка" +BUF_GROUP="Сменная группа" +ST_EMAIL="d.krikov@ngenix.net" +LICENSE_NO=3 +SHIFTH=12 + +ACTRL_ZENDESK_SUBDOMAIN="ngenix1612197338" +ACTRL_API_EMAIL="email@example.com" +ACTRL_API_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +ACTRL_API_PASSWORD="" diff --git a/.gitignore b/.gitignore index 1f6ea85..a1195c0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ __pycache__/ local_settings.py db.sqlite3 db.sqlite3-journal +db/ media/ logs/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..59c861e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.6 +COPY ./ /access_controller +WORKDIR /access_controller/ +RUN pip install -r requirements/prod.txt +RUN python manage.py makemigrations +EXPOSE 8000 +COPY start.sh /var/ +CMD bash /var/start.sh + + diff --git a/README.md b/README.md index 14e3869..e0b2f61 100644 --- a/README.md +++ b/README.md @@ -42,34 +42,47 @@ ```bash sudo apt install make pip install --upgrade pip -pip install -r requirements.txt +pip install -r requirements/dev.txt ./manage.py migrate ./manage.py loaddata data.json ./manage.py runserver ``` -##ZenDesk Access Controller instruction for eng +## ZenDesk Access Controller instruction for eng -##Перед запуском для тестирования: +## Перед запуском для тестирования: -Убедитесь, что вы зарегистрированы в песочнице ZenDesk, у вас назначена организация (SYSTEM) +Убедитесь, что вы зарегистрированы в песочнице ZenDesk, у вас назначена организация `SYSTEM` Для админов ZenDesk дополнительно - создайте токен доступа в ZenDesk При запуске в Docker убедитесь что папка, которая будет служить хранилищем для БД, открыта на запись и чтение -##Запуск на локальной машине: - -скопировать репозиторий на локальную машину -перейти в папку приложения -активировать вирутальное окружение -выполнить команду pip install -r requirements.txt -в вирутальное окружение добавить следующие переменные : +## Запуск на локальной машине: +- Скопировать репозиторий на локальную машину +- Перейти в папку приложения +- Активировать виртуальное окружение +- Выполнить команду `pip install -r requirements/dev.txt` +- В виртуальное окружение добавить следующие переменные: -ACCESS_CONTROLLER_API_EMAIL={EMAIL} - почта админа в ZenDesk -ACCESS_CONTROLLER_API_PASSWORD={PASSWORD} - пароль админа ZenDesk -ACCESS_CONTROLLER_API_TOKEN={API_TOKEN} - API токен зендеск -ZD_DOMAIN={DOMAIN} - домен ZenDesk +``` +ACTRL_DEBUG={0/1} - включить режим дебага +ACTRL_HOST={HOSTNAME} - при запуске без дебага, надо указать домен на котором будет работать приложение +ACTRL_SECRET_KEY={DJANGO_SECRET_KEY} - секретный ключ сгенерированый Django + +ACTRL_EMAIL_HOST={SMTP_HOST} - домен почтового сервера через который приложение будет отправлять письма, например "smtp.gmail.com" +ACTRL_EMAIL_PORT={SMTP_PORT} - порт для почтового сервера, например 587, 465 , 2525 +ACTRL_EMAIL_TLS={USE_TLS} - использовать TLS для подключения к почтовому серверу, 0 или 1 +ACTRL_EMAIL_HOST_USER={USERNAME} - логин с которым приложение входит на почтовый сервер +ACTRL_EMAIL_HOST_PASSWORD={PASSWORD} - пароль/ключ с которым приложение входит на почтовый сервер +ACTRL_FROM_EMAIL={EMAIL} - адрес с которого приложение отправляет письма +ACTRL_SERVER_EMAIL={EMAIL} - адрес на который отвечают пользователя + +ACTRL_API_EMAIL={EMAIL} - почта админа в ZenDesk +ACTRL_API_PASSWORD={PASSWORD} - пароль админа ZenDesk +ACTRL_API_TOKEN={API_TOKEN} - API токен зендеск +ACTRL_ZENDESK_SUBDOMAIN={DOMAIN} - домен ZenDesk + ENG_CROLE_ID={ENGINEER_CUSTOM_ROLE_ID} - id роли инженера( custom_role_id сотрдника смены) LA_CROLE_ID={LIGHT_AGENT_CUSTOM_ROLE_ID} - id роли легкого агента (custom_role_id роли -легкий агент) EMPL_GROUP={EMPLOYEE_GROUP_NAME} - имя группы которой принадлежат сотрудники ССКС @@ -77,48 +90,62 @@ BUF_GROUP={BUFFER_GROUP_NAME} - имя буферной группы для пе ST_EMAIL={SOLVED_TICKETS_EMAIL} - почта на которую будут переназначятся закрытые тикеты LICENSE_NO={LICENSE_NO} - количество лицензий, отображаемых как доступные в приложении SHIFTH={SHIFT_HOURS} - количество часов в рабочей смене (нужно для статистики, пока не реализовано но требует указания значения) +``` + +- Выполнить команду `python manage.py migrate` +- Запустить приложение командой `python manage.py runserver` (можно указать в параметрах для файла manage.py) +- Перейти по ссылке в консоли (вероятнее всего откроется по адресу http://127.0.0.1:8000/) -выполнить команду python manage.py makemigrations -выполнить команду python manage.py migrate -запустить приложение командой python manage.py runserver (можно указать в параметрах для файла manage.py) -перейти по ссылке в консоли (вероятнее всего откроется по адресу http://127.0.0.1:8000/) +## Запуск в Docker: +Требуется установленный и настроенный Docker + +- Скопировать репозиторий на локальную машину +- В командной строке перейти в папку проекта +- Выполнить команду `docker build --tag access_controller:latest .` +- Выполнить команду +```bash +docker run -d -p 8000:8000 \ + ACTRL_DEBUG={0/1} \ + ACTRL_HOST={HOSTNAME} \ + ACTRL_SECRET_KEY={DJANGO_SECRET_KEY} \ + ACTRL_EMAIL_HOST={SMTP_HOST} \ + ACTRL_EMAIL_PORT={SMTP_PORT} \ + ACTRL_EMAIL_TLS={USE_TLS} \ + ACTRL_EMAIL_HOST_USER={USERNAME} \ + ACTRL_EMAIL_HOST_PASSWORD={PASSWORD} \ + ACTRL_FROM_EMAIL={EMAIL} \ + ACTRL_SERVER_EMAIL={EMAIL} \ + ACTRL_API_EMAIL={EMAIL} \ + ACTRL_API_PASSWORD={PASSWORD} \ + ACTRL_API_TOKEN={API_TOKEN} \ + ACTRL_ZENDESK_SUBDOMAIN={DOMAIN} \ + ENG_CROLE_ID={ENGINEER_CUSTOM_ROLE_ID} \ + LA_CROLE_ID={LIGHT_AGENT_CUSTOM_ROLE_ID} \ + EMPL_GROUP={EMPLOYEE_GROUP_NAME} \ + BUF_GROUP={BUFFER_GROUP_NAME} \ + ST_EMAIL={SOLVED_TICKETS_EMAIL} \ + LICENSE_NO={LICENSE_NO} \ + SHIFTH={SHIFT_HOURS} \ + -v {ABSOLUTE_PATH_TO_DB}:/zendesk-access-controller/db \ + access_controller:latest +``` +- открываем запущеный контейнер в браузере (можно перейти по ссылке http://localhost:8000/) -##Запуск в Docker: -Требуется установленный и настроеный Docker +## Запуск с тестовыми юзерами: +На локальной машине - перед запуском команды `python manage.py runserver` выполнить команду `python manage.py loaddata data.json` +Это создаст тестового админа и тестового пользователя в приложении для песочницы ZenDesk. -скопировать репозиторий на локальную машину -в командной строке перейти в папку проекта -выполнить команду docker build . -выполнить команду docker images (нам нужен id созданного образа) -выполнить команду docker run -d -p 8000:8000 -e ACCESS_CONTROLLER_API_EMAIL={EMAIL} -e ACCESS_CONTROLLER_API_PASSWORD={PASSWORD} -...(перечисляем все параметры виртуального окружени разделяя их -e) -v {абсолютный путь к папке, в которой будет размещена база}:/zendesk-access-controller/db {id образа докера} -открываем запущеный контейнер в браузере (можно перейти по ссылке http://localhost:8000/) +- Админ - `admin@gmail.com` / `zendeskadmin` +- Пользователь - `123@test.ru` / `zendeskuser` + +Не сработает если домен песочницы отличается от `ngenix1612197338` (на другом домене нужно будет создать сначала пользователей в песочнице с правами админа и легкого агента +с этими же почтами, назначить им организацию `SYSTEM`) -##Запуск с тестовыми юзерами: - -На локальной машине - перед запуском команды python manage.py runserver выполнить команду python manage.py loaddata data.json -Это создаст тестового админа и тестового пользователя в приложении для песочницы ZenDesk. Админ - admin@gmail.com / zendeskadmin , пользователь - 123@test.ru / zendeskuser . -Не сработает если домен песочницы отличается от ngenix1612197338 (на другом домене нужно будет создать сначала пользователей в песочнице с правами админа и легкого агента -с этими же почтами, назначить им организацию (SYSTEM)) - - -##Параметры тестовой песочницы: - -ACCESS_CONTROLLER_API_EMAIL={EMAIL} - почта админа в ZenDesk - взять у роководителя(если вы не админ) -ACCESS_CONTROLLER_API_PASSWORD={PASSWORD} - пароль админа ZenDesk - взять у роководителя(если вы не админ) -ACCESS_CONTROLLER_API_TOKEN={API_TOKEN} - API токен зендеск - взять у роководителя(если вы не админ) -ZD_DOMAIN=ngenix1612197338 -ENG_CROLE_ID=360005209000 -LA_CROLE_ID=360005208980 -EMPL_GROUP=Поддержка -BUF_GROUP=Сменная группа -ST_EMAIL=d.krikov@ngenix.net - -LICENSE_NO=3 -SHIFTH=12 +## Параметры тестовой песочницы: +Пример полной конфигурации можно найти в [.env.example](.env.example). Почту и токен админа ZenDesk взять у руководителя (если вы не админ). ## Read more diff --git a/access_controller/settings.py b/access_controller/settings.py index f9b5119..a7585ed 100644 --- a/access_controller/settings.py +++ b/access_controller/settings.py @@ -19,12 +19,16 @@ BASE_DIR = Path(__file__).resolve().parent.parent # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'v1i_fb$_jf2#1v_lcsbu&eon4u-os0^px=s^iycegdycqy&5)6' +SECRET_KEY = os.getenv('ACTRL_SECRET_KEY','empty') # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = bool(int(os.getenv('ACTRL_DEBUG',1))) -ALLOWED_HOSTS = ['127.0.0.1'] +ALLOWED_HOSTS = [ + '127.0.0.1', + 'localhost', + os.getenv('ACTRL_HOST'), +] # Application definition @@ -53,13 +57,13 @@ MIDDLEWARE = [ ROOT_URLCONF = 'access_controller.urls' EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' -EMAIL_HOST = 'smtp.gmail.com' -EMAIL_PORT = 587 -EMAIL_USE_TLS = True -EMAIL_HOST_USER = 'group02django@gmail.com' -EMAIL_HOST_PASSWORD = 'djangogroup02' -DEFAULT_FROM_EMAIL = EMAIL_HOST_USER -SERVER_EMAIL = EMAIL_HOST_USER +EMAIL_HOST = os.getenv('ACTRL_EMAIL_HOST','smtp.gmail.com') +EMAIL_PORT = int(os.getenv('ACTRL_EMAIL_PORT',587)) +EMAIL_USE_TLS = bool(int(os.getenv('ACTRL_EMAIL_TLS',1))) +EMAIL_HOST_USER = os.getenv('ACTRL_EMAIL_HOST_USER','group02django@gmail.com') +EMAIL_HOST_PASSWORD = os.getenv('ACTRL_EMAIL_HOST_PASSWORD','djangogroup02') +DEFAULT_FROM_EMAIL = os.getenv('ACTRL_FROM_EMAIL',EMAIL_HOST_USER) +SERVER_EMAIL = os.getenv('ACTRL_SERVER_EMAIL',EMAIL_HOST_USER) TEMPLATES = [ { @@ -87,7 +91,7 @@ WSGI_APPLICATION = 'access_controller.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', + 'NAME': BASE_DIR / 'db' / 'zd_db.sqlite3' } } @@ -146,18 +150,18 @@ AUTHENTICATION_BACKENDS = [ ZENDESK_ROLES = { - 'engineer': 360005209000, - 'light_agent': 360005208980, + 'engineer': int(os.getenv('ENG_CROLE_ID',0)), + 'light_agent': int(os.getenv('LA_CROLE_ID',0)), } ZENDESK_GROUPS = { - 'employees': 'Поддержка', - 'buffer': 'Сменная группа', + 'employees': os.getenv('EMPL_GROUP'), + 'buffer': os.getenv('BUF_GROUP'), } -SOLVED_TICKETS_EMAIL = 'd.krikov@ngenix.net' +SOLVED_TICKETS_EMAIL = os.getenv('ST_EMAIL') -ZENDESK_MAX_AGENTS = 3 +ZENDESK_MAX_AGENTS = int(os.getenv('LICENSE_NO',0)) REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, @@ -167,4 +171,9 @@ REST_FRAMEWORK = { ] } -ONE_DAY = 12 # Количество часов в 1 рабочем дне +ONE_DAY = int(os.getenv('SHIFTH',0)) # Количество часов в 1 рабочем дне + +ACTRL_ZENDESK_SUBDOMAIN = os.getenv('ACTRL_ZENDESK_SUBDOMAIN') or os.getenv('ZD_DOMAIN') +ACTRL_API_EMAIL = os.getenv('ACTRL_API_EMAIL') or os.getenv('ACCESS_CONTROLLER_API_EMAIL') +ACTRL_API_TOKEN = os.getenv('ACTRL_API_TOKEN') or os.getenv('ACCESS_CONTROLLER_API_TOKEN') +ACTRL_API_PASSWORD = os.getenv('ACTRL_API_PASSWORD') or os.getenv('ACCESS_CONTROLLER_API_PASSWORD') diff --git a/data.json b/data.json index 97678f3..a4310a4 100644 --- a/data.json +++ b/data.json @@ -1,7 +1,7 @@ [ { "model": "auth.user", - "pk": 3, + "pk": 1, "fields": { "password": "pbkdf2_sha256$216000$gHBBCr1jBELf$ZkEDW3IEd8Wij7u8vkv+0Eze32CS01bcaYWhcD9OIC4=", "last_login": null, @@ -19,16 +19,16 @@ }, { "model": "main.userprofile", - "pk": 3, + "pk": 1, "fields": { "name": "ZendeskAdmin", - "user": 3, + "user": 1, "role": "admin" } }, { "model": "auth.user", - "pk": 4, + "pk": 2, "fields": { "password": "pbkdf2_sha256$216000$5qLJgrm2Quq9$KDBNNymVZXkUx0HKBPFst2m83kLe0egPBnkW7KnkORU=", "last_login": null, @@ -46,10 +46,10 @@ }, { "model": "main.userprofile", - "pk": 4, + "pk": 2, "fields": { "name": "UserForAccessTest", - "user": 4, + "user": 2, "role": "agent", "custom_role_id": "360005209000" } diff --git a/db/.gitkeep b/db/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/main/apiauth.py b/main/apiauth.py index c24e85f..08a018c 100644 --- a/main/apiauth.py +++ b/main/apiauth.py @@ -3,6 +3,8 @@ import os from zenpy import Zenpy from zenpy.lib.api_objects import User as ZenpyUser +from access_controller.settings import ACTRL_ZENDESK_SUBDOMAIN, ACTRL_API_EMAIL, ACTRL_API_TOKEN, ACTRL_API_PASSWORD + def api_auth() -> dict: """ @@ -15,15 +17,15 @@ def api_auth() -> dict: :return: данные пользователя """ credentials = { - 'subdomain': 'ngenix1612197338' + 'subdomain': ACTRL_ZENDESK_SUBDOMAIN } - email = os.getenv('ACCESS_CONTROLLER_API_EMAIL') - token = os.getenv('ACCESS_CONTROLLER_API_TOKEN') - password = os.getenv('ACCESS_CONTROLLER_API_PASSWORD') + email = ACTRL_API_EMAIL + token = ACTRL_API_TOKEN + password = ACTRL_API_PASSWORD if email is None: raise ValueError('access_controller email not in env') - credentials['email'] = os.getenv('ACCESS_CONTROLLER_API_EMAIL') + credentials['email'] = email # prefer token, use password if token not provided if token: diff --git a/main/extra_func.py b/main/extra_func.py index 27986c8..3e54ae4 100644 --- a/main/extra_func.py +++ b/main/extra_func.py @@ -9,7 +9,8 @@ from zenpy import Zenpy from zenpy.lib.exception import APIException -from access_controller.settings import ZENDESK_ROLES as ROLES, ONE_DAY, ZENDESK_GROUPS, SOLVED_TICKETS_EMAIL +from access_controller.settings import ZENDESK_ROLES as ROLES, ONE_DAY, ZENDESK_GROUPS, SOLVED_TICKETS_EMAIL, \ + ACTRL_API_EMAIL, ACTRL_API_TOKEN, ACTRL_API_PASSWORD, ACTRL_ZENDESK_SUBDOMAIN from main.models import UserProfile, RoleChangeLogs, UnassignedTicket, UnassignedTicketStatus @@ -28,11 +29,11 @@ class ZendeskAdmin: """ credentials: dict = { - 'subdomain': 'ngenix1612197338' + 'subdomain': ACTRL_ZENDESK_SUBDOMAIN } - email: str = os.getenv('ACCESS_CONTROLLER_API_EMAIL') - token: str = os.getenv('ACCESS_CONTROLLER_API_TOKEN') - password: str = os.getenv('ACCESS_CONTROLLER_API_PASSWORD') + email: str = ACTRL_API_EMAIL + token: str = ACTRL_API_TOKEN + password: str = ACTRL_API_PASSWORD def __init__(self): self.create_admin() @@ -253,7 +254,7 @@ def check_user_auth(email: str, password: str) -> bool: creds = { 'email': email, 'password': password, - 'subdomain': 'ngenix1612197338', + 'subdomain': ACTRL_ZENDESK_SUBDOMAIN, } try: user = Zenpy(**creds) diff --git a/main/models.py b/main/models.py index ac6f91c..1920c4d 100644 --- a/main/models.py +++ b/main/models.py @@ -81,3 +81,4 @@ class UnassignedTicket(models.Model): assignee = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name='tickets', help_text='Пользователь, с которого снят тикет') ticket_id = models.IntegerField(help_text='Номер тикера, для которого сняли ответственного') status = models.IntegerField(choices=UnassignedTicketStatus.choices, default=UnassignedTicketStatus.UNASSIGNED, help_text='Статус тикета') + diff --git a/requirements.txt b/requirements.txt index 16ae562..b0c3540 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,15 +1 @@ -# Engine -Django==3.1.6 -Pillow==8.1.0 -zenpy~=2.0.24 -django_registration==3.1.1 -djangorestframework==3.12.2 -daphne==3.0.1 - - -# Documentation -Sphinx==3.4.3 -sphinx-rtd-theme==0.5.1 -sphinx-autodoc-typehints==1.11.1 -pyenchant==3.2.0 -sphinxcontrib-spelling==7.1.0 +-r requirements/dev.txt diff --git a/requirements/common.txt b/requirements/common.txt new file mode 100644 index 0000000..6b3e7fa --- /dev/null +++ b/requirements/common.txt @@ -0,0 +1,16 @@ +# Contains requirements common to all environments + +# Engine +Django==3.1.6 +Pillow==8.1.0 +zenpy~=2.0.24 +django_registration==3.1.1 +djangorestframework==3.12.2 + + +# Documentation +Sphinx==3.4.3 +sphinx-rtd-theme==0.5.1 +sphinx-autodoc-typehints==1.11.1 +pyenchant==3.2.0 +sphinxcontrib-spelling==7.1.0 diff --git a/requirements/dev.txt b/requirements/dev.txt new file mode 100644 index 0000000..73c27d0 --- /dev/null +++ b/requirements/dev.txt @@ -0,0 +1,3 @@ +# Development specific dependencies +-r common.txt + diff --git a/requirements/prod.txt b/requirements/prod.txt new file mode 100644 index 0000000..b0e6925 --- /dev/null +++ b/requirements/prod.txt @@ -0,0 +1,5 @@ +# Production specific dependencies +-r common.txt + +daphne==3.0.1 +Twisted[tls,http2]==21.2.0 diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..4041353 --- /dev/null +++ b/start.sh @@ -0,0 +1,6 @@ +cd /access_controller/ + +python manage.py migrate + +python manage.py collectstatic --noinput +daphne -b 0.0.0.0 access_controller.asgi:application