From 10aa8c40a76cf63b2742fa09b0aa29a99ac30da7 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 10 Nov 2016 23:54:21 +0800 Subject: [PATCH] Add login log --- apps/audits/hands.py | 1 + apps/audits/models.py | 2 - apps/audits/tasks.py | 11 +++++ apps/audits/utils.py | 45 ++++++++++++++++++- apps/audits/views.py | 3 +- apps/templates/_footer.html | 2 +- apps/users/api.py | 10 +++-- apps/users/hands.py | 1 + .../templates/users/user_granted_asset.html | 2 +- apps/users/views.py | 6 ++- requirements.txt | 1 + 11 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 apps/audits/tasks.py diff --git a/apps/audits/hands.py b/apps/audits/hands.py index 36358cbf5..281440780 100644 --- a/apps/audits/hands.py +++ b/apps/audits/hands.py @@ -1,6 +1,7 @@ # ~*~ coding: utf-8 ~*~ # +from users.utils import AdminUserRequiredMixin from users.models import User from assets.models import Asset, SystemUser from users.backends import IsSuperUserOrTerminalUser diff --git a/apps/audits/models.py b/apps/audits/models.py index a98178a0d..b2da116e3 100644 --- a/apps/audits/models.py +++ b/apps/audits/models.py @@ -22,9 +22,7 @@ class LoginLog(models.Model): login_ip = models.GenericIPAddressField(verbose_name=_('Login ip')) login_city = models.CharField(max_length=100, blank=True, null=True, verbose_name=_('Login city')) user_agent = models.CharField(max_length=100, blank=True, null=True, verbose_name=_('User agent')) - from_terminal = models.ForeignKey date_login = models.DateTimeField(auto_now_add=True, verbose_name=_('Date login')) - date_logout = models.DateTimeField(null=True, verbose_name=_('Date logout')) class Meta: db_table = 'login_log' diff --git a/apps/audits/tasks.py b/apps/audits/tasks.py new file mode 100644 index 000000000..a43d261de --- /dev/null +++ b/apps/audits/tasks.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# ~*~ coding: utf-8 ~*~ +# + +from celery import shared_task +from .utils import write_login_log + + +@shared_task +def write_login_log_async(*args, **kwargs): + write_login_log(*args, **kwargs) \ No newline at end of file diff --git a/apps/audits/utils.py b/apps/audits/utils.py index 2ad77a7e8..c495dd6a5 100644 --- a/apps/audits/utils.py +++ b/apps/audits/utils.py @@ -1,5 +1,48 @@ # ~*~ coding: utf-8 ~*~ # -from users.utils import AdminUserRequiredMixin +from __future__ import unicode_literals +import requests +import ipaddress + +from .models import LoginLog + + +def validate_ip(ip): + try: + ipaddress.ip_address(ip) + return True + except ValueError: + pass + return False + + +def write_login_log(username, name='', login_type='W', + terminal='', login_ip='', user_agent=''): + print(login_ip) + if not (login_ip and validate_ip(login_ip)): + login_ip = '0.0.0.0' + if not name: + name = username + login_city = get_ip_city(login_ip) + LoginLog.objects.create(username=username, name=name, login_type=login_type, login_ip=login_ip, + terminal=terminal, login_city=login_city, user_agent=user_agent) + + +def get_ip_city(ip, timeout=3): + # Taobao ip api: http://ip.taobao.com//service/getIpInfo.php?ip=8.8.8.8 + # Sina ip api: http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=8.8.8.8&format=js + + url = 'http://ip.taobao.com//service/getIpInfo.php?ip=' + ip + r = requests.get(url, timeout=timeout) + city = 'Unknown' + if r.status_code == 200: + try: + data = r.json() + if data['code'] == 0: + city = data['data']['country'] + data['data']['city'] + except ValueError: + pass + return city + diff --git a/apps/audits/views.py b/apps/audits/views.py index 39aa3f578..35371894b 100644 --- a/apps/audits/views.py +++ b/apps/audits/views.py @@ -11,8 +11,7 @@ from django.conf import settings from django.db.models import Q from .models import ProxyLog, CommandLog -from .utils import AdminUserRequiredMixin -from .hands import User, Asset, SystemUser +from .hands import User, Asset, SystemUser, AdminUserRequiredMixin seven_days_ago_s = (datetime.datetime.now()-datetime.timedelta(7)).strftime('%m/%d/%Y') diff --git a/apps/templates/_footer.html b/apps/templates/_footer.html index d3b860048..c43bda248 100644 --- a/apps/templates/_footer.html +++ b/apps/templates/_footer.html @@ -1,6 +1,6 @@
- +
diff --git a/apps/users/views.py b/apps/users/views.py index 212c2a262..12a71df21 100644 --- a/apps/users/views.py +++ b/apps/users/views.py @@ -28,7 +28,7 @@ from common.utils import get_object_or_none, get_logger from perms.models import AssetPermission from .models import User, UserGroup from .utils import AdminUserRequiredMixin, user_add_success_next, send_reset_password_mail -# from .hands import AssetPermission, get_user_granted_asset_groups, get_user_granted_assets +from .hands import write_login_log_async from . import forms @@ -50,6 +50,10 @@ class UserLoginView(FormView): def form_valid(self, form): auth_login(self.request, form.get_user()) + login_ip = self.request.META.get('REMOTE_ADDR', '') + user_agent = self.request.META.get('HTTP_USER_AGENT', '') + write_login_log_async.delay(self.request.user.username, self.request.user.name, + login_type='W', login_ip=login_ip, user_agent=user_agent) return redirect(self.get_success_url()) def get_success_url(self): diff --git a/requirements.txt b/requirements.txt index a89fd6191..698006f9a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,4 @@ sshpubkeys==2.2.0 djangorestframework-bulk==0.2.1 paramiko==2.0.2 django-redis-cache==1.7.1 +requests==2.11.1 \ No newline at end of file