You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2014/07/21 16:58:08 UTC

[1/3] git commit: [#7480] ticket:610 Track last active session

Repository: allura
Updated Branches:
  refs/heads/master e2978623c -> 27e3d6abc


[#7480] ticket:610 Track last active session


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/273dcf22
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/273dcf22
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/273dcf22

Branch: refs/heads/master
Commit: 273dcf229cfe8df37ea3ef6dfbf3a2b58fff3a89
Parents: 2664ba7
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 17 14:27:43 2014 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Jul 21 14:57:46 2014 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/root.py      |  2 ++
 Allura/allura/model/auth.py            | 14 ++++++++
 Allura/allura/tests/model/test_auth.py | 50 +++++++++++++++++++++++++++--
 3 files changed, 64 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/273dcf22/Allura/allura/controllers/root.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/root.py b/Allura/allura/controllers/root.py
index 9c0b147..f354872 100644
--- a/Allura/allura/controllers/root.py
+++ b/Allura/allura/controllers/root.py
@@ -87,6 +87,8 @@ class RootController(WsgiDispatchController):
         c.user = plugin.AuthenticationProvider.get(request).authenticate_request()
         assert c.user is not None, ('c.user should always be at least User.anonymous(). '
                                     'Did you run `paster setup-app` to create the database?')
+        if not c.user.is_anonymous():
+            c.user.track_active(request)
 
     def _cleanup_request(self):
         pass

http://git-wip-us.apache.org/repos/asf/allura/blob/273dcf22/Allura/allura/model/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index ff4acea..f0ad1c2 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -290,6 +290,20 @@ class User(MappedClass, ActivityNode, ActivityObject):
         self.last_access['login_ua'] = user_agent
         session(self).flush(self)
 
+    def track_active(self, req):
+        user_ip = req.headers.get('X_FORWARDED_FOR', req.remote_addr)
+        user_agent = req.headers.get('User-Agent')
+        now = datetime.utcnow()
+        last_date = self.last_access['session_date']
+        date_changed = last_date is None or last_date.date() != now.date()
+        ip_changed = user_ip != self.last_access['session_ip']
+        ua_changed = user_agent != self.last_access['session_ua']
+        if date_changed or ip_changed or ua_changed:
+            self.last_access['session_date'] = datetime.utcnow()
+            self.last_access['session_ip'] = user_ip
+            self.last_access['session_ua'] = user_agent
+            session(self).flush(self)
+
     def can_send_user_message(self):
         """Return true if User is permitted to send a mesage to another user.
 

http://git-wip-us.apache.org/repos/asf/allura/blob/273dcf22/Allura/allura/tests/model/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_auth.py b/Allura/allura/tests/model/test_auth.py
index 56ffca1..f3869ee 100644
--- a/Allura/allura/tests/model/test_auth.py
+++ b/Allura/allura/tests/model/test_auth.py
@@ -24,20 +24,23 @@ Model tests for auth
 from nose.tools import (
     with_setup,
     assert_equal,
+    assert_not_equal,
+    assert_true,
     assert_not_in,
     assert_in,
 )
 from pylons import tmpl_context as c, app_globals as g
 from webob import Request
-from mock import patch
+from mock import patch, Mock
 from datetime import datetime, timedelta
 
 from ming.orm.ormsession import ThreadLocalORMSession
+from ming.odm import session
 
 from allura import model as M
 from allura.lib import plugin
 from allura.tests import decorators as td
-from alluratest.controller import setup_basic_test, setup_global_objects
+from alluratest.controller import setup_basic_test, setup_global_objects, setup_functional_test
 
 
 def setUp():
@@ -229,3 +232,46 @@ def test_check_sent_user_message_times():
     user1.sent_user_message_times.append(
         datetime.utcnow() - timedelta(minutes=15))
     assert not user1.can_send_user_message()
+
+
+@td.with_user_project('test-admin')
+@with_setup(setUp)
+def test_user_track_active():
+    # without this session flushing inside track_active raises Exception
+    setup_functional_test()
+    c.user = M.User.by_username('test-admin')
+
+    assert_equal(c.user.last_access['session_date'], None)
+    assert_equal(c.user.last_access['session_ip'], None)
+    assert_equal(c.user.last_access['session_ua'], None)
+
+    req = Mock(headers={'User-Agent': 'browser'}, remote_addr='addr')
+    c.user.track_active(req)
+    c.user = M.User.by_username(c.user.username)
+    assert_not_equal(c.user.last_access['session_date'], None)
+    assert_equal(c.user.last_access['session_ip'], 'addr')
+    assert_equal(c.user.last_access['session_ua'], 'browser')
+
+    # ensure that session activity tracked with a whole-day granularity
+    prev_date = c.user.last_access['session_date']
+    c.user.track_active(req)
+    c.user = M.User.by_username(c.user.username)
+    assert_equal(c.user.last_access['session_date'], prev_date)
+    yesterday = datetime.utcnow() - timedelta(1)
+    c.user.last_access['session_date'] = yesterday
+    session(c.user).flush(c.user)
+    c.user.track_active(req)
+    c.user = M.User.by_username(c.user.username)
+    assert_true(c.user.last_access['session_date'] > yesterday)
+
+    # ...or if IP or User Agent has changed
+    req.remote_addr = 'new addr'
+    c.user.track_active(req)
+    c.user = M.User.by_username(c.user.username)
+    assert_equal(c.user.last_access['session_ip'], 'new addr')
+    assert_equal(c.user.last_access['session_ua'], 'browser')
+    req.headers['User-Agent'] = 'new browser'
+    c.user.track_active(req)
+    c.user = M.User.by_username(c.user.username)
+    assert_equal(c.user.last_access['session_ip'], 'new addr')
+    assert_equal(c.user.last_access['session_ua'], 'new browser')


[2/3] git commit: [#7480] ticket:610 Track login info

Posted by br...@apache.org.
[#7480] ticket:610 Track login info


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/2664ba72
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/2664ba72
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/2664ba72

Branch: refs/heads/master
Commit: 2664ba72792b6bc80fe26f033ad1e10476eefb79
Parents: e297862
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 17 13:08:53 2014 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Jul 21 14:57:46 2014 +0000

----------------------------------------------------------------------
 Allura/allura/lib/plugin.py                 |  1 +
 Allura/allura/model/auth.py                 | 15 +++++++++++++++
 Allura/allura/tests/functional/test_auth.py | 14 ++++++++++++++
 3 files changed, 30 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/2664ba72/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index eb1fb43..a5c3f65 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -144,6 +144,7 @@ class AuthenticationProvider(object):
             self.session.save()
             g.zarkov_event('login', user=user)
             g.statsUpdater.addUserLogin(user)
+            user.track_login(self.request)
             return user
         except exc.HTTPUnauthorized:
             self.logout()

http://git-wip-us.apache.org/repos/asf/allura/blob/2664ba72/Allura/allura/model/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index ed3c4d0..ff4acea 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -274,6 +274,21 @@ class User(MappedClass, ActivityNode, ActivityObject):
 
     # Statistics
     stats_id = FieldProperty(S.ObjectId, if_missing=None)
+    last_access = FieldProperty(dict(
+        login_date=S.DateTime,
+        login_ip=str,
+        login_ua=str,
+        session_date=S.DateTime,
+        session_ip=str,
+        session_ua=str))
+
+    def track_login(self, req):
+        user_ip = req.headers.get('X_FORWARDED_FOR', req.remote_addr)
+        user_agent = req.headers.get('User-Agent')
+        self.last_access['login_date'] = datetime.utcnow()
+        self.last_access['login_ip'] = user_ip
+        self.last_access['login_ua'] = user_agent
+        session(self).flush(self)
 
     def can_send_user_message(self):
         """Return true if User is permitted to send a mesage to another user.

http://git-wip-us.apache.org/repos/asf/allura/blob/2664ba72/Allura/allura/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index 1c41e8a..a200352 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -78,6 +78,20 @@ class TestAuth(TestController):
             username='test-usera', password='foo'))
         assert 'Invalid login' in str(r), r.showbrowser()
 
