From d5f6b2b41455377b9db65a1ad05558227c7dcf56 Mon Sep 17 00:00:00 2001 From: Firmlyzhu Date: Wed, 12 Dec 2018 19:10:05 +0800 Subject: [PATCH] Add LoginFailMsg into model & Ban user if he input wrong password for many times. --- conf/nginx_docklet.conf | 5 ++++- src/master/userManager.py | 31 ++++++++++++++++++++++++++++--- src/utils/model.py | 14 ++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/conf/nginx_docklet.conf b/conf/nginx_docklet.conf index 1ab42ad..d97042a 100644 --- a/conf/nginx_docklet.conf +++ b/conf/nginx_docklet.conf @@ -1,6 +1,9 @@ server { - listen %NGINX_PORT; + listen %NGINX_PORT; + #ssl on; + #ssl_certificate /etc/nginx/ssl/1604242_iwork.pku.edu.cn.pem; + #ssl_certificate_key /etc/nginx/ssl/1604242_iwork.pku.edu.cn.key; server_name nginx_docklet.conf; charset UTF-8; add_header X-Frame-Options SAMEORIGIN; diff --git a/src/master/userManager.py b/src/master/userManager.py index 782217f..4f7d5f1 100755 --- a/src/master/userManager.py +++ b/src/master/userManager.py @@ -7,7 +7,7 @@ Warning: in some early versions, "token" stand for the instance of class model.U Original author: Liu Peidong ''' -from utils.model import db, User, UserGroup, Notification, UserUsage, LoginMsg +from utils.model import db, User, UserGroup, Notification, UserUsage, LoginMsg, LoginFailMsg from functools import wraps import os, subprocess, math import hashlib @@ -19,7 +19,7 @@ import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.header import Header -from datetime import datetime +from datetime import datetime, timedelta import json from utils.log import logger from utils.lvmtool import * @@ -144,7 +144,6 @@ class userManager: ''' try: User.query.all() - LoginMsg.query.all() except: db.create_all() if password == None: @@ -202,6 +201,8 @@ class userManager: try: UserUsage.query.all() + LoginMsg.query.all() + LoginFailMsg.query.all() except: db.create_all() @@ -327,7 +328,22 @@ class userManager: return a token as well as some user information ''' user = User.query.filter_by(username = username).first() + failmsg = LoginFailMsg.query.filter_by(username = username).first() result = {} + if failmsg == None: + newfailmsg = LoginFailMsg(username) + db.session.add(newfailmsg) + db.session.commit() + failmsg = newfailmsg + elif failmsg.failcnt > 40: + reason = "You have been input wrong password over 40 times. You account will be locked. Please contact administrators for help." + logger.info("Login failed: userip=%s reason:%s" % (userip,reason)) + return {'success':'false', 'reason':reason} + elif datetime.now() < failmsg.bantime: + reason = "You have been input wrong password %d times. Please try after %s." % (failmsg.failcnt, failmsg.bantime.strftime("%Y-%m-%d %H:%M:%S")) + logger.info("Login failed: userip=%s reason:%s" % (userip,reason)) + return {'success':'false', 'reason':reason} + if (user == None or user.auth_method =='local'): result = self.auth_local(username, password) elif (user.auth_method == 'pam'): @@ -337,11 +353,20 @@ class userManager: if result['success'] == 'true': loginmsg = LoginMsg(result['data']['username'],userip) + failmsg.failcnt = 0 db.session.add(loginmsg) db.session.commit() logger.info("Login success: username=%s, userip=%s" % (result['data']['username'], userip)) else: logger.info("Login failed: userip=%s" % (userip)) + failmsg.failcnt += 1 + if failmsg.failcnt == 10: + failmsg.bantime = datetime.now() + timedelta(minutes=10) + elif failmsg.failcnt == 20: + failmsg.bantime = datetime.now() + timedelta(minutes=100) + elif failmsg.failcnt == 30: + failmsg.bantime = datetime.now() + timedelta(days=1) + db.session.commit() return result def auth_token(self, token): diff --git a/src/utils/model.py b/src/utils/model.py index f8e9651..37ef56c 100755 --- a/src/utils/model.py +++ b/src/utils/model.py @@ -221,6 +221,20 @@ class LoginMsg(db.Model): def __repr__(self): return '' % (self.id,self.username,self.userip,self.time.strftime("%Y-%m-%d %H:%M:%S")) +class LoginFailMsg(db.Model): + id = db.Column(db.Integer, primary_key=True) + username = db.Column(db.String(10), unique=True) + failcnt = db.Column(db.Integer) + bantime = db.Column(db.DateTime) + + def __init__(self, username): + self.username = username + self.failcnt = 0 + self.bantime = datetime.now() + + def __repr__(self): + return '' % (self.id,self.username,self.failcnt,self.bantime.strftime("%Y-%m-%d %H:%M:%S")) + class VNode(db.Model): __bind_key__ = 'history' name = db.Column(db.String(100), primary_key=True)