changeset 1277:f0d1cbe58e53

refactored "trusted" user handling there is a new .trusted user object attribute now. all authenticator constructors have a parameter trusted=True/False now (implemented in the base class). if one sets it to True, user objects created by that authenticator will have u.trusted = True. The default is False. it is also stored into the session, so user object created from a session have .trusted also maintained. Killed cfg.auth_methods_trusted, can be done more easily now. Refactored all auth classes to user super() to call the base class __init__ with any keywords they did not use. If the base class gets keywords it does not know, it raises a TypeError.
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sat, 03 Mar 2012 16:37:14 +0100
parents a3da549dc32e
children 2c58cbcfeabe
files MoinMoin/_tests/__init__.py MoinMoin/app.py MoinMoin/apps/frontend/views.py MoinMoin/auth/__init__.py MoinMoin/auth/http.py MoinMoin/auth/ldap_login.py MoinMoin/auth/log.py MoinMoin/auth/openidrp.py MoinMoin/auth/smb_mount.py MoinMoin/config/default.py MoinMoin/security/__init__.py MoinMoin/user.py
diffstat 12 files changed, 44 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/_tests/__init__.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/_tests/__init__.py	Sat Mar 03 16:37:14 2012 +0100
@@ -41,7 +41,7 @@
 def become_trusted(username=u"TrustedUser"):
     """ modify flaskg.user to make the user valid and trusted, so it is in acl group Trusted """
     become_valid(username)
-    flaskg.user.auth_method = app.cfg.auth_methods_trusted[0]
+    flaskg.user.trusted = True
 
 
 # Creating and destroying test items --------------------------------
--- a/MoinMoin/app.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/app.py	Sat Mar 03 16:37:14 2012 +0100
@@ -215,6 +215,7 @@
     # if we have a valid user we store it in the session
     if userobj.valid:
         session['user.itemid'] = userobj.itemid
+        session['user.trusted'] = userobj.trusted
         session['user.auth_method'] = userobj.auth_method
         session['user.auth_attribs'] = userobj.auth_attribs
     return userobj
--- a/MoinMoin/apps/frontend/views.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/apps/frontend/views.py	Sat Mar 03 16:37:14 2012 +0100
@@ -1203,7 +1203,7 @@
 
 
 def _logout():
-    for key in ['user.itemid', 'user.auth_method', 'user.auth_attribs', ]:
+    for key in ['user.itemid', 'user.trusted', 'user.auth_method', 'user.auth_attribs', ]:
         if key in session:
             del session[key]
 
--- a/MoinMoin/auth/__init__.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/auth/__init__.py	Sat Mar 03 16:37:14 2012 +0100
@@ -1,7 +1,7 @@
 # Copyright: 2005-2006 Bastian Blank, Florian Festi
 # Copyright: MoinMoin:AlexanderSchremmer, Nick Phillips
 # Copyright: MoinMoin:FrankieChow, MoinMoin:NirSoffer
-# Copyright: 2005-2009 MoinMoin:ThomasWaldmann
+# Copyright: 2005-2012 MoinMoin:ThomasWaldmann
 # Copyright: 2007      MoinMoin:JohannesBerg
 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
 
@@ -202,8 +202,10 @@
     name = None
     login_inputs = []
     logout_possible = False
-    def __init__(self):
-        pass
+    def __init__(self, trusted=False, **kw):
+        self.trusted = trusted
+        if kw:
+            raise TypeError("got unexpected arguments %r" % kw)
     def login(self, user_obj, **kw):
         return ContinueLogin(user_obj)
     def request(self, user_obj, **kw):
@@ -218,8 +220,8 @@
 
 class MoinAuth(BaseAuth):
     """ handle login from moin login form """
-    def __init__(self):
-        BaseAuth.__init__(self)
+    def __init__(self, **kw):
+        super(MoinAuth, self).__init__(**kw)
 
     login_inputs = ['username', 'password']
     name = 'moin'
@@ -241,7 +243,7 @@
         if username and not password:
             return ContinueLogin(user_obj, _('Missing password. Please enter user name and password.'))
 
-        u = user.User(name=username, password=password, auth_method=self.name)
+        u = user.User(name=username, password=password, auth_method=self.name, trusted=self.trusted)
         if u.valid:
             logging.debug("{0}: successfully authenticated user {1!r} (valid)".format(self.name, u.name))
             return ContinueLogin(u)
@@ -276,7 +278,9 @@
                  titlecase=False,  # joe doe -> Joe Doe
                  remove_blanks=False,  # Joe Doe -> JoeDoe
                  coding='utf-8',  # for decoding REMOTE_USER correctly
+                 **kw
                 ):
+        super(GivenAuth, self).__init__(**kw)
         self.env_var = env_var
         self.user_name = user_name
         self.autocreate = autocreate
@@ -285,7 +289,6 @@
         self.titlecase = titlecase
         self.remove_blanks = remove_blanks
         self.coding = coding
