Back to index

moin  1.9.0~rc2
Public Member Functions | Public Attributes | Private Member Functions
MoinMoin.script.account.check.PluginScript Class Reference
Inheritance diagram for MoinMoin.script.account.check.PluginScript:
Inheritance graph
[legend]
Collaboration diagram for MoinMoin.script.account.check.PluginScript:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def collect_data
def hasmagicpage
def disableUser
def getsortvalue
def process
def make_users_unique
def make_emails_unique
def make_WikiNames
def remove_passwords
def mainloop
def init_request
def run
def logRuntime

Public Attributes

 users
 names
 emails
 uids_noemail
 request
 argv
 def_values
 parser
 args

Private Member Functions

def _addFlag

Detailed Description

\
Purpose:
========
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).

Detailed Instructions:
======================

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

Definition at line 24 of file check.py.


Constructor & Destructor Documentation

def MoinMoin.script.account.check.PluginScript.__init__ (   self,
  argv,
  def_values 
)

Reimplemented from MoinMoin.script.MoinScript.

Definition at line 74 of file check.py.

00074 
00075     def __init__(self, argv, def_values):
00076         MoinScript.__init__(self, argv, def_values)
00077         self._addFlag("usersunique",
00078             "Makes user names unique (by appending the ID to"
00079             " name and email, disabling subscribed pages and"
00080             " disabling all, but the latest saved user account);"
00081             " default is to SHOW what will be happening, you"
00082             " need to give the --save option to really do it."
00083         )
00084         self._addFlag("emailsunique",
00085             "Makes user emails unique;"
00086             " default is to show, use --save to save it."
00087         )
00088         self._addFlag("wikinames",
00089             "Convert user account names to wikinames (camel-case)."
00090         )
00091         self._addFlag("save",
00092             "If specified as LAST option, will allow the other"
00093             " options to save user accounts back to disk."
00094             " If not specified, no settings will be changed permanently."
00095         )
00096         self._addFlag("removepasswords",
00097             "Remove pre-1.1 cleartext passwords from accounts."
00098         )

Here is the call graph for this function:


Member Function Documentation

def MoinMoin.script.account.check.PluginScript._addFlag (   self,
  name,
  help 
) [private]

Definition at line 99 of file check.py.

00099 
00100     def _addFlag(self, name, help):
00101         self.parser.add_option("--" + name,
00102             action="store_true", dest=name, default=0, help=help)

Here is the caller graph for this function:

Definition at line 103 of file check.py.

00103 
00104     def collect_data(self):
00105         import re
00106         request = self.request
00107         for uid in user.getUserList(request):
00108             u = user.User(request, uid)
00109             self.users[uid] = u
00110 
00111             # collect name duplicates:
00112             if u.name in self.names:
00113                 self.names[u.name].append(uid)
00114             else:
00115                 self.names[u.name] = [uid]
00116 
00117             # collect email duplicates:
00118             if u.email:
00119                 if u.email in self.emails:
00120                     self.emails[u.email].append(uid)
00121                 else:
00122                     self.emails[u.email] = [uid]
00123 
00124             # collect account with no or invalid email address set:
00125             if not u.email or not re.match(".*@.*\..*", u.email):
00126                 self.uids_noemail[uid] = u.name

Definition at line 131 of file check.py.

00131 
00132     def disableUser(self, uid):
00133         u = self.users[uid]
00134         print " %-20s %-30r %-35r" % (uid, u.name, u.email),
00135         keepthis = self.hasmagicpage(uid)
00136         if keepthis:
00137             print "- keeping (magicpage)!"
00138             u.save() # update timestamp, so this will be latest next run
00139         elif not u.disabled: # only disable once
00140             u.disabled = 1
00141             u.name = "%s-%s" % (u.name, uid)
00142             if u.email:
00143                 u.email = "%s-%s" % (u.email, uid)
00144             u.subscribed_pages = "" # avoid using email
00145             if self.options.save:
00146                 u.save()
00147                 print "- disabled."
00148             else:
00149                 print "- would be disabled."

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.script.account.check.PluginScript.getsortvalue (   self,
  uid,
  user 
)

Definition at line 150 of file check.py.

00150 
00151     def getsortvalue(self, uid, user):
00152         return float(user.last_saved) # when user did last SAVE of his account data

Here is the caller graph for this function:

Definition at line 127 of file check.py.

00127 
00128     def hasmagicpage(self, uid):
00129         u = self.users[uid]
00130         return u.isSubscribedTo(magicpages)

Here is the caller graph for this function:

def MoinMoin.script.MoinScript.init_request (   self) [inherited]
create request 

Definition at line 174 of file __init__.py.

00174 
00175     def init_request(self):
00176         """ create request """
00177         from MoinMoin.web.contexts import ScriptContext
00178         url = self.options.wiki_url or None
00179         self.request = ScriptContext(url, self.options.page)

Here is the caller graph for this function:

def MoinMoin.script.Script.logRuntime (   self) [inherited]
Print the total command run time. 

