changeset 5326:7557da2252a3

auth: construct AuthUser from either user_id or db.User object If the caller already has the database User object, there's no reason for AuthUser to look it up again. The `api_key` lookup functionality is dropped, because 1) it's only used in one place, and 2) it's simple enough for the caller to do the lookup itself. The `user_id` lookup functionality is kept, because 1) it's frequently used, and 2) far from a simple `User.get(id)` lookup, it has a complex interaction with UserModel. (That cleanup will have to wait for another day.) All calls of the form `AuthUser(user_id=x.user_id)` can be replaced with `AuthUser(dbuser=x)`, assuming `x` is a db.User. However, verifying that assumption requires a manual audit of every call site, since `x` might also be another `AuthUser` object, for instance. Therefore, only the most obvious call sites have been fixed here.
author Søren Løvborg <kwi@kwi.dk>
date Sun, 26 Jul 2015 14:10:16 +0200
parents fd3e1ca9cce9
children fd80edc4aa20
files kallithea/controllers/api/__init__.py kallithea/lib/auth.py kallithea/lib/base.py kallithea/model/db.py kallithea/tests/api/api_base.py
diffstat 5 files changed, 17 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/controllers/api/__init__.py	Sun Jul 26 14:07:33 2015 +0200
+++ b/kallithea/controllers/api/__init__.py	Sun Jul 26 14:10:16 2015 +0200
@@ -158,7 +158,7 @@
                 return jsonrpc_error(retid=self._req_id,
                                      message='Invalid API key')
 
-            auth_u = AuthUser(u.user_id)
+            auth_u = AuthUser(dbuser=u)
             if not AuthUser.check_ip_allowed(auth_u, ip_addr):
                 return jsonrpc_error(retid=self._req_id,
                         message='request from IP:%s not allowed' % (ip_addr,))
--- a/kallithea/lib/auth.py	Sun Jul 26 14:07:33 2015 +0200
+++ b/kallithea/lib/auth.py	Sun Jul 26 14:10:16 2015 +0200
@@ -460,8 +460,8 @@
     but is also used as a generic user information data structure in
     parts of the code, e.g. user management.
 
-    Constructed from user ID, API key or cookie dict, it looks
-    up the matching database `User` and copies all attributes to itself,
+    Constructed from a database `User` object, a user ID or cookie dict,
+    it looks up the user (if needed) and copies all attributes to itself,
     adding various non-persistent data. If lookup fails but anonymous
     access to Kallithea is enabled, the default user is loaded instead.
 
@@ -474,7 +474,7 @@
     However, `AuthUser` does refuse to load a user that is not `active`.
     """
 
-    def __init__(self, user_id=None, api_key=None,
+    def __init__(self, user_id=None, dbuser=None,
             is_external_auth=False):
 
         self.is_authenticated = False
@@ -482,7 +482,6 @@
 
         user_model = UserModel()
         self.anonymous_user = User.get_default_user(cache=True)
-        is_user_loaded = False
 
         # These attributes will be overriden by fill_data, below, unless the
         # requested user cannot be found and the default anonymous user is
@@ -496,18 +495,15 @@
         self.admin = False
         self.inherit_default_permissions = False
 
-        # lookup by userid
+        # Look up database user, if necessary.
         if user_id is not None:
             log.debug('Auth User lookup by USER ID %s' % user_id)
-            is_user_loaded = user_model.fill_data(self, user_model.get(user_id))
+            dbuser = user_model.get(user_id)
+        else:
+            # Note: dbuser is allowed to be None.
+            log.debug('Auth User lookup by database user %s', dbuser)
 
-        # try go get user by API key
-        elif api_key:
-            log.debug('Auth User lookup by API key %s' % api_key)
-            is_user_loaded = user_model.fill_data(self, User.get_by_api_key(api_key))
-
-        else:
-            log.debug('No data in %s that could been used to log in' % self)
+        is_user_loaded = user_model.fill_data(self, dbuser)
 
         # If user cannot be found, try falling back to anonymous.
         if not is_user_loaded:
--- a/kallithea/lib/base.py	Sun Jul 26 14:07:33 2015 +0200
+++ b/kallithea/lib/base.py	Sun Jul 26 14:10:16 2015 +0200
@@ -115,7 +115,7 @@
     user.update_lastlogin()
     meta.Session().commit()
 
-    auth_user = AuthUser(user_id=user.user_id,
+    auth_user = AuthUser(dbuser=user,
                          is_external_auth=is_external_auth)
     auth_user.set_authenticated()
 
@@ -385,7 +385,8 @@
         # Authenticate by API key
         if api_key:
             # when using API_KEY we are sure user exists.
-            return AuthUser(api_key=api_key, is_external_auth=True)
+            return AuthUser(dbuser=User.get_by_api_key(api_key),
+                            is_external_auth=True)
 
         # Authenticate by session cookie
         # In ancient login sessions, 'authuser' may not be a dict.
--- a/kallithea/model/db.py	Sun Jul 26 14:07:33 2015 +0200
+++ b/kallithea/model/db.py	Sun Jul 26 14:10:16 2015 +0200
@@ -511,7 +511,7 @@
         Returns instance of AuthUser for this user
         """
         from kallithea.lib.auth import AuthUser
-        return AuthUser(user_id=self.user_id)
+        return AuthUser(dbuser=self)
 
     @hybrid_property
     def user_data(self):
--- a/kallithea/tests/api/api_base.py	Sun Jul 26 14:07:33 2015 +0200
+++ b/kallithea/tests/api/api_base.py	Sun Jul 26 14:10:16 2015 +0200
@@ -235,7 +235,7 @@
 
         usr = User.get_by_username(TEST_USER_ADMIN_LOGIN)
         ret = usr.get_api_data()
-        ret['permissions'] = AuthUser(usr.user_id).permissions
+        ret['permissions'] = AuthUser(dbuser=usr).permissions
 
         expected = ret
         self._compare_ok(id_, expected, given=response.body)
@@ -254,7 +254,7 @@
 
         usr = User.get_by_username(TEST_USER_ADMIN_LOGIN)
         ret = usr.get_api_data()
-        ret['permissions'] = AuthUser(usr.user_id).permissions
+        ret['permissions'] = AuthUser(dbuser=usr).permissions
 
         expected = ret
         self._compare_ok(id_, expected, given=response.body)
@@ -265,7 +265,7 @@
 
         usr = User.get_by_username(self.TEST_USER_LOGIN)
         ret = usr.get_api_data()
-        ret['permissions'] = AuthUser(usr.user_id).permissions
+        ret['permissions'] = AuthUser(dbuser=usr).permissions
 
         expected = ret
         self._compare_ok(id_, expected, given=response.body)