-        BaseAuth.__init__(self)
 
     def decode_username(self, name):
         """ decode the name we got from the environment var to unicode """
@@ -341,7 +344,7 @@
             auth_username = self.transform_username(auth_username)
             logging.debug("auth_username (after decode/transform) = {0!r}".format(auth_username))
             u = user.User(auth_username=auth_username,
-                          auth_method=self.name, auth_attribs=('name', 'password'))
+                          auth_method=self.name, auth_attribs=('name', 'password'), trusted=self.trusted)
 
         logging.debug("u: {0!r}".format(u))
         if u and self.autocreate:
@@ -427,15 +430,17 @@
 def setup_from_session():
     userobj = None
     if 'user.itemid' in session:
-        auth_userid = session['user.itemid']
+        itemid = session['user.itemid']
+        trusted = session['user.trusted']
         auth_method = session['user.auth_method']
-        auth_attrs = session['user.auth_attribs']
-        logging.debug("got from session: {0!r} {1!r}".format(auth_userid, auth_method))
+        auth_attribs = session['user.auth_attribs']
+        logging.debug("got from session: {0!r} {1!r} {2!r} {3!r}".format(itemid, trusted, auth_method, auth_attribs))
         logging.debug("current auth methods: {0!r}".format(app.cfg.auth_methods))
         if auth_method and auth_method in app.cfg.auth_methods:
-            userobj = user.User(auth_userid,
+            userobj = user.User(itemid,
                                 auth_method=auth_method,
-                                auth_attribs=auth_attrs)
+                                auth_attribs=auth_attribs,
+                                trusted=trusted)
     logging.debug("session started for user {0!r}".format(userobj))
     return userobj
 
--- a/MoinMoin/auth/http.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/auth/http.py	Sat Mar 03 16:37:14 2012 +0100
@@ -14,8 +14,6 @@
 
     from MoinMoin.auth.http import HTTPAuthMoin
     auth = [HTTPAuthMoin()]
-    # check if you want 'http' auth name in there:
-    auth_methods_trusted = ['http', ]
 """
 
 
@@ -33,11 +31,11 @@
     """ authenticate via http (basic) auth """
     name = 'http'
 
-    def __init__(self, autocreate=False, realm='MoinMoin', coding='iso-8859-1'):
+    def __init__(self, autocreate=False, realm='MoinMoin', coding='iso-8859-1', **kw):
+        super(HTTPAuthMoin, self).__init__(**kw)
         self.autocreate = autocreate
         self.realm = realm
         self.coding = coding
-        BaseAuth.__init__(self)
 
     def request(self, user_obj, **kw):
         u = None
@@ -53,7 +51,7 @@
             logging.debug("http basic auth, received username: {0!r} password: {1!r}".format(auth.username, auth.password))
             u = user.User(name=auth.username.decode(self.coding),
                           password=auth.password.decode(self.coding),
-                          auth_method=self.name, auth_attribs=[])
+                          auth_method=self.name, auth_attribs=[], trusted=self.trusted)
             logging.debug("user: {0!r}".format(u))
 
         if not u or not u.valid:
--- a/MoinMoin/auth/ldap_login.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/auth/ldap_login.py	Sat Mar 03 16:37:14 2012 +0100
@@ -86,7 +86,9 @@
         autocreate=False, # set to True if you want to autocreate user profiles
         name='ldap', # use e.g. 'ldap_pdc' and 'ldap_bdc' (or 'ldap1' and 'ldap2') if you auth against 2 ldap servers
         report_invalid_credentials=True, # whether to emit "invalid username or password" msg at login time or not
+        **kw
         ):
+        super(LDAPAuth, self).__init__(**kw)
         self.server_uri = server_uri
         self.bind_dn = bind_dn
         self.bind_pw = bind_pw
@@ -232,10 +234,12 @@
                     username = self.name_callback(ldap_dict)
 
                 if email:
-                    u = user.User(auth_username=username, auth_method=self.name, auth_attribs=('name', 'password', 'email', 'mailto_author', ))
+                    u = user.User(auth_username=username, auth_method=self.name, auth_attribs=('name', 'password', 'email', 'mailto_author', ),
+                                  trusted=self.trusted)
                     u.email = email
                 else:
-                    u = user.User(auth_username=username, auth_method=self.name, auth_attribs=('name', 'password', 'mailto_author', ))
+                    u = user.User(auth_username=username, auth_method=self.name, auth_attribs=('name', 'password', 'mailto_author', ),
+                                  trusted=self.trusted)
                 u.name = username
                 u.aliasname = aliasname
                 logging.debug("creating user object with name {0!r} email {1!r} alias {2!r}".format(username, email, aliasname))
--- a/MoinMoin/auth/log.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/auth/log.py	Sat Mar 03 16:37:14 2012 +0100
@@ -18,6 +18,9 @@
     """ just log the call, do nothing else """
     name = "log"
 
+    def __init__(self, **kw):
+        super(AuthLog, self).__init__(**kw)
+
     def log(self, action, user_obj, kw):
         logging.info('{0}: user_obj={1!r} kw={2!r}'.format(action, user_obj, kw))
 
--- a/MoinMoin/auth/openidrp.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/auth/openidrp.py	Sat Mar 03 16:37:14 2012 +0100
@@ -26,7 +26,8 @@
 
 
 class OpenIDAuth(BaseAuth):
-    def __init__(self, trusted_providers=[]):
+    def __init__(self, trusted_providers=[], **kw):
+        super(OpenIDAuth, self).__init__(**kw)
         # the name
         self.name = 'openid'
         # we only need openid
@@ -37,7 +38,6 @@
         self.store = MemoryStore()
 
         self._trusted_providers = list(trusted_providers)
-        BaseAuth.__init__(self)
 
     def _handleContinuationVerify(self):
         """
