changeset 501:069acf15d7b3

moin account {check,create,disable} script commands imported from: moin--main--1.5--patch-505
author Thomas Waldmann <tw@waldmann-edv.de>
date Sun, 26 Mar 2006 12:23:13 +0000
parents b3c18ea7db7d
children 55691a4d867a
files ChangeLog MoinMoin/script/account/__init__.py MoinMoin/script/account/check.py MoinMoin/script/account/create.py MoinMoin/script/account/disable.py MoinMoin/script/old/accounts/.cvsignore MoinMoin/script/old/accounts/__init__.py MoinMoin/script/old/accounts/moin_usercheck-jh-new.py MoinMoin/script/old/accounts/moin_usercheck.py docs/CHANGES setup.py
diffstat 11 files changed, 418 insertions(+), 553 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Mar 26 10:01:15 2006 +0000
+++ b/ChangeLog	Sun Mar 26 12:23:13 2006 +0000
@@ -2,6 +2,49 @@
 # arch-tag: automatic-ChangeLog--arch@arch.thinkmo.de--2003-archives/moin--main--1.5
 #
 
+2006-03-26 13:23:13 GMT	Thomas Waldmann <tw@waldmann-edv.de>	patch-505
+
+    Summary:
+      moin account {check,create,disable} script commands
+    Revision:
+      moin--main--1.5--patch-505
+
+    moin account {check,create,disable} script commands
+    
+
+    new files:
+     MoinMoin/script/account/.arch-ids/=id
+     MoinMoin/script/account/.arch-ids/__init__.py.id
+     MoinMoin/script/account/.arch-ids/check.py.id
+     MoinMoin/script/account/.arch-ids/create.py.id
+     MoinMoin/script/account/.arch-ids/disable.py.id
+     MoinMoin/script/account/__init__.py
+     MoinMoin/script/account/check.py
+     MoinMoin/script/account/create.py
+     MoinMoin/script/account/disable.py
+
+    removed files:
+     MoinMoin/script/old/accounts/.arch-ids/.cvsignore.id
+     MoinMoin/script/old/accounts/.arch-ids/=id
+     MoinMoin/script/old/accounts/.arch-ids/__init__.py.id
+     MoinMoin/script/old/accounts/.arch-ids/moin_usercheck-jh-new.py.id
+     MoinMoin/script/old/accounts/.arch-ids/moin_usercheck.py.id
+     MoinMoin/script/old/accounts/.cvsignore
+     MoinMoin/script/old/accounts/__init__.py
+     MoinMoin/script/old/accounts/moin_usercheck-jh-new.py
+     MoinMoin/script/old/accounts/moin_usercheck.py
+
+    modified files:
+     ChangeLog docs/CHANGES setup.py
+
+    new directories:
+     MoinMoin/script/account MoinMoin/script/account/.arch-ids
+
+    removed directories:
+     MoinMoin/script/old/accounts
+     MoinMoin/script/old/accounts/.arch-ids
+
+
 2006-03-26 11:01:15 GMT	Thomas Waldmann <tw@waldmann-edv.de>	patch-504
 
     Summary:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/script/account/__init__.py	Sun Mar 26 12:23:13 2006 +0000
