Here is a modified version for handling epxired ip log.
def limitAttemped(func):
max_attempted = tg.config.get('identity.max_attempted', 10)
expired_delay = tg.config.get('identity.expired_delay', 1800)
log = logging.getLogger('turbogears.identity')
def callee(*args, **kwargs):
result = func(*args, **kwargs)
ip = getIpAddress()
ipLog = model.IPLog.get(ip)
if ipLog is not None:
expired = ipLog.updated + datetime.timedelta
(seconds=expired_delay)
if datetime.datetime.now() > expired:
db.session.delete(ipLog)
db.session.flush()
ipLog = None
log.info('Delete expired ip log %s', ip)
if tg.identity.current.anonymous and
tg.identity.was_login_attempted():
ipLog = model.IPLog.logIp(ip)
if ipLog is not None and ipLog.times > max_attempted:
cherrypy.request.identity_exceed_max_attempted = True
tg.identity.current.logout()
log.warning('Login failed exceed limit times from %s', ip)
return result
return callee
Victor wrote:
> Hi,
>
> I want to limit times of failed login. Here is the recipe I write.
>
> #### the model
> class IPLog(Entity):
> """A table for logging ip of user who try to login with wrong
> password
>
> """
> using_options(tablename='ip_log')
> using_table_options(mysql_engine='MEMORY')
>
> # which ip
> ip = Field(String(64), primary_key=True, nullable=False)
> # how many mistake he made
> times = Field(Integer, nullable=False, default=0)
> # last login failed date time
> updated = Field(DateTime, default=datetime.now, index=True)
>
> @classmethod
> def logIp(cls, ip):
> ip = unicode(ip)
> log = cls.query.get(ip)
> if log is None:
> log = cls(ip=ip, times=0)
> log.times += 1
> log.updated = func.current_timestamp()
> return log
>
> # before root controller
>
> def getIpAddress():
> return cherrypy.request.headers.get('X-Forwarded-For',
> cherrypy.request.remote_addr)
>
> def limitAttemped(func):
> max_attempted = tg.config.get('identity.max_attempted', 10)
> def callee(*args, **kwargs):
> result = func(*args, **kwargs)
> ip = getIpAddress()
> if tg.identity.current.anonymous and
> tg.identity.was_login_attempted():
> log = model.IPLog.logIp(ip)
> else:
> log = model.IPLog.get(ip)
> if log is not None and log.times > max_attempted:
> log = logging.getLogger('turbogears.identity')
> cherrypy.request.identity_exceed_max_attempted = True
> tg.identity.current.logout()
> log.warning('Login failed exceed limit times from %s', ip)
> return result
> return callee
>
> tg.identity.visitor.IdentityVisitPlugin.record_request = \
> limitAttemped
> (tg.identity.visitor.IdentityVisitPlugin.record_request)
>
> ### login method
>
> @tg.expose(template="radioweb.templates.login")
> def login(self, forward_url=None, *args, **kw):
>
> if getattr(cherrypy.request, 'identity_exceed_max_attempted',
> False):
> flash.error(
> _('Sorry, you attempted to login exceed the limit
> times. '
> 'Please try later.')
> )
> tg.redirect(tg.url('/'))
>
>
> It works, but however, I am wondering, is there any thing I did not
> considered? Is that safe enough? If it is safe enough, I will post it
> to wiki of turbogears.
>
> Thanks.
> Victor Lin.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---