def log(cls, user, ip_address): try: geo = geo_by_addr(ip_address) except Exception: geo = None values = {"last_seen": timezone.now()} if geo: values.update({"country_code": geo["country_code"], "region_code": geo["region"]}) UserIP.objects.create_or_update(user=user, ip_address=ip_address, values=values)
def from_ip_address(cls, ip_address): try: geo = geo_by_addr(ip_address) except Exception: geo = None if not geo: return None data = { 'country_code': geo.get('country_code'), 'city': geo.get('city'), 'region': geo.get('region'), } return cls.to_python(data)
def serialize_eventusers(organization, item_list, user, lookup): if not item_list: return {} # We have no reliable way to map the tag value format # back into real EventUser rows. EventUser is only unique # per-project, and this is an organization aggregate. # This means a single value maps to multiple rows. filters = reduce( or_, [ Q(hash=EventUser.hash_from_tag(tag), project_id=project) for tag, project in item_list ], ) eu_by_key = {(eu.tag_value, eu.project_id): eu for eu in EventUser.objects.filter(filters)} projects = serialize_projects(organization, {i[1] for i in item_list}, user) rv = {} for tag, project in item_list: eu = eu_by_key.get((tag, project)) if eu is None: attr, value = tag.split(":", 1) eu = EventUser(project_id=project, **{EventUser.attr_from_keyword(attr): value}) rv[(tag, project)] = { HEALTH_ID_KEY: make_health_id(lookup, [eu.tag_value, eu.project_id]), "value": { "id": str(eu.id) if eu.id else None, "project": projects.get(eu.project_id), "hash": eu.hash, "tagValue": eu.tag_value, "identifier": eu.ident, "username": eu.username, "email": eu.email, "ipAddress": eu.ip_address, "dateCreated": eu.date_added, "label": eu.get_label(), "name": eu.get_display_name(), "geo": geo_by_addr(eu.ip_address), }, } return rv
def test_geo_by_addr(self): import importlib import sentry.utils.geo importlib.reload(sentry.utils.geo) from sentry.utils.geo import geo_by_addr assert geo_by_addr("8.8.8.8") == { "country_code": "US", "region": "CA", "city": "Beverly Hills", "latitude": 34.09109878540039, "longitude": -118.41169738769531, }
def log(cls, user, ip_address): # Only log once every 5 minutes for the same user/ip_address pair # since this is hit pretty frequently by all API calls in the UI, etc. cache_key = f"userip.log:{user.id}:{ip_address}" if cache.get(cache_key): return try: geo = geo_by_addr(ip_address) except Exception: geo = None values = {"last_seen": timezone.now()} if geo: values.update({"country_code": geo["country_code"], "region_code": geo["region"]}) UserIP.objects.create_or_update(user=user, ip_address=ip_address, values=values) cache.set(cache_key, 1, 300)
def from_ip_address(cls, ip_address): try: geo = geo_by_addr(ip_address) except Exception: geo = None if not geo: return None data = {} for k in ('country_code', 'city', 'region'): d = geo.get(k) if isinstance(d, six.binary_type): d = d.decode('ISO-8859-1') data[k] = d return cls.to_python(data)
def log(cls, user, ip_address): try: geo = geo_by_addr(ip_address) except Exception: geo = None values = { 'last_seen': timezone.now(), } if geo: values.update({ 'country_code': geo['country_code'], 'region_code': geo['region'], }) UserIP.objects.create_or_update( user=user, ip_address=ip_address, values=values, )
def notify_orbital(ip, data=None, **kwargs): try: result = geo_by_addr(ip) except Exception: return if not result: return if data: platform = (data.get("platform") or "other").lower() else: platform = "" data = [ round(result["latitude"], 4), round(result["longitude"], 4), int(time() * 1000), platform, ] udp_socket.sendto(dumps(data).encode("utf-8"), udp_addr)