import os from django.contrib.auth.models import User from zenpy import Zenpy from zenpy.lib.exception import APIException from main.models import UserProfile from django.core.exceptions import ObjectDoesNotExist from access_controller.settings import ZENDESK_ROLES as ROLES, ZENDESK_ROLES class ZendeskAdmin: """ Класс **ZendeskAdmin** существует, чтобы в каждой фунциии отдельно не проверять аккаунт администратора :param credentials: Полномочия (первым указывается учетная запись организации в Zendesk) :type credentials: :class:`dict` :param email: Email администратора, указанный в env :type email: :class:`str` :param token: Токен администратора (формируется в Zendesk, указывается в env) :type token: :class:`str` :param password: Пароль администратора, указанный в env :type password: :class:`str` """ credentials: dict = { 'subdomain': 'ngenix1612197338' } email: str = os.getenv('ACCESS_CONTROLLER_API_EMAIL') token: str = os.getenv('ACCESS_CONTROLLER_API_TOKEN') password: str = os.getenv('ACCESS_CONTROLLER_API_PASSWORD') _instance = None def __new__(cls, *args, **kwargs): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def __init__(self): self.create_admin() def check_user(self, email: str) -> bool: """ Функция **check_user** осуществляет проверку существования пользователя в Zendesk по email """ return True if self.admin.search(email, type='user') else False def get_user_name(self, email: str) -> str: """ Функция **get_user_name** возвращает имя пользователя по его email """ user = self.admin.users.search(email).values[0] return user.name def get_user_role(self, email: str) -> str: """ Функция **get_user_role** возвращает роль пользователя по его email """ user = self.admin.users.search(email).values[0] return user.role def get_user_id(self, email: str) -> str: """ Функция **get_user_id** возвращает id пользователя по его email """ user = self.admin.users.search(email).values[0] return user.id def get_user_image(self, email: str) -> str: """ Функция **get_user_image** возвращает url-ссылку на аватар пользователя по его email """ user = self.admin.users.search(email).values[0] return user.photo['content_url'] if user.photo else None def get_user(self, email: str) -> str: """ Функция **get_user** возвращает пользователя (объект) по его email :param email: email пользователя :return: email пользователя, найденного в БД """ return self.admin.users.search(email).values[0] def get_user_org(self, email: str) -> str: """ Функция **get_user_org** возвращает организацию, к которой относится пользователь по его email """ user = self.admin.users.search(email).values[0] return user.organization.name def create_admin(self) -> Zenpy: """ Функция **Create_admin()** создает администратора, проверяя наличие вводимых данных в env. :param credentials: В список полномочий администратора вносятся email, token, password из env :type credentials: :class:`dict` :raise: :class:`ValueError`: исключение, вызываемое если email не введен в env :raise: :class:`APIException`: исключение, вызываемое если пользователя с таким email не существует в Zendesk """ if self.email is None: raise ValueError('access_controller email not in env') self.credentials['email'] = os.getenv('ACCESS_CONTROLLER_API_EMAIL') if self.token: self.credentials['token'] = self.token elif self.password: self.credentials['password'] = self.password else: raise ValueError('access_controller token or password not in env') self.admin = Zenpy(**self.credentials) try: self.admin.search(self.email, type='user') except APIException: raise ValueError('invalid access_controller`s login data') def update_role(user_profile: UserProfile, role: str) -> UserProfile: """ Функция **update_role** меняет роль пользователя. """ zendesk = ZendeskAdmin() user = zendesk.get_user(user_profile.user.email) user.custom_role_id = role zendesk.admin.users.update(user) def make_engineer(user_profile: UserProfile) -> UserProfile: """ Функция **make_engineer** устанавливапет пользователю роль инженера. """ update_role(user_profile, ROLES['engineer']) def make_light_agent(user_profile: UserProfile) -> UserProfile: """ Функция **make_light_agent** устанавливапет пользователю роль легкого агента. """ update_role(user_profile, ROLES['light_agent']) def get_users_list() -> list: """ Функция **get_users_list** возвращает список пользователей Zendesk, относящихся к организации. """ zendesk = ZendeskAdmin() # У пользователей должна быть организация SYSTEM org = next(zendesk.admin.search(type='organization', name='SYSTEM')) return zendesk.admin.organizations.users(org) def update_profile(user_profile: UserProfile) -> UserProfile: """ Функция обновляет профиль пользователя в соотвтетствии с текущим в Zendesk """ user = ZendeskAdmin().get_user(user_profile.user.email) user_profile.name = user.name user_profile.role = user.role user_profile.image = user.photo['content_url'] if user.photo else None user_profile.save() def check_user_exist(email: str) -> bool: """ Функция проверяет, существует ли пользователь """ return ZendeskAdmin().check_user(email) def get_user_organization(email: str) -> str: """ Функция возвращает организацию пользователя """ return ZendeskAdmin().get_user_org(email) def check_user_auth(email: str, password: str) -> bool: """ Функция проверяет, верны ли входные данные :raise: :class:`APIException`: исключение, вызываемое если пользователь не аутентифицирован """ creds = { 'email': email, 'password': password, 'subdomain': 'ngenix1612197338', } try: user = Zenpy(**creds) user.search(email, type='user') except APIException: return False return True def update_user_in_model(profile, zendesk_user): profile.name = zendesk_user.name profile.role = zendesk_user.role profile.image = zendesk_user.photo['content_url'] if zendesk_user.photo else None profile.save() def count_users(users) -> tuple: """ Функция подсчета количества сотрудников с ролями engineer и light_a .. todo:: this func counts users from all zendesk instead of just from a model: """ engineers, light_agents = 0, 0 for user in users: if user.custom_role_id == ZENDESK_ROLES['engineer']: engineers += 1 elif user.custom_role_id == ZENDESK_ROLES['light_agent']: light_agents += 1 return engineers, light_agents def update_users_in_model(): """ Обновляет пользователей в модели UserProfile по списку пользователей в организации """ users = get_users_list() for user in users: try: profile = User.objects.get(email=user.email).userprofile update_user_in_model(profile, user) except ObjectDoesNotExist: pass return users