from django.contrib.gis.geoip import GeoIP from django.utils.translation import get_language from django.core.cache import cache from logging import getLogger # noinspection PyProtectedMember from phonenumbers.data import _COUNTRY_CODE_TO_REGION_CODE from pytz import country_timezones logger = getLogger(__name__) def get_client_ip(request): """ http://stackoverflow.com/questions/4581789/how-do-i-get-user-ip-address-in-django """ x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') return ip def get_geoip(request): """ Return GeoIP.country dictionary, queried by request IP address. """ ip = get_client_ip(request) geoip = GeoIP() if ip: ret = geoip.country(ip) logger.debug('GeoIP detection on IP: %s with result: %s', ip, ret) return ret else: return {'country_code': None, 'country_name': None} def get_time_zone(country_code): """ Return time zone for country. """ try: return country_timezones[country_code][0] except KeyError: return None def get_phone_prefix(country_code): """ Return international phone country prefix. """ # noinspection PyCompatibility for prefix, countries in _COUNTRY_CODE_TO_REGION_CODE.iteritems(): if country_code in countries: return '+%d' % prefix return '' def get_initial_data(request): """Initial data for registration page""" dc_settings = request.dc.settings initial = { 'language': get_language(), 'country': dc_settings.PROFILE_COUNTRY_CODE_DEFAULT, 'phone': dc_settings.PROFILE_PHONE_PREFIX_DEFAULT, 'time_zone': dc_settings.PROFILE_TIME_ZONE_DEFAULT, } # This code should be bullet proof. We don't want to fail a registration because of some geo detection. try: country = get_geoip(request)['country_code'] if not country: country = dc_settings.PROFILE_COUNTRY_CODE_DEFAULT phone = get_phone_prefix(country) if not phone: phone = dc_settings.PROFILE_PHONE_PREFIX_DEFAULT time_zone = get_time_zone(country) if not time_zone: time_zone = dc_settings.PROFILE_TIME_ZONE_DEFAULT except Exception as ex: logger.error('Registration GEO detection problem') logger.exception(ex) else: initial['phone'] = phone initial['country'] = country initial['timezone'] = time_zone return initial def generate_key(request, key, view_type): """ Generate key from username unique per type, and return default timeout in seconds """ if view_type == 'login': return 'delay_login__' + get_client_ip(request) + '_' + key, 45 elif view_type == 'forgot': return 'delay_forgot_password__' + get_client_ip(request) + '_' + key, 150 else: return 'delay_generic__' + get_client_ip(request) + '_' + key, 60 def get_attempts_from_cache(key): attempts = cache.get(key) if attempts: return int(attempts) return 0 def set_attempts_to_cache(key, timeout=30): attempts = get_attempts_from_cache(key) + 1 timeout *= attempts cache.set(key, attempts, timeout) return attempts, timeout def clear_attempts_cache(request, key): gen_key, timeout = generate_key(request, key, 'login') cache.delete(gen_key) gen_key, timeout = generate_key(request, key, 'forgot') cache.delete(gen_key)