@@ -83,7 +83,7 @@
                 # we get the user with this openid associated to him
                 identity = oid_info.identity_url
                 users = user.search_users(openid=identity)
-                user_obj = users and user.User(users[0][ITEMID])
+                user_obj = users and user.User(users[0][ITEMID], trusted=self.trusted)
 
                 # if the user actually exists
                 if user_obj:
--- a/MoinMoin/auth/smb_mount.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/auth/smb_mount.py	Sat Mar 03 16:37:14 2012 +0100
@@ -34,8 +34,9 @@
         iocharset='utf-8', # mount.cifs -o iocharset=... (try 'iso8859-1' if default does not work)
         coding='utf-8', # encoding used for username/password/cmdline (try 'iso8859-1' if default does not work)
         log='/dev/null', # logfile for mount.cifs output
+        **kw
         ):
-        BaseAuth.__init__(self)
+        super(SMBMount, self).__init__(**kw)
         self.server = server
         self.share = share
         self.mountpoint_fn = mountpoint_fn
--- a/MoinMoin/config/default.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/config/default.py	Sat Mar 03 16:37:14 2012 +0100
@@ -301,8 +301,6 @@
   'auth': ('Authentication / Authorization / Security settings', None, (
     ('auth', DefaultExpression('[MoinAuth()]'),
      "list of auth objects, to be called in this order (see HelpOnAuthentication)"),
-    ('auth_methods_trusted', ['http', 'given', ], # Note: 'http' auth method is currently just a redirect to 'given'
-     'authentication methods for which users should be included in the special "Trusted" ACL group.'),
     ('secrets', None, """Either a long shared secret string used for multiple purposes or a dict {"purpose": "longsecretstring", ...} for setting up different shared secrets for different purposes."""),
     ('SecurityPolicy',
      None,
--- a/MoinMoin/security/__init__.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/security/__init__.py	Sat Mar 03 16:37:14 2012 +0100
@@ -262,12 +262,12 @@
         return None
 
     def _special_Trusted(self, name, dowhat, rightsdict):
-        """ check if user <name> is known AND has logged in using a trusted
-            authentication method.
+        """ check if user <name> is the current user AND is has logged in using
+            an authentication method that set the trusted attribute.
             Does not work for subsription emails that should be sent to <user>,
-            as he is not logged in in that case.
+            as the user is not logged in in that case.
         """
-        if flaskg.user.name == name and flaskg.user.auth_trusted:
+        if flaskg.user.name == name and flaskg.user.trusted:
             return rightsdict.get(dowhat)
         return None
 
--- a/MoinMoin/user.py	Sat Mar 03 02:55:40 2012 +0100
+++ b/MoinMoin/user.py	Sat Mar 03 16:37:14 2012 +0100
@@ -246,7 +246,7 @@
 class User(object):
     """ A MoinMoin User """
 
-    def __init__(self, uid=None, name="", password=None, auth_username="", **kw):
+    def __init__(self, uid=None, name="", password=None, auth_username="", trusted=False, **kw):
         """ Initialize User object
 
         :param uid: (optional) user ID
@@ -264,6 +264,7 @@
         self.profile = UserProfile()
         self._cfg = app.cfg
         self.valid = False
+        self.trusted = trusted # trusted auth methods can set this to True
         self.auth_method = kw.get('auth_method', 'internal')
         self.auth_attribs = kw.get('auth_attribs', ())
 
@@ -312,13 +313,6 @@
             return object.__getattr__(self, name)
 
     @property
-    def auth_trusted(self):
-        # TODO: auth_trusted should be set by the auth method (auth class
-        # could have a param where the admin could tell whether he wants to
-        # trust it)
-        return self.auth_method in app.cfg.auth_methods_trusted
-
-    @property
     def language(self):
         l = self._cfg.language_default
         locale = self.locale  # is either None or something like 'en_US'