@@ -0,0 +1,14 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - User Accounts Script Package
+
+    @copyright: 2006 by Thomas Waldmann
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin.util import pysupport
+
+# create a list of extension scripts from the subpackage directory
+account_scripts = pysupport.getPackageModules(__file__)
+modules = account_scripts
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/script/account/check.py	Sun Mar 26 12:23:13 2006 +0000
@@ -0,0 +1,252 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - check / process user accounts
+
+    @copyright: 2003-2006 by MoinMoin:ThomasWaldmann
+    @license: GNU GPL, see COPYING for details.
+
+    Why is this needed?
+    ===================
+    When using ACLs, a wiki user name has to be unique, there must not be
+    multiple accounts having the same username. The problem is, that this
+    was possible before the introduction of ACLs and many users, who forgot
+    their ID, simply created a new ID using the same user name.
+
+    Because access rights (when using ACLs) depend on the NAME (not the ID),
+    this must be cleaned up before using ACLs or users will have difficulties
+    changing settings and saving their account data (system won't accept the
+    save, if the user name and email is not unique).
+
+    How to use this tool?
+    =====================
+
+    General syntax: moin [options] account check [check-options]
+    
+    [options] usually should be:
+        --config-dir=/path/to/my/cfg/ --wiki-url=wiki.example.org/
+    
+    [check-options] see below:
+    
+    0. Check the settings at top of the code!
+       Making a backup of your wiki might be also a great idea.
+       
+    1. Best is to first look at duplicate user names:
+       moin ... account check --usersunique
+
+       If everything looks OK there, you may save that to disk:
+       moin ... account check --usersunique --save
+
+    2. Now, check also for duplicate email addresses:
+       moin ... account check --emailsunique
+
+       If everything looks OK, you may save that to disk:
+       moin ... account check --emailsunique --save
+
+    3. If the announced action is incorrect, you may choose to better manually
+       disable some accounts: moin ... account disable --uid 1234567.8.90
+
+    4. After cleaning up, do 1. and 2. again. There should be no output now, if
+       everything is OK.
+       
+    5. Optionally you may want to make wikinames out of the user names
+       moin ... account check --wikinames
+       moin ... account check --wikinames --save
+        
+"""
+
+# ----------------------------------------------------------------------------
+# if a user subsribes to magicpages, it means that he wants to keep
+# exactly THIS account - this will avoid deleting it.
+magicpages = [
+    "ThisAccountIsCorrect", 
+    "DieserAccountIstRichtig",
+]
+
+# ----------------------------------------------------------------------------
+
+import os
+
+from MoinMoin.script._util import MoinScript
+from MoinMoin import user, wikiutil
+
+class PluginScript(MoinScript):
+    def __init__(self, argv, def_values):
+        MoinScript.__init__(self, argv, def_values)
+        self._addFlag("usersunique",
+            "Makes user names unique (by appending the ID to"
+            " name and email, disabling subscribed pages and"
+            " disabling all, but the latest saved user account);"
+            " default is to SHOW what will be happening, you"
+            " need to give the --save option to really do it."
+        )
+        self._addFlag("emailsunique",
+            "Makes user emails unique;"
+            " default is to show, use --save to save it."
+        )
+        self._addFlag("wikinames",
+            "Convert user account names to wikinames (camel-case)."
+        )
+        self._addFlag("lastsaved",
+            "Normally the account most recently USED will"
+            " survive and the others will be disabled."
+            " Using --lastsaved, the account most recently"
+            " SAVED will survive."
+        )
+        self._addFlag("save",
+            "If specified as LAST option, will allow the other"
+            " options to save user accounts back to disk."
+            " If not specified, no settings will be changed permanently."
+        )
+        self._addFlag("removepasswords",
+            "Remove pre-1.1 cleartext passwords from accounts."
+        )
+
+    def _addFlag(self, name, help):
+        self.parser.add_option("--" + name,
+            action="store_true", dest=name, default=0, help=help)
+
+    def collect_data(self):
+        import re
+        request = self.request
+        for uid in user.getUserList(request):
+            u = user.User(request, uid)
+            self.users[uid] = u
+    
+            # collect name duplicates:
+            if self.names.has_key(u.name):
+                self.names[u.name].append(uid)
+            else:
+                self.names[u.name] = [uid]
+    
+            # collect email duplicates:
+            if u.email:
+                if self.emails.has_key(u.email):
+                    self.emails[u.email].append(uid)
+                else:
+                    self.emails[u.email] = [uid]
+    
+            # collect account with no or invalid email address set:
+            if not u.email or not re.match(".*@.*\..*", u.email):
+                self.uids_noemail[uid] = u.name
+    
+    def hasmagicpage(self, uid):
+        u = self.users[uid]
+        return u.isSubscribedTo(magicpages)
+    
+    def disableUser(self, uid):
+        u = self.users[uid]
+        print " %-20s %-30r %-35r" % (uid, u.name, u.email),
+        keepthis = self.hasmagicpage(uid)
+        if keepthis:
+            print "- keeping (magicpage)!"
+            u.save() # update timestamp, so this will be latest next run
+        elif not u.disabled: # only disable once
+            u.disabled = 1
+            u.name = "%s-%s" % (u.name, uid)
+            if u.email:
+                u.email = "%s-%s" % (u.email, uid)
+            u.subscribed_pages = "" # avoid using email
+            if self.options.save:
+                u.save()
+                print "- disabled."
+            else:
+                print "- would be disabled."
+    
+    def getsortvalue(self, uid, user):
+        t_ls = float(user.last_saved) # when user did last SAVE of his account data
+        if self.options.lastsaved:
+            return t_ls
+        else: # last USED (we check the page trail for that)
+            try:
+                t_lu = float(os.path.getmtime(os.path.join(self.request.cfg.user_dir, "%s.trail" % uid)))
+            except OSError:
+                t_lu = t_ls # better than having nothing
+            return t_lu
+    
+    def process(self, uidlist):
+        sortlist = []
+        for uid in uidlist:
+            u = self.users[uid]
+            sortlist.append((self.getsortvalue(uid, u), uid))
+        sortlist.sort()
+        #print sortlist
+        # disable all, but the last/latest one
+        for t, uid in sortlist[:-1]:
+            self.disableUser(uid)
+        # show what will be kept
+        uid = sortlist[-1][1]
+        u = self.users[uid]
+        print " %-20s %-30r %-35r - keeping%s!" % (uid, u.name, u.email, self.hasmagicpage(uid) and " (magicpage)" or "")
+    
+    def make_users_unique(self):
+        for name, uids in self.names.items():
+            if len(uids) > 1:
+                self.process(uids)
+    
+    def make_emails_unique(self):
+        for email, uids in self.emails.items():
+            if len(uids) > 1:
+                self.process(uids)
+    
+    def make_WikiNames(self):
+        import string
+        for uid, u in self.users.items():
+            if u.disabled:
+                continue
+            if not wikiutil.isStrictWikiname(u.name):
+                newname = string.capwords(u.name).replace(" ", "").replace("-", "")
+                if not wikiutil.isStrictWikiname(newname):
+                    print " %-20s %-30r - no WikiName, giving up" % (uid, u.name)
+                else:
+                    print " %-20s %-30r - no WikiName -> %r" % (uid, u.name, newname)
+                    if self.options.save:
+                        u.name = newname
+                        u.save()
+
+    def remove_passwords(self):
+        for uid, u in self.users.items():
+            # user.User already clears the old cleartext passwords on loading,
+            # so nothing to do here!
+            if save:
+                # we can't encrypt the cleartext password as it is cleared
+                # already. and we would not trust it anyway, so we don't WANT
+                # to do that either!
+                # Just save the account data without cleartext password:
+                print " %-20s %-25s - saving" % (uid, u.name)
+                u.save()
+
+    def mainloop(self):
+        import os, sys
+
+        # we don't expect non-option arguments
+        if len(self.args) != 0:
+            self.parser.error("incorrect number of arguments")
+
+        # check for correct option combination
+        flags_given = (self.options.usersunique 
+                    or self.options.emailsunique 
+                    or self.options.wikinames
+                    or self.options.removepasswords)
+
+        # no option given ==> show usage
+        if not flags_given:
+            self.parser.print_help()
+            sys.exit(1)
+
+        self.init_request()
+
+        self.users = {} # uid : UserObject
+        self.names = {} # name : [uid, uid, uid]
+        self.emails = {} # email : [uid, uid, uid]
+        self.uids_noemail = {} # uid : name
+
+        self.collect_data()
+        if self.options.usersunique:
+            self.make_users_unique()
+        if self.options.emailsunique: 
+            self.make_emails_unique()
+        if self.options.wikinames:
+            self.make_WikiNames()
+        if self.options.removepasswords:
+            self.remove_passwords()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/script/account/create.py	Sun Mar 26 12:23:13 2006 +0000
@@ -0,0 +1,52 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - create a user account
+
+    @copyright: 2006 by MoinMoin:ThomasWaldmann
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin.script._util import MoinScript
+
+class PluginScript(MoinScript):
+    def __init__(self, argv, def_values):
+        MoinScript.__init__(self, argv, def_values)
+        self.parser.add_option(
+            "--name", metavar="NAME", dest="uname",
+            help="Set the wiki user name to NAME."
+        )
+        self.parser.add_option(
+            "--alias", metavar="ALIAS", dest="ualiasname",
+            help="Set the wiki user alias name to ALIAS (e.g. the real name if NAME is cryptic)."
+        )
+        self.parser.add_option(
+            "--email", metavar="EMAIL", dest="email",
+            help="Set the user's email address to EMAIL."
+        )
+        self.parser.add_option(
+            "--password", metavar="PASSWORD", dest="password",
+            help="Set the user's password to PASSWORD (either cleartext or {SHA1}...)."
+        )
+
+    def mainloop(self):
+        # we don't expect non-option arguments
+        if len(self.args) != 0:
+            self.parser.error("incorrect number of arguments")
+
+        flags_given = self.options.uname and self.options.email
+        if not flags_given:
+            self.parser.print_help()
+            import sys
+            sys.exit(1)
+
+        self.init_request()
+        request = self.request
+
+        from MoinMoin import user, wikiutil
+        u = user.User(request, None, self.options.uname, password=self.options.password)
+        u.email = self.options.email
+        u.aliasname = self.options.ualiasname or ''
+        print " %-20s %-25s %-35s" % (u.id, u.name, u.email),
+        u.save()
+        print "- created."
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/script/account/disable.py	Sun Mar 26 12:23:13 2006 +0000
@@ -0,0 +1,53 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - disable a user account
+
+    @copyright: 2006 by MoinMoin:ThomasWaldmann
+    @license: GNU GPL, see COPYING for details.
+"""
+
+from MoinMoin.script._util import MoinScript
+
+class PluginScript(MoinScript):
+    def __init__(self, argv, def_values):
+        MoinScript.__init__(self, argv, def_values)
+        self.parser.add_option(
+            "--uid", metavar="UID", dest="uid",
+            help="Disable the user with user id UID."
+        )
+        self.parser.add_option(
+            "--name", metavar="NAME", dest="uname",
+            help="Disable the user with user name NAME."
+        )
+
+    def mainloop(self):
+        # we don't expect non-option arguments
+        if len(self.args) != 0:
+            self.parser.error("incorrect number of arguments")
+
+        flags_given = self.options.uid or self.options.uname
+        if not flags_given:
+            self.parser.print_help()
+            import sys
+            sys.exit(1)
+
+        self.init_request()
+        request = self.request
+
+        from MoinMoin import user, wikiutil
+        if self.options.uid:
+            u = user.User(request, self.options.uid)
+        elif self.options.uname:
+            u = user.User(request, None, self.options.uname)
+        print " %-20s %-25s %-35s" % (u.id, u.name, u.email),
+        if not u.disabled: # only disable once
+            u.disabled = 1
+            u.name = "%s-%s" % (u.name, u.id)
+            if u.email:
+                u.email = "%s-%s" % (u.email, u.id)
+            u.subscribed_pages = "" # avoid using email
+            u.save()
+            print "- disabled."
+        else:
+            print "- is already disabled."
+            
--- a/MoinMoin/script/old/accounts/.cvsignore	Sun Mar 26 10:01:15 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-{arch}
-.arch-ids
-
--- a/MoinMoin/script/old/accounts/__init__.py	Sun Mar 26 10:01:15 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-"""
-    MoinMoin - account managment Scripts
-
-    @copyright: 2004 by Thomas Waldmann
-    @license: GNU GPL, see COPYING for details.
-"""
-
--- a/MoinMoin/script/old/accounts/moin_usercheck-jh-new.py	Sun Mar 26 10:01:15 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,289 +0,0 @@
-#!/usr/bin/env python
-"""
-MoinMoin - check / process user accounts tool
-GPL code written by Thomas Waldmann, 20031005
-
-Why is this needed?
-===================
-When using ACLs, a wiki user name has to be unique, there must not be
-multiple accounts having the same username. The problem is, that this
-was possible before the introduction of ACLs and many users, who forgot
-their ID, simply created a new ID using the same user name.
-
-Because access rights (when using ACLs) depend on the NAME (not the ID),
-this must be cleaned up before using ACLs or users will have difficulties
-changing settings and saving their account data (system won't accept the
-save, if the user name and email is not unique).
-
-How to use this tool?
-=====================
-
-0. Check the settings at top of the code!
-   Making a backup of your wiki might be also a great idea.
-   
-1. Best is to first look at duplicate user names:
-    --usersunique
-
-   If everything looks OK there, you may save that to disk:
-    --usersunique --save
-
-2. Now, check also for duplicate email addresses:
-    --emailsunique
-
-   If everything looks OK, you may save that to disk:
-    --emailsunique --save
-
-3. If the announced action is incorrect, you may choose to better manually
-disable some accounts:
-    --disableuser 1234567.8.90 --save
-
-4. After cleaning up, do 1. and 2. again. There should be no output now, if
-   everything is OK.
-   
-5. Optionally you may want to make wikinames out of the user names
-    --wikinames
-    --wikinames --save
-    
-"""
-
-# ----------------------------------------------------------------------------
-# if a user subsribes to magicpages, it means that he wants to keep
-# exactly THIS account - this will avoid deleting it.
-magicpages = [
-    "ThisAccountIsCorrect", 
-    "DieserAccountIstRichtig",
-]
-
-# ----------------------------------------------------------------------------
-from MoinMoin.script import _util
-config = None
-
-
-#############################################################################
-### Main program
-#############################################################################
-
-class MoinUserCheck(_util.Script):
-    def __init__(self):
-        _util.Script.__init__(self, __name__, "[options]")
-
-        # --config=DIR
-        self.parser.add_option(
-            "--config", metavar="DIR", dest="configdir",
-            help="Path to wikiconfig.py (or its directory)"
-        )
-
-        # --disableuser=UID
-        self.parser.add_option(
-            "--disableuser", metavar="UID", dest="disableuser",
-            help="Disable the user with user id UID;"
-                " this can't be combined with options below!"
-        )
-
-        # Flags
-        self._addFlag("usersunique",
-            "Makes user names unique (by appending the ID to"
-            " name and email, disabling subscribed pages and"
-            " disabling all, but the latest saved user account);"
-            " default is to SHOW what will be happening, you"
-            " need to give the --save option to really do it."
-        )
-        self._addFlag("emailsunique",
-            "Makes user emails unique;"
-            " default is to show, use --save to save it."
-        )
-        self._addFlag("wikinames",
-            "Convert user account names to wikinames (camel-case)."
-        )
-        self._addFlag("lastsaved",
-            "Normally the account most recently USED will"
-            " survive and the others will be disabled."
-            " Using --lastsaved, the account most recently"
-            " SAVED will survive."
-        )
-        self._addFlag("save",
-            "If specified as LAST option, will allow the other"
-            " options to save user accounts back to disk."
-            " If not specified, no settings will be changed permanently."
-        )
-
-
-    def _addFlag(self, name, help):
-        self.parser.add_option("--" + name,
-            action="store_true", dest=name, default=0, help=help)
-
-
-    def mainloop(self):
-        """ moin-usercheck's main code.
-        """
-        import os, sys
-
-        # we don't expect non-option arguments
-        if len(self.args) != 0:
-            self.parser.error("incorrect number of arguments")
-
-        # check for correct option combination
-        flags_given = (
-               self.options.usersunique 
-            or self.options.emailsunique 
-            or self.options.wikinames)
-
-        if flags_given and self.options.disableuser:
-            # XXX: why is this? only because the former option parser code was braindead?
-            self.parser.error("--disableuser can't be combined with other options!")
-
-        # no option given ==> show usage
-        if not (flags_given or self.options.disableuser):
-            self.parser.print_help()
-            sys.exit(1)
-
-        #
-        # Load the configuration
-        #
-        configdir = self.options.configdir
-        if configdir:
-            if os.path.isfile(configdir): configdir = os.path.dirname(configdir)
-            if not os.path.isdir(configdir):
-                _util.fatal("Bad path %r given to --config parameter" % configdir)
-            configdir = os.path.abspath(configdir)
-            sys.path[0:0] = [configdir]
-            os.chdir(configdir)
-
-        global config
-        from MoinMoin import config
-        if config.default_config:
-            _util.fatal("You have to be in the directory containing wikiconfig.py, "
-                "or use the --config option!")
-
-        # XXX: globals bad bad bad!
-        #global users, names, emails, uids_noemail
-        users = {} # uid : UserObject
-        names = {} # name : [uid, uid, uid]
-        emails = {} # email : [uid, uid, uid]
-        uids_noemail = {} # uid : name
-
-        # XXX: Refactor to methods!
-        from MoinMoin import user, wikiutil
-
-        def collect_data():
-            import re
-
-            for uid in user.getUserList():
-                u = user.User(None, uid)
-                users[uid] = u
-        
-                # collect name duplicates:
-                if names.has_key(u.name):
-                    names[u.name].append(uid)
-                else:
-                    names[u.name] = [uid]
-        
-                # collect email duplicates:
-                if u.email:
-                    if emails.has_key(u.email):
-                        emails[u.email].append(uid)
-                    else:
-                        emails[u.email] = [uid]
-        
-                # collect account with no or invalid email address set:
-                if not u.email or not re.match(".*@.*\..*", u.email):
-                    uids_noemail[uid] = u.name
-        
-        
-        def hasmagicpage(uid):
-            u = users[uid]
-            return u.isSubscribedTo(magicpages)
-        
-        
-        def disableUser(uid):
-            u = users[uid]
-            print " %-20s %-25s %-35s" % (uid, u.name, u.email),
-            keepthis = hasmagicpage(uid)
-            if keepthis:
-                print "- keeping (magicpage)!"
-                u.save() # update timestamp, so this will be latest next run
-            elif not u.disabled: # only disable once
-                u.disabled = 1
-                u.name = "%s-%s" % (u.name, uid)
-                if u.email:
-                    u.email = "%s-%s" % (u.email, uid)
-                u.subscribed_pages = "" # avoid using email
-                if self.options.save:
-                    u.save()
-                    print "- disabled."
-                else:
-                    print "- would be disabled."
-        
-        
-        def getsortvalue(uid,user):
-            t_ls = float(user.last_saved) # when user did last SAVE of his account data
-            if self.options.lastsaved:
-                return t_ls
-            else: # last USED (we check the page trail for that)
-                try:
-                    t_lu = float(os.path.getmtime(os.path.join(config.user_dir, uid+".trail")))
-                except OSError:
-                    t_lu = t_ls # better than having nothing
-                return t_lu
-        
-        
-        def process(uidlist):
-            sortlist = []
-            for uid in uidlist:
-                u = users[uid]
-                sortlist.append((getsortvalue(uid,u),uid))
-            sortlist.sort()
-            #print sortlist
-            # disable all, but the last/latest one
-            for t,uid in sortlist[:-1]:
-                disableUser(uid)
-            # show what will be kept
-            uid = sortlist[-1][1]
-            u = users[uid]
-            print " %-20s %-25s %-35s - keeping%s!" % (uid, u.name, u.email, hasmagicpage(uid) and " (magicpage)" or "")
-        
-        
-        def make_users_unique():
-            for name in names.keys():
-                if len(names[name])>1:
-                    process(names[name])
-        
-        
-        def make_emails_unique():
-            for email in emails.keys():
-                if len(emails[email])>1:
-                    process(emails[email])
-        
-        
-        def make_WikiNames():
-            import string
-            for uid in users.keys():
-                u = users[uid]
-                if u.disabled: continue
-                if not wikiutil.isStrictWikiname(u.name):
-                    newname = string.capwords(u.name).replace(" ","").replace("-","")
-                    if not wikiutil.isStrictWikiname(newname):
-                        print " %-20s %-25s - no WikiName, giving up" % (uid, u.name)
-                    else:
-                        print " %-20s %-25s - no WikiName -> %s" % (uid, u.name, newname)
-                        if self.options.save:
-                            u.name = newname
-                            u.save()
-
-        collect_data()
-        if self.options.disableuser:
-            disableUser(self.options.disableuser)
-        else:
-            if self.options.usersunique:
-                make_users_unique()
-            if self.options.emailsunique: 
-                make_emails_unique()
-            if self.options.wikinames:
-                make_WikiNames()
-
-
-def run():
-    MoinUserCheck().run()
-
-if __name__ == "__main__":
-    run()
--- a/MoinMoin/script/old/accounts/moin_usercheck.py	Sun Mar 26 10:01:15 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: iso-8859-1 -*-
-"""
-MoinMoin - check / process user accounts tool
-GPL code written by Thomas Waldmann, 20031005
-
-Why is this needed?
-===================
-When using ACLs, a wiki user name has to be unique, there must not be
-multiple accounts having the same username. The problem is, that this
-was possible before the introduction of ACLs and many users, who forgot
-their ID, simply created a new ID using the same user name.
-
-Because access rights (when using ACLs) depend on the NAME (not the ID),
-this must be cleaned up before using ACLs or users will have difficulties
-changing settings and saving their account data (system won't accept the
-save, if the user name and email is not unique).
-
-How to use this tool?
-=====================
-
-0. Check the settings at top of the code!
-   Making a backup of your wiki might be also a great idea.
-   
-1. Best is to first look at duplicate user names:
-    --usersunique
-
-   If everything looks OK there, you may save that to disk:
-    --usersunique --save
-
-2. Now, check also for duplicate email addresses:
-    --emailsunique
-
-   If everything looks OK, you may save that to disk:
-    --emailsunique --save
-
-3. If the announced action is incorrect, you may choose to better manually
-disable some accounts:
-    --disableuser 1234567.8.90 --save
-
-4. After cleaning up, do 1. and 2. again. There should be no output now, if
-   everything is OK.
-   
-5. Optionally you may want to make wikinames out of the user names
-    --wikinames
-    --wikinames --save
-    
-"""
-
-import sys, re
-
-# ----------------------------------------------------------------------------
-# CHECK THESE SETTINGS, then remove or comment out the following line:
-#print "Check the settings in the script first, please!" ; sys.exit(1)
-
-# this is where your moinmoin code is (if you installed it using
-# setup.py into your python site-packages, then you don't need that setting):
-sys.path.insert(0, '/home/twaldmann/moincvs/moin--main')
-
-# this is where your wikiconfig.py is:
-sys.path.insert(0, '/org/org.linuxwiki/cgi-bin')
-
-# if you include other stuff in your wikiconfig, you might need additional
-# pathes in your search path. Put them here:
-sys.path.insert(0, '/org/wiki')
-
-# if a user subsribes to magicpage, it means that he wants to keep
-# exactly THIS account - this will avoid deleting it.
-#magicpage = "ThisAccountIsCorrect"
-magicpage = "DieserAccountIstRichtig"
-
-# ----------------------------------------------------------------------------
-
-from MoinMoin.user import *
-from MoinMoin import config, wikiutil
-
-def collect_data():
-    for uid in getUserList(request): # XXX FIXME make request object for getting config vars there
-        u = User(None, uid)
-        users[uid] = u
-
-        # collect name duplicates:
-        if names.has_key(u.name):
-            names[u.name].append(uid)
-        else:
-            names[u.name] = [uid]
-
-        # collect email duplicates:
-        if u.email:
-            if emails.has_key(u.email):
-                emails[u.email].append(uid)
-            else:
-                emails[u.email] = [uid]
-
-        # collect account with no or invalid email address set:
-        if not u.email or not re.match(".*@.*\..*", u.email):
-            uids_noemail[uid] = u.name
-
-def hasmagicpage(uid):
-    u = users[uid]
-    return u.subscribed_pages.find(magicpage) >= 0
-
-def disableUser(uid):
-    u = users[uid]
-    print " %-20s %-25s %-35s" % (uid, u.name, u.email),
-    keepthis = hasmagicpage(uid)
-    if keepthis:
-        print "- keeping (magicpage)!"
-        u.save() # update timestamp, so this will be latest next run
-    elif not u.disabled: # only disable once
-        u.disabled = 1
-        u.name = "%s-%s" % (u.name, uid)
-        if u.email:
-            u.email = "%s-%s" % (u.email, uid)
-        u.subscribed_pages = "" # avoid using email
-        if save:
-            u.save()
-            print "- disabled."
-        else:
-            print "- would be disabled."
-
-def getsortvalue(uid,user):
-    t_ls = float(user.last_saved) # when user did last SAVE of his account data
-    if lastsaved:
-        return t_ls
-    else: # last USED (we check the page trail for that)
-        try:
-            t_lu = float(os.path.getmtime(os.path.join(config.user_dir, uid+".trail")))
-        except OSError:
-            t_lu = t_ls # better than having nothing
-        return t_lu
-
-def process(uidlist):
-    sortlist = []
-    for uid in uidlist:
-        u = users[uid]
-        sortlist.append((getsortvalue(uid,u),uid))
-    sortlist.sort()
-    #print sortlist
-    # disable all, but the last/latest one
-    for t,uid in sortlist[:-1]:
-        disableUser(uid)
-    # show what will be kept
-    uid = sortlist[-1][1]
-    u = users[uid]
-    print " %-20s %-25s %-35s - keeping%s!" % (uid, u.name, u.email, hasmagicpage(uid) and " (magicpage)" or "")
-
-def make_users_unique():
-    for name in names.keys():
-        if len(names[name])>1:
-            process(names[name])
-        
-def make_emails_unique():
-    for email in emails.keys():
-        if len(emails[email])>1:
-            process(emails[email])
-
-
-def make_WikiNames():
-    import string
-    for uid in users.keys():
-        u = users[uid]
-        if u.disabled: continue
-        if not wikiutil.isStrictWikiname(u.name):
-            newname = string.capwords(u.name).replace(" ","").replace("-","")
-            if not wikiutil.isStrictWikiname(newname):
-                print " %-20s %-25s - no WikiName, giving up" % (uid, u.name)
-            else:
-                print " %-20s %-25s - no WikiName -> %s" % (uid, u.name, newname)
-                if save:
-                    u.name = newname
-                    u.save()
-            
-def do_removepasswords():
-    for uid in users.keys():
-        u = users[uid]
-        # user.User already clears the old cleartext passwords on loading,
-        # so nothing to do here!
-        if save:
-            # we can't encrypt the cleartext password as it is cleared
-            # already. and we would not trust it anyway, so we don't WANT
-            # to do that either!
-            # Just save the account data without cleartext password:
-            print " %-20s %-25s - saving" % (uid, u.name)
-            u.save()
-            
-# here the main routine starts --------------------------------
-usersunique = emailsunique = lastsaved = save = 0
-disableuser = wikinames = removepasswords = 0
-
-users = {} # uid : UserObject
-names = {} # name : [uid, uid, uid]
-emails = {} # email : [uid, uid, uid]
-uids_noemail = {} # uid : name
-
-def run():
-    global usersunique, emailsunique, lastsaved, save, disableuser, wikinames
-    global users, names, emails, uids_noemail, removepasswords
-    
-    if "--usersunique" in sys.argv:  usersunique = 1
-    if "--emailsunique" in sys.argv: emailsunique = 1
-    if "--lastsaved" in sys.argv:    lastsaved = 1
-    if "--wikinames" in sys.argv:    wikinames = 1
-    if "--removepasswords" in sys.argv:    removepasswords = 1
-    if "--save" in sys.argv:         save = 1
-
-    if "--disableuser" in sys.argv:  disableuser = 1
-
-    if not usersunique and not emailsunique and not disableuser and \
-       not wikinames and not removepasswords:
-        print """%s
-    Options:
-        --usersunique       makes user names unique (by appending the ID to
-                            name and email, disabling subscribed pages and
-                            disabling all, but the latest saved user account)
-                            default is to SHOW what will be happening, you
-                            need to give the --save option to really do it.
-
-        --emailsunique      makes user emails unique
-                            default is to show, use --save to save it.
-
-        --lastsaved         normally the account most recently USED will
-                            survive and the others will be disabled.
-                            using --lastsaved, the account most recently
-                            SAVED will survive.
-
-        --disableuser uid   disable the user with user id uid
-                            this can't be combined with the options above!
-                            
-        --wikinames         try to make "WikiNames" out of "user names"
-        --removepasswords   remove pre-1.1 cleartext passwords from accounts
-        
-        --save              if specified as LAST option, will allow the other
-                            options to save user accounts back to disk.
-                            if not specified, no settings will be permanently
-                            changed.
-
-    """ % sys.argv[0]
-        return
-        
-    collect_data()
-    if usersunique:  make_users_unique()
-    if emailsunique: make_emails_unique()
-    if disableuser:  disableUser(sys.argv[2])
-    if wikinames:    make_WikiNames()
-    if removepasswords: do_removepasswords()
-
-if __name__ == "__main__":
-    run()
-
-# EOF
-
--- a/docs/CHANGES	Sun Mar 26 10:01:15 2006 +0000
+++ b/docs/CHANGES	Sun Mar 26 12:23:13 2006 +0000
@@ -108,6 +108,9 @@
         The old scripts that have not been migrated to this new interface can
         still be found in MoinMoin/script/old/ - including the old migration
         scripts.
+      * moin ... account create --name=JoeDoe --email=joe@doe.org
+      * moin ... account disable --name=JoeDoe
+      * moin ... acount check    <-- this is what usercheck script was before
 
   Bugfixes:
     * cookie_lifetime didn't work comfortable for low values. The cookie was
--- a/setup.py	Sun Mar 26 10:01:15 2006 +0000
+++ b/setup.py	Sun Mar 26 12:23:13 2006 +0000
@@ -206,11 +206,11 @@
         'MoinMoin.parser',
         'MoinMoin.processor',
         'MoinMoin.script',
+        'MoinMoin.script.account',
         'MoinMoin.script.cli',
         'MoinMoin.script.migration',
         'MoinMoin.script.import',
         'MoinMoin.script.old',
-        'MoinMoin.script.old.accounts',
         'MoinMoin.script.old.migration',
         'MoinMoin.script.old.reducewiki',
         'MoinMoin.script.old.unicode',