Definition at line 148 of file __init__.py.

00148 
00149     def logRuntime(self):
00150         """ Print the total command run time. """
00151         if self.options.show_timing:
00152             log("Needed %.3f secs." % (time.clock() - _start_time, ))
00153 

Here is the call graph for this function:

Reimplemented from MoinMoin.script.MoinScript.

Definition at line 204 of file check.py.

00204 
00205     def mainloop(self):
00206         # we don't expect non-option arguments
00207         if len(self.args) != 0:
00208             self.parser.error("incorrect number of arguments")
00209 
00210         # check for correct option combination
00211         flags_given = (self.options.usersunique
00212                     or self.options.emailsunique
00213                     or self.options.wikinames
00214                     or self.options.removepasswords)
00215 
00216         # no option given ==> show usage
00217         if not flags_given:
00218             self.parser.print_help()
00219             sys.exit(1)
00220 
00221         self.init_request()
00222 
00223         self.users = {} # uid : UserObject
00224         self.names = {} # name : [uid, uid, uid]
00225         self.emails = {} # email : [uid, uid, uid]
00226         self.uids_noemail = {} # uid : name
00227 
00228         self.collect_data()
00229         if self.options.usersunique:
00230             self.make_users_unique()
00231         if self.options.emailsunique:
00232             self.make_emails_unique()
00233         if self.options.wikinames:
00234             self.make_WikiNames()
00235         if self.options.removepasswords:
00236             self.remove_passwords()
00237 

Here is the call graph for this function:

Definition at line 173 of file check.py.

00173 
00174     def make_emails_unique(self):
00175         for email, uids in self.emails.items():
00176             if len(uids) > 1:
00177                 self.process(uids)

Here is the call graph for this function:

Definition at line 168 of file check.py.

00168 
00169     def make_users_unique(self):
00170         for name, uids in self.names.items():
00171             if len(uids) > 1:
00172                 self.process(uids)

Here is the call graph for this function:

Definition at line 178 of file check.py.

00178 
00179     def make_WikiNames(self):
00180         for uid, u in self.users.items():
00181             if u.disabled:
00182                 continue
00183             if not wikiutil.isStrictWikiname(u.name):
00184                 newname = u.name.capwords().replace(" ", "").replace("-", "")
00185                 if not wikiutil.isStrictWikiname(newname):
00186                     print " %-20s %-30r - no WikiName, giving up" % (uid, u.name)
00187                 else:
00188                     print " %-20s %-30r - no WikiName -> %r" % (uid, u.name, newname)
00189                     if self.options.save:
00190                         u.name = newname
00191                         u.save()

Definition at line 153 of file check.py.

00153 
00154     def process(self, uidlist):
00155         sortlist = []
00156         for uid in uidlist:
00157             u = self.users[uid]
00158             sortlist.append((self.getsortvalue(uid, u), uid))
00159         sortlist.sort()
00160         #print sortlist
00161         # disable all, but the last/latest one
00162         for dummy, uid in sortlist[:-1]:
00163             self.disableUser(uid)
00164         # show what will be kept
00165         uid = sortlist[-1][1]
00166         u = self.users[uid]
00167         print " %-20s %-30r %-35r - keeping%s!" % (uid, u.name, u.email, self.hasmagicpage(uid) and " (magicpage)" or "")

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 192 of file check.py.

00192 
00193     def remove_passwords(self):
00194         for uid, u in self.users.items():
00195             # user.User already clears the old cleartext passwords on loading,
00196             # so nothing to do here!
00197             if self.options.save:
00198                 # we can't encrypt the cleartext password as it is cleared
00199                 # already. and we would not trust it anyway, so we don't WANT
00200                 # to do that either!
00201                 # Just save the account data without cleartext password:
00202                 print " %-20s %-25s - saving" % (uid, u.name)
00203                 u.save()

def MoinMoin.script.Script.run (   self,
  showtime = 1 
) [inherited]
Run the main function of a command. 

Definition at line 130 of file __init__.py.

00130 
00131     def run(self, showtime=1):
00132         """ Run the main function of a command. """
00133         global flag_quiet
00134         try:
00135             try:
00136                 self.options, self.args = self.parser.parse_args(self.argv)
00137                 flag_quiet = self.options.quiet
00138                 # ToDo check if we need to initialize request (self.init_request())
00139                 self.mainloop()
00140             except KeyboardInterrupt:
00141                 log("*** Interrupted by user!")
00142             except SystemExit:
00143                 showtime = 0
00144                 raise
00145         finally:
00146             if showtime:
00147                 self.logRuntime()

Here is the caller graph for this function:


Member Data Documentation

Definition at line 135 of file __init__.py.

Definition at line 102 of file __init__.py.

Definition at line 224 of file check.py.

Definition at line 223 of file check.py.

Definition at line 113 of file __init__.py.

Definition at line 178 of file __init__.py.

Definition at line 225 of file check.py.

Definition at line 222 of file check.py.


The documentation for this class was generated from the following file: