# HG changeset patch # User Søren Løvborg # Date 1437912616 -7200 # Node ID 7557da2252a39631a0e56a5a5f02cd199605cd63 # Parent fd3e1ca9cce9efe30e9eca30791d5151a9e60bd3 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. diff -r fd3e1ca9cce9 -r 7557da2252a3 kallithea/controllers/api/__init__.py --- 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,)) diff -r fd3e1ca9cce9 -r 7557da2252a3 kallithea/lib/auth.py --- 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: diff -r fd3e1ca9cce9 -r 7557da2252a3 kallithea/lib/base.py --- 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. diff -r fd3e1ca9cce9 -r 7557da2252a3 kallithea/model/db.py --- 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): diff -r fd3e1ca9cce9 -r 7557da2252a3 kallithea/tests/api/api_base.py --- 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)