# coding=utf-8 import datetime from lms.decors import out_api_decor, api_decor from access.models import TrafSource, User, TrafHistory # , UserSync from lms.regex import check_email from management.letters import sent_registration from finance.models import Price, Bill from lms.tools import out_date_format import hashlib from django.contrib import auth from lms.settings import SECRET_KEY, SUPERVISOR, MANAGER from django.http import Http404 @api_decor(without_auth=False) def set_in_user(request, context): # Наша установка data = None context['code'] = '0' context['response'] = '' if request.user and request.user.is_authenticated() and request.user.is_admin: if request.method: if request.method == 'POST': data = request.POST elif request.method == 'GET': data = request.GET else: raise Http404 if not data or not (data.get('SERVICE') or data.get('USER')) or (data.get('SERVICE') and not data.get('USER')): context['response'] = u'REQUEST IS NOT VALID. ' \ u'USER - user email (required) / ' \ u'SERVICE - service token / ' \ u'GIFT - will set bill in a payed status / ' \ u'PRICE - set self price to the service' return context service = None if data.get('SERVICE'): try: service = Price.objects.get(key=data.get('SERVICE')) except Price.DoesNotExist: context['response'] = u'SERVICE NOT FOUND' return context if data.get('USER') and check_email(data.get('USER')): result, user = self_create_user(data.get('USER'), sent_letter=True) context['response'] = 'USER CREATED.' if result else 'USER ALREADY EXISTS.' elif not check_email(data.get('USER')): context['response'] = 'USER EMAIL IS NOT VALID' if service and user: bill, created = Bill.objects.get_or_create(service=service, gift=bool(data.get('GIFT')), user=user, status='F' if data.get('GIFT') else 'W', manager=User.objects.get(email=MANAGER), price=data['PRICE'] if data.get('PRICE') else service.cost) if created: if data.get('GIFT'): context['response'] += ' ACCESS OPENED. IT IS A GIFT.' else: context['response'] += ' THIS OFFER SENT TO THE USER. THE SERVICE PRICE: %s' % str(bill.price) else: context['response'] += ' BILL ALREADY EXISTS id:%s' % str(bill.id) return context def self_check_token(token): try: source = TrafSource.objects.get(on=True, token=token) except TrafSource.DoesNotExist: return [False, None] else: return [True, source] def self_check_user_exists(email): email = email.lower() try: user = User.objects.get(email=email) except User.DoesNotExist: return [False, None] else: return [True, user] def self_create_user(email, phone=None, sent_letter=True): email = email.lower() try: user = User.objects.get(email=email) except User.DoesNotExist: user = User.objects.create_user(email=email, sent_letter=sent_letter) user.reg_status = '1' user.refer = 'B' user.is_active = False if phone: user.phone = phone user.save() return [True, user] else: return [False, user] def self_create_bill(user, service_key, uid=None): # Создание счета для пользователя по ключу услуги description = u'' bill = None result = False try: price = Price.objects.get(key=service_key) except Price.DoesNotExist: description = u'Счет по ключу не найден' else: bill, c = Bill.objects.get_or_create(user=user, manager=User.objects.get(email=SUPERVISOR), service=price) if bill.status == 'F': description = u'Счет для данного пользователя уже был создан {0}'.format( out_date_format(bill.finish_date, no_time=True)) result = False else: result = True description = u'Счет успешно создан. Приятного обучения' if bill.status in ['C', 'H']: bill.status = 'P' bill.status_changed = datetime.datetime.now() bill.save() if uid: bill.admitad_uid = uid bill.save() return [result, description, bill] def code_dict(d): # Преобразование словаря для передачи по HTTP return u'||'.join(list([u'{0}|{1}'.format(key, value) for key, value in d.items()])) def decode_dict(s): # Расшифровка словаря из строки, переданого по HTTP result = {} for one in s.split(u'||'): __tmp = one.split(u'|') result[__tmp[0]] = __tmp[1] return result def get_sync_data(user): # Синхронизировать пользователя с остальными LMS # Отправить в LMS измнениея по пользователю или нового пользователя # POST['user'] = {} # Поля с полной информацией пользователя _data = {} _keys = [] exclude = ['id', 'customer', 'deactivate', 'delay', 'delay_description', 'delay_date', 'changed_email', 'status', 'last_time', 'date_joined', 'avatar', 'last_login', 'activate_time', 'in_avatar'] for key in user._meta.local_concrete_fields: if key.name not in exclude: _tmp = key.value_to_string(user) if _tmp: _keys.append(key.name) _data[key.name] = _tmp _tmp = code_dict(_data) return {'data': _tmp, 'hash': hashlib.md5(_tmp.encode('utf-8')).hexdigest()} ''' def sent_sync_user(user): data = get_sync_data(user) data['secret_key'] = SECRET_KEY data['source'] = DOMAIN ## Если провал на одном из этапов - пропустить синхронизацию этого пользователя # Авторизация на сервисе под системным пользователем result = 0 for HOST in REL_LMS: __tmp = HOST['protocol'] + HOST['url'] if __tmp != DOMAIN: log = UserSync.objects.create(user=user, source=DOMAIN, dist=__tmp, data=str(data)) _request = requests.post(__tmp + 'access/sync_user/', data=data) if _request.status_code == 200: _tmp = ast.literal_eval(_request.text) if _tmp['code'] == '1': result += 1 log.good_sync() else: log.fail_sync() else: log.fail_sync() return result == len(REL_LMS)-1 ''' @out_api_decor(without_auth=True, method='POST', need_keys=['email', 'password', 'secret_key'], check_request=True) def service_auth(request, context): # Удаленная авторизация для внутренних процессов # Авторизация if request.POST['secret_key'] == SECRET_KEY: email = request.POST['email'].lower() user = auth.authenticate(email=email, password=request.POST.get('password')) if user is not None: context['code'] = '1' context['response'] = u'AUTH_SUCCESS' auth.login(request, user) elif user is None: context['response'] = u'По введенным данным пользователь не найден' context['code'] = '0' else: context['response'] = u"Не верные данные. Повторите попытку" context['code'] = '0' else: context['response'] = u'AUTH SUCCESS' context['code'] = '0' return context ''' @out_api_decor(without_auth=True, method='POST', need_keys=['secret_key', 'data', 'hash', 'source'], check_request=True) def sync_user(request, context): if request.POST['secret_key'] == SECRET_KEY: if hashlib.md5(request.POST['data'].encode('utf-8')).hexdigest() != request.POST['hash']: context['code'] = '0' context['data'] = '' context['response'] = u'Не сходится хеш данных' return context data = decode_dict(request.POST['data']) # Получение пользователя для вставки try: user = User.objects.get(email=data['email']) except User.DoesNotExist: # Создать пользователя user = User.objects.create(email=data['email']) log = UserSync.objects.create(user=user, source=request.POST['source'], dist=DOMAIN, data=str(request.POST['data'])) save = False if 'refer' in data and user.refer != data['refer']: user.refer = data['refer'] save = True if 'refer_source' in data and user.refer_source != data['refer_source']: user.refer_source = data['refer_source'] save = True if 'private' in data and user.private != data['private']: user.private = data['private'] save = True if 'interactive_key' in data and user.interactive_key != data['interactive_key']: user.interactive_key = data['interactive_key'] save = True if 'email' in data and user.email != data['email']: user.email = data['email'] save = True if 'phone' in data and user.phone != data['phone']: user.phone = data['phone'] save = True if 'back_phone' in data and user.back_phone != data['back_phone']: user.back_phone = data['back_phone'] save = True if 'in_role' in data and user.in_role != data['in_role']: user.in_role = data['in_role'] save = True if 'unique_role' in data and user.unique_role != data['unique_role']: user.unique_role = data['unique_role'] save = True if 'city' in data and user.city != data['city']: user.city = data['city'] save = True if 'b_day' in data and user.b_day != data['b_day']: user.b_day = data['b_day'] save = True if 'token' in data and user.token != data['token']: user.token = data['token'] save = True if 'reg_status' in data and user.reg_status != data['reg_status']: user.reg_status = data['reg_status'] save = True if 'is_active' in data and user.is_active != data['is_active']: user.is_active = data['is_active'] save = True if 'is_admin' in data and user.is_admin != data['is_admin']: user.is_admin = data['is_admin'] save = True if 'is_staff' in data and user.is_staff != data['is_staff']: user.is_staff = data['is_staff'] save = True if 'fname' in data and user.fname != data['fname']: user.fname = data['fname'] save = True if 'name' in data and user.name != data['name']: user.name = data['name'] save = True if 'oname' in data and user.oname != data['oname']: user.oname = data['oname'] save = True if 'skype' in data and user.skype != data['skype']: user.skype = data['skype'] save = True if 'facebook' in data and user.facebook != data['facebook']: user.facebook = data['facebook'] save = True if 'vk' in data and user.vk != data['vk']: user.vk = data['vk'] save = True if 'linkedin' in data and user.linkedin != data['linkedin']: user.linkedin = data['linkedin'] save = True if 'odnoklassniki' in data and user.odnoklassniki != data['odnoklassniki']: user.odnoklassniki = data['odnoklassniki'] save = True if 'password' in data and user.password != data['password']: user.password = data['password'] save = True if save: user.save() log.good_sync() context['code'] = '1' else: log.fail_sync() else: raise Http404 return context ''' @out_api_decor(without_auth=True, need_keys=['token', 'email'], method='POST', check_request=True) def create_user(request, context): # Создание пользователя # TODO: Политика использования токена res = False result, source = self_check_token(request.POST['token']) if not result: context['code'] = '0' description = u'Не найден активный источник' context['response'] = description return context result, user = self_check_user_exists(request.POST['email']) if result: if user.is_active and user.reg_status == '4': context['code'] = '0' description = u'Пользователь уже существует и активен' context['response'] = description else: context['code'] = '1' res = True description = u'Пользователь уже существует. Отправлено повторное письмо активации' context['response'] = description sent_registration(user, title=u'Повторное письмо активации') return context else: result, user = self_create_user(request.POST['email'], phone=request.POST['phone'] if request.POST.get('phone') else None) context['code'] = '1' res = True description = u'Пользователь создан. На указанный email отправлено письмо активации' context['response'] = description ref_history = TrafHistory.objects.create(action='C', source=source, token=request.POST['token'], data=request.POST, result_description=description, result=res) user.traf_source = ref_history user.save() return context @out_api_decor(without_auth=True, check_request=True, need_keys=['token', 'service', 'email'], method='POST') def create_bill(request, context): # TODO: Политика использования токена result, source = self_check_token(request.POST['token']) if not result: context['code'] = '0' context['response'] = u'Не найден активный источник' return context result, user = self_check_user_exists(request.POST['email']) if result: if not user.is_active or user.reg_status != '4': sent_registration(user, title=u'Повторное письмо активации') if request.POST.get('phone') and user.phone != request.POST.get('phone'): user.phone = request.POST['phone'] user.save() else: result, user = self_create_user(request.POST['email'], phone=request.POST['phone'] if request.POST.get('phone') else None) result, description, bill = self_create_bill(user, request.POST['service'], request.POST['uid'] if request.POST.get('uid') else None) context['code'] = '1' if result else '0' context['response'] = description context['data'] = bill.get_face() rel_source = TrafHistory.objects.create(action='O', source=source, token=request.POST['token'], data=request.POST, result_description=description, result=True if result else False) bill.traf_source = rel_source bill.save() return context @out_api_decor(without_auth=True, need_keys=['token', 'data'], method='POST', check_request=True) def set_lendos_data(request, context): # Создание пользователя res = False result, source = self_check_token(request.POST['token']) if not result: context['code'] = '0' description = u'Не найден активный источник' context['response'] = description return context TrafHistory.objects.create(action='D', source=source, token=request.POST['token'], data=request.POST['data'], result_description='Данные из форм', result=res) return context