+    def test_track_login(self):
+        user = M.User.by_username('test-user')
+        assert_equal(user.last_access['login_date'], None)
+        assert_equal(user.last_access['login_ip'], None)
+        assert_equal(user.last_access['login_ua'], None)
+
+        self.app.post('/auth/do_login', params=dict(
+            username='test-user', password='foo'),
+            headers={'X_FORWARDED_FOR': 'addr', 'User-Agent': 'browser'})
+        user = M.User.by_username('test-user')
+        assert_not_equal(user.last_access['login_date'], None)
+        assert_equal(user.last_access['login_ip'], 'addr')
+        assert_equal(user.last_access['login_ua'], 'browser')
+
     @td.with_user_project('test-admin')
     def test_prefs(self):
         r = self.app.get('/auth/preferences/',


[3/3] git commit: [#7480] ticket:610 Add last_access field to scrub-allura-data script

Posted by br...@apache.org.
[#7480] ticket:610 Add last_access field to scrub-allura-data script


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/27e3d6ab
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/27e3d6ab
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/27e3d6ab

Branch: refs/heads/master
Commit: 27e3d6abc9b45c1d6d4dc653bb10b6062befb3e2
Parents: 273dcf2
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 17 16:33:19 2014 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Jul 21 14:57:47 2014 +0000

----------------------------------------------------------------------
 scripts/scrub-allura-data.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/27e3d6ab/scripts/scrub-allura-data.py
----------------------------------------------------------------------
diff --git a/scripts/scrub-allura-data.py b/scripts/scrub-allura-data.py
index 3864c42..337e8ae 100644
--- a/scripts/scrub-allura-data.py
+++ b/scripts/scrub-allura-data.py
@@ -125,7 +125,10 @@ def main(options):
 
     if not options.dry_run:
         M.EmailAddress.query.remove()
-        M.User.query.update({}, {"$set": {"email_addresses": []}}, multi=True)
+        M.User.query.update({}, {
+            "$set": {"email_addresses": [],
+                     "last_access": {}},
+        }, multi=True)
         DM.Forum.query.update({"monitoring_email": {"$nin": [None, ""]}},
                               {"$set": {"monitoring_email": None}}, multi=True)
     return 0