You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

448 lines
17 KiB

# 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