Mercurial > moin > 1.9
changeset 5936:2d3352c547bc
moin account resetpw - misc. improvements
add some options to define email subject and text, either by commandline
arguments or by reading an email template from a text file.
added instructions about how to deal with a password reset and a email
template, see docs/resetpw/
if notificiation is requested and the wiki is not configured for email
sending, abort.
author | Thomas Waldmann <tw AT waldmann-edv DOT de> |
---|---|
date | Thu, 24 Jan 2013 22:34:41 +0100 |
parents | 6f201a3b1b24 |
children | 9a9af7912a44 |
files | MoinMoin/script/account/resetpw.py MoinMoin/user.py docs/CHANGES docs/resetpw/README docs/resetpw/mailtemplate.txt |
diffstat | 5 files changed, 183 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/MoinMoin/script/account/resetpw.py Thu Jan 24 14:25:48 2013 +0100 +++ b/MoinMoin/script/account/resetpw.py Thu Jan 24 22:34:41 2013 +0100 @@ -7,6 +7,8 @@ @license: GNU GPL, see COPYING for details. """ +import sys + from MoinMoin.script import MoinScript, log from MoinMoin.user import getUserList, set_password, Fault @@ -67,6 +69,26 @@ help="Notify user(s), send them an E-Mail with a password reset link." ) self.parser.add_option( + "--subject", metavar="SUBJECT", dest="subject", + help="Subject text for the password reset notification E-Mail." + ) + self.parser.add_option( + "--text-intro", metavar="TEXT_INTRO", dest="text_intro", + help="Intro text for the password reset notification E-Mail. Default: empty." + ) + self.parser.add_option( + "--text-msg", metavar="TEXT_MSG", dest="text_msg", + help="Main text for the password reset notification E-Mail. Default: use the builtin standard message" + ) + self.parser.add_option( + "--text-data", metavar="TEXT_DATA", dest="text_data", + help="Data template text for the password reset notification E-Mail. Default: use the builtin standard data template" + ) + self.parser.add_option( + "--text-from-file", metavar="TEXT_DATA", dest="text_file", + help="Read full template for the password reset notification E-Mail from the given file, overrides --text-intro/msg/data. Default: None" + ) + self.parser.add_option( "-v", "--verbose", dest="verbose", action="store_true", help="Verbose operation." ) @@ -83,22 +105,40 @@ flags_given = self.options.uid or self.options.uname or self.options.all_users if not flags_given: self.parser.print_help() - import sys sys.exit(1) self.init_request() request = self.request + notify = self.options.notify + if notify and not request.cfg.mail_enabled: + print "This wiki is not enabled for mail processing. The --notify option requires this. Aborting..." + sys,exit(1) + + subject = self.options.subject + text_intro = self.options.text_intro + text_msg = self.options.text_msg + text_data = self.options.text_data + text_file = self.options.text_file + + if text_file: + text_intro = '' + text_msg = '' + with open(text_file) as f: + text_data = f.read().decode('utf-8') + if self.options.uid: try: set_password(request, newpass, uid=self.options.uid, - notify=self.options.notify) + notify=notify, subject=subject, + text_intro=text_intro, text_msg=text_msg, text_data=text_data) except Fault, err: print str(err) elif self.options.uname: try: set_password(request, newpass, uname=self.options.uname, - notify=self.options.notify) + notify=notify, subject=subject, + text_intro=text_intro, text_msg=text_msg, text_data=text_data) except Fault, err: print str(err) elif self.options.all_users: @@ -108,6 +148,7 @@ log("%05d / %05d - processing uid %s" % (nr, total, uid)) try: set_password(request, newpass, uid=uid, - notify=self.options.notify) + notify=notify, subject=subject, + text_intro=text_intro, text_msg=text_msg, text_data=text_data) except Fault, err: print str(err)
--- a/MoinMoin/user.py Thu Jan 24 14:25:48 2013 +0100 +++ b/MoinMoin/user.py Thu Jan 24 22:34:41 2013 +0100 @@ -191,7 +191,9 @@ """raised if e-mail sending failed""" -def set_password(request, newpass, u=None, uid=None, uname=None, notify=False): +def set_password(request, newpass, u=None, uid=None, uname=None, + notify=False, subject=None, + text_intro=None, text_msg=None, text_data=None): if uid: u = User(request, uid) elif uname: @@ -204,7 +206,8 @@ u.enc_password = encodePassword(request.cfg, newpass) u.save() if notify and not u.disabled: - mailok, msg = u.mailAccountData() + mailok, msg = u.mailAccountData(subject=subject, + text_intro=text_intro, text_msg=text_msg, text_data=text_data) if not mailok: raise MailFailed(msg) else: @@ -1111,12 +1114,13 @@ self.save() return True - def mailAccountData(self, cleartext_passwd=None): + def mailAccountData(self, cleartext_passwd=None, + subject=None, + text_intro=None, text_msg=None, text_data=None): """ Mail a user who forgot his password a message enabling him to login again. """ from MoinMoin.mail import sendmail - from MoinMoin.wikiutil import getLocalizedPage _ = self._request.getText if not self.email: @@ -1124,30 +1128,35 @@ tok = self.generate_recovery_token() - text = '\n' + _("""\ + if subject is None: + subject = _('[%(sitename)s] Your wiki account data') + subject = subject % dict(sitename=self._cfg.sitename or "Wiki") + if text_intro is None: + text_intro = '' + if text_msg is None: + text_msg = """\ +Somebody has requested to email you a password recovery token. + +If you lost your password, please go to the password reset URL below or +go to the password recovery page again and enter your username and the +recovery token. +""" + if text_data is None: + text_data = """\ Login Name: %s Password recovery token: %s Password reset URL: %s?action=recoverpass&name=%s&token=%s -""") % ( +""" + # note: text_intro is for custom stuff, we do not have i18n for it anyway + text = text_intro + '\n' + _(text_msg) + '\n' + _(text_data) % ( self.name, tok, self._request.url, # use full url, including current page url_quote_plus(self.name), tok, ) - text = _("""\ -Somebody has requested to email you a password recovery token. - -If you lost your password, please go to the password reset URL below or -go to the password recovery page again and enter your username and the -recovery token. -""") + text - - - subject = _('[%(sitename)s] Your wiki account data', - ) % {'sitename': self._cfg.sitename or "Wiki"} mailok, msg = sendmail.sendmail(self._request, [self.email], subject, text, mail_from=self._cfg.mail_from) return mailok, msg
--- a/docs/CHANGES Thu Jan 24 14:25:48 2013 +0100 +++ b/docs/CHANGES Thu Jan 24 22:34:41 2013 +0100 @@ -87,10 +87,7 @@ http://packages.python.org/passlib/new_app_quickstart.html#choosing-a-hash http://packages.python.org/passlib/password_hash_api.html#choosing-the-right-rounds-value - * Password mass reset support: - Resetting the passwords of all wiki users can be done using: - moin ... --verbose account resetpw --all-users --notify - + * Password mass reset/invalidation support, see docs/resetpw/. This is useful to make sure everybody sets a new password and moin computes the password hash using the current configuration.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/resetpw/README Thu Jan 24 22:34:41 2013 +0100 @@ -0,0 +1,92 @@ +Resetting (invalidating) password(s) +==================================== + +First make sure E-Mail functionality for your wiki is enabled, something like: + + # the E-Mail address used for From: (consider using an address that + # can be directly replied to, at least while doing the pw reset): + mail_from = 'wiki@example.org' + # your smtp mail server hostname:port (default is 25) + mail_smarthost = 'mail.example.org:587' + # the login there, if authentication is needed + mail_login = 'wiki@example.org SuperSecretSMTPPassword' + +Optionally, you can also remind your users that having a valid E-Mail address +in their user settings is essential for getting a password recovery E-Mail. +If a active user does somehow not get such a mail, you likely will have to +manually define a password for that user. + +If you had a security breach on your wiki (password hashes stolen) or you want +to make sure all password hashes use strong algorithms (which is strongly +recommended), you need to reset ALL users' passwords: + +Editing mailtemplate.txt +======================== + +If you edit mailtemplate.txt, please be very careful and follow these rules +(otherwise you might just see the script command crashing): + +The contents must be utf-8 (or ascii, which is a subset of utf-8). +In case of doubt, just use plain English. + +Never ever change the AMOUNT or ORDER of the %s placeholders in the template. +They will get replaced by MoinMoin with specific values in a specific order. +We know this can be done better in Python, but this restriction is for +compatibility with existing translations of the builtin texts, thus we +could not do better without requiring lots of translation updates. + +Do not use any % character in your text (except for the placeholders). + +That said, feel free to change or add any other text. + +It is a very good idea to give some URL (e.g. of a web or wiki page) in +the text where users can read more information about why you reset the +password(s), who exactly resetted the password(s) and who (E-Mail) to contact +if there are any questions or issues. + +Of course the information at that URL should be readable without requiring +a wiki login (you just have invalidated his/her password!), so the user can +get informed before clicking links he got from someone via E-Mail. + +Instead of creating a web or wiki page with the information, you could +also write all the stuff into the mail template directly, but please consider +that E-Mail delivery to some users might fail for misc. reasons, so having +some information on the web/wiki is usually better. + +Doing the password reset +======================== + +Maybe first try it with a single user account: + +moin ... account resetpw --name JoeDoe --notify --subject 'Wiki password reset' --text-from-file contrib/resetpw/mailtemplate.txt + +Use some valid name, maybe a testing account of yourself. You should now have +mail. If that worked ok, you can now do a global password reset for your wiki: + +moin ... account resetpw --all-users --notify --subject 'Wiki password reset' --text-from-file contrib/resetpw/mailtemplate.txt + +The subject may contain a placeholder for the sitename, which is useful for +wiki farms (showing the builtin default here): + + '[%(sitename)s] Your wiki account data' + +Please note: +- Instead of ... you need to give the --config-dir and --wiki-url options with + correct values for the wiki you want to operate on. +- If you have a farm wiki, you need to invoke the command with correct params + for each of your farm member wikis. + +Helping users who can't do the password recovery +================================================ +Either they did not get the E-Mail, or deleted it, or ... + +You can just set an arbitrary password for them (and tell it to them). +But make sure they change it a minute afterwards: + +Alternatively, if you are in the superuser list, you can go to YOUR user +settings, switch to the user having troubles and just fix / add a valid +E-Mail address for that user (if that was the problem). Logout to get back +to your user account. + +Then do the password reset again, but just for that user. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/resetpw/mailtemplate.txt Thu Jan 24 22:34:41 2013 +0100 @@ -0,0 +1,19 @@ +The wiki administrator has invalidated your wiki password and requested +to send this E-Mail to you, so you can set a wiki password. + +Reason for the password invalidation: + +... + +Please go to the password reset URL below and set a password. + +Alternatively, you can go to the password recovery page and manually +(use copy&paste) enter the recovery token, your login name and the +password. + +Login Name: %s + +Password recovery token: %s + +Password reset URL: %s?action=recoverpass&name=%s&token=%s +