Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Jul 2018 00:05:20 +0000 (UTC)
From:      Kubilay Kocak <koobs@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r475859 - in head/www/moinmoin: . files
Message-ID:  <201807300005.w6U05Kmg037475@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: koobs
Date: Mon Jul 30 00:05:20 2018
New Revision: 475859
URL: https://svnweb.freebsd.org/changeset/ports/475859

Log:
  www/moinmoin: Add recaptcha v2 and email verification support
  
  Add patches to include:
  
     - reCAPTCHA v2 support [1]
     - Email verification for new account creation [2]
  
  Both patches are OPTION'al, both OPTIONS are enabled by default. Both features
  require additional configuration (within moinmoin) to enable them within wiki
  instances.
  
  While I'm here:
  
    - Use TLS for MASTER_SITES and pkg-descr WWW: URLs
    - Update COMMENT to match setup.py description
    - Enable NO_ARCH
    - Sort sections
  
  PR:			227394 [1]
  Submitted by:		<daz hackerspace pl> [1]
  Reviewed by:		0mp
  Tested by:		0mp (upgrade process)
  Approved by:		koobs (python, maintainer)
  Obtained from:		clusteradm (sbruno, custom patch to port) [2]
  Differential Revision:	D16315

Added:
  head/www/moinmoin/files/extra-patch-recaptchav2   (contents, props changed)
  head/www/moinmoin/files/extra-patch-verifyemail   (contents, props changed)
Modified:
  head/www/moinmoin/Makefile
  head/www/moinmoin/files/patch-setup.py
  head/www/moinmoin/pkg-descr
  head/www/moinmoin/pkg-plist

Modified: head/www/moinmoin/Makefile
==============================================================================
--- head/www/moinmoin/Makefile	Sun Jul 29 22:49:09 2018	(r475858)
+++ head/www/moinmoin/Makefile	Mon Jul 30 00:05:20 2018	(r475859)
@@ -3,19 +3,22 @@
 
 PORTNAME=	moinmoin
 PORTVERSION=	1.9.9
+PORTREVISION=	1
 CATEGORIES=	www python
-MASTER_SITES=	http://static.moinmo.in/files/
+MASTER_SITES=	https://static.moinmo.in/files/
 DISTNAME=	moin-${PORTVERSION}
 
 MAINTAINER=	python@FreeBSD.org
-COMMENT=	Python clone of WikiWiki
+COMMENT=	Easy to use, full-featured and extensible wiki software package
 
 LICENSE=	GPLv2
 LICENSE_FILE=	${WRKSRC}/docs/licenses/COPYING
 
 USES=		cpe python:2.7 shebangfix
-CPE_VENDOR=	moinmo
 USE_PYTHON=	distutils
+
+NO_ARCH=	yes
+CPE_VENDOR=	moinmo
 PYDISTUTILS_PKGNAME=	moin
 SHEBANG_FILES=	wiki/server/moin*
 
@@ -24,6 +27,16 @@ PLIST_SUB+=	PYTHON_SITELIB=${PYTHON_SITELIBDIR:S|^${LO
 SUB_FILES=	pkg-install
 SUB_LIST=	MOINDIR=${MOINDIR} MOINDEST=${MOINDEST} MOINVER=${MOINVER} \
 		HTDOCS=${PYTHON_SITELIBDIR}/MoinMoin/web/static/htdocs
+
+OPTIONS_DEFINE=		RECAPTCHA VERIFYEMAIL
+OPTIONS_DEFAULT=	RECAPTCHA VERIFYEMAIL
+OPTIONS_SUB=		yes
+
+RECAPTCHA_DESC=		reCAPTCHA v2 support
+VERIFYEMAIL_DESC=	Support for verifying new account email addresses
+
+RECAPTCHA_EXTRA_PATCHES=	${PATCHDIR}/extra-patch-recaptchav2
+VERIFYEMAIL_EXTRA_PATCHES=	${PATCHDIR}/extra-patch-verifyemail
 
 CGIUSER?=	www
 CGIGROUP?=	www

Added: head/www/moinmoin/files/extra-patch-recaptchav2
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/moinmoin/files/extra-patch-recaptchav2	Mon Jul 30 00:05:20 2018	(r475859)
@@ -0,0 +1,299 @@
+# Based on https://gist.github.com/tfoote/675b98df53369e199dea
+
+--- MoinMoin/action/AttachFile.py.orig	2016-10-31 20:44:01 UTC
++++ MoinMoin/action/AttachFile.py
+@@ -44,6 +44,7 @@ from MoinMoin import config, packages
+ from MoinMoin.Page import Page
+ from MoinMoin.util import filesys, timefuncs
+ from MoinMoin.security.textcha import TextCha
++from MoinMoin.security.sec_recaptcha import ReCaptcha
+ from MoinMoin.events import FileAttachedEvent, FileRemovedEvent, send_event
+ 
+ action_name = __name__.split('.')[-1]
+@@ -654,6 +655,7 @@ def send_uploadform(pagename, request):
+ <dd><input type="checkbox" name="overwrite" value="1" %(overwrite_checked)s></dd>
+ </dl>
+ %(textcha)s
++%(recaptcha)s
+ <p>
+ <input type="hidden" name="action" value="%(action_name)s">
+ <input type="hidden" name="do" value="upload">
+@@ -671,6 +673,7 @@ def send_uploadform(pagename, request):
+     'overwrite_checked': ('', 'checked')[request.form.get('overwrite', '0') == '1'],
+     'upload_button': _('Upload'),
+     'textcha': TextCha(request).render(),
++    'recaptcha': ReCaptcha(request).render(),
+     'ticket': wikiutil.createTicket(request),
+ })
+ 
+@@ -728,6 +731,8 @@ def _do_upload(pagename, request):
+     # but it could be extended to more/all attachment write access
+     if not TextCha(request).check_answer_from_form():
+         return _('TextCha: Wrong answer! Go back and try again...')
++    if not ReCaptcha(request).check_answer_from_form():
++        return _('ReCaptcha: Wrong answer! Go back and try again...')
+ 
+     form = request.form
+ 
+--- MoinMoin/action/CopyPage.py.orig	2016-10-31 20:44:01 UTC
++++ MoinMoin/action/CopyPage.py
+@@ -14,6 +14,7 @@ from MoinMoin.Page import Page
+ from MoinMoin.PageEditor import PageEditor
+ from MoinMoin.action import ActionBase
+ from MoinMoin.security.textcha import TextCha
++from MoinMoin.security.sec_recaptcha import ReCaptcha
+ 
+ class CopyPage(ActionBase):
+     """ Copy page action
+@@ -45,11 +46,14 @@ class CopyPage(ActionBase):
+ 
+     def do_action(self):
+         """ copy this page to "pagename" """
++        status = False
+         _ = self._
+         # Currently we only check TextCha for upload (this is what spammers ususally do),
+         # but it could be extended to more/all attachment write access
+         if not TextCha(self.request).check_answer_from_form():
+             return False, _('TextCha: Wrong answer! Go back and try again...')
++        if not ReCaptcha(self.request).check_answer_from_form():
++            return status, _('ReCaptcha: Wrong answer! Go back and try again...')
+ 
+         form = self.form
+         newpagename = form.get('newpagename', u'')
+@@ -90,6 +94,7 @@ class CopyPage(ActionBase):
+ 
+             d = {
+                 'textcha': TextCha(self.request).render(),
++                'recaptcha': ReCaptcha(self.request).render(),
+                 'subpage': subpages,
+                 'subpages_checked': ('', 'checked')[self.request.args.get('subpages_checked', '0') == '1'],
+                 'subpage_label': _('Copy all /subpages too?'),
+@@ -105,6 +110,7 @@ class CopyPage(ActionBase):
+ <br>
+ <br>
+ %(textcha)s
++%(recaptcha)s
+ <table>
+     <tr>
+     <dd>
+@@ -140,6 +146,7 @@ class CopyPage(ActionBase):
+         else:
+             d = {
+                 'textcha': TextCha(self.request).render(),
++                'recaptcha': ReCaptcha(self.request).render(),
+                 'pagename': wikiutil.escape(self.pagename, True),
+                 'newname_label': _("New name"),
+                 'comment_label': _("Optional reason for the copying"),
+@@ -147,6 +154,7 @@ class CopyPage(ActionBase):
+                 }
+             return '''
+ %(textcha)s
++%(recaptcha)s
+ <table>
+     <tr>
+         <td class="label"><label>%(newname_label)s</label></td>
+--- MoinMoin/action/edit.py.orig	2016-10-31 20:44:01 UTC
++++ MoinMoin/action/edit.py
+@@ -163,6 +163,9 @@ def execute(pagename, request):
+             from MoinMoin.security.textcha import TextCha
+             if not TextCha(request).check_answer_from_form():
+                 raise pg.SaveError(_('TextCha: Wrong answer! Try again below...'))
++            from MoinMoin.security.sec_recaptcha import ReCaptcha
++            if not ReCaptcha(request).check_answer_from_form():
++                raise pg.SaveError(_('ReCaptcha: Wrong answer! Try again below...'))
+             if request.cfg.comment_required and not comment:
+                 raise pg.SaveError(_('Supplying a comment is mandatory. Write a comment below and try again...'))
+             savemsg = pg.saveText(savetext, rev, trivial=trivial, comment=comment)
+--- MoinMoin/action/Load.py.orig	2016-10-31 20:44:01 UTC
++++ MoinMoin/action/Load.py
+@@ -14,6 +14,7 @@ from MoinMoin.action import ActionBase, AttachFile
+ from MoinMoin.PageEditor import PageEditor
+ from MoinMoin.Page import Page
+ from MoinMoin.security.textcha import TextCha
++from MoinMoin.security.sec_recaptcha import ReCaptcha
+ 
+ class Load(ActionBase):
+     """ Load page action
+@@ -40,6 +41,8 @@ class Load(ActionBase):
+         # but it could be extended to more/all attachment write access
+         if not TextCha(request).check_answer_from_form():
+             return status, _('TextCha: Wrong answer! Go back and try again...')
++        if not ReCaptcha(request).check_answer_from_form():
++            return _('ReCaptcha: Wrong answer! Go back and try again...')
+ 
+         comment = form.get('comment', u'')
+         comment = wikiutil.clean_input(comment)
+@@ -97,6 +100,7 @@ class Load(ActionBase):
+ <dd><input type="text" name="comment" size="80" maxlength="200"></dd>
+ </dl>
+ %(textcha)s
++%(recaptcha)s
+ <p>
+ <input type="hidden" name="action" value="%(action_name)s">
+ <input type="hidden" name="do" value="upload">
+@@ -115,6 +119,7 @@ class Load(ActionBase):
+     'buttons_html': buttons_html,
+     'action_name': self.form_trigger,
+     'textcha': TextCha(self.request).render(),
++    'recaptcha': ReCaptcha(self.request).render(),
+ }
+ 
+ def execute(pagename, request):
+--- MoinMoin/action/newaccount.py.orig	2016-10-31 20:44:01 UTC
++++ MoinMoin/action/newaccount.py
+@@ -10,6 +10,7 @@ from MoinMoin import user, wikiutil
+ from MoinMoin.Page import Page
+ from MoinMoin.widget import html
+ from MoinMoin.security.textcha import TextCha
++from MoinMoin.security.sec_recaptcha import ReCaptcha
+ from MoinMoin.auth import MoinAuth
+ 
+ 
+@@ -26,6 +27,9 @@ def _create_user(request):
+     if not TextCha(request).check_answer_from_form():
+         return _('TextCha: Wrong answer! Go back and try again...')
+ 
++    if not ReCaptcha(request).check_answer_from_form():
++        return _('ReCaptcha: Wrong answer! Go back and try again...')
++
+     # Create user profile
+     theuser = user.User(request, auth_method="new-user")
+ 
+@@ -141,6 +145,17 @@ def _create_form(request):
+         if textcha:
+             td.append(textcha.render())
+         row.append(td)
++
++    recaptcha = ReCaptcha(request)
++    if recaptcha.is_enabled():
++        row = html.TR()
++        tbl.append(row)
++        row.append(html.TD().append(html.STRONG().append(
++                                      html.Text(_('ReCaptcha (required)')))))
++        td = html.TD()
++        if recaptcha:
++            td.append(recaptcha.render())
++        row.append(td)        
+ 
+     row = html.TR()
+     tbl.append(row)
+--- MoinMoin/PageEditor.py.orig	2016-10-31 20:44:01 UTC
++++ MoinMoin/PageEditor.py
+@@ -422,6 +422,9 @@ If you don't want that, hit '''%(cancel_button_text)s'
+         from MoinMoin.security.textcha import TextCha
+         request.write(TextCha(request).render())
+ 
++        from MoinMoin.security.sec_recaptcha import ReCaptcha
++        request.write(ReCaptcha(request).render())
++
+         # Add textarea with page text
+         self.sendconfirmleaving()
+ 
+--- MoinMoin/PageGraphicalEditor.py.orig	2016-10-31 20:44:01 UTC
++++ MoinMoin/PageGraphicalEditor.py
+@@ -305,6 +305,9 @@ If you don't want that, hit '''%(cancel_button_text)s'
+         from MoinMoin.security.textcha import TextCha
+         request.write(TextCha(request).render())
+ 
++        from MoinMoin.security.sec_recaptcha import ReCaptcha
++        request.write(ReCaptcha(request).render())
++
+         self.sendconfirmleaving() # TODO update state of flgChange to make this work, see PageEditor
+ 
+         # Add textarea with page text
+--- MoinMoin/security/sec_recaptcha.py.orig	2018-05-02 03:24:23 UTC
++++ MoinMoin/security/sec_recaptcha.py
+@@ -0,0 +1,93 @@
++# -*- coding: iso-8859-1 -*-
++"""
++    MoinMoin - recaptcha support
++
++    Based heavily on the textcha support in textcha.py
++
++    @copyright: 2011 by Steve McIntyre
++    @copyright: 2018 by d42
++    @license: GNU GPL, see COPYING for details.
++"""
++import json
++import urllib
++import urllib2
++from textwrap import dedent
++
++from MoinMoin import log
++
++logging = log.getLogger(__name__)
++
++
++class ReCaptcha(object):
++    """ Recaptcha support """
++
++    VERIFY_URL = "https://www.google.com/recaptcha/api/siteverify"
++
++    def __init__(self, request):
++        """ Initialize the Recaptcha setup.
++
++            @param request: the request object
++        """
++        self.request = request
++        self.user_info = request.user.valid and request.user.name or request.remote_addr
++
++        self.site_key = getattr(request.cfg, "recaptcha_site_key", None)
++        self.secret_key = getattr(request.cfg, "recaptcha_secret_key", None)
++
++    def is_enabled(self):
++        """ check if we're configured, i.e. we have a key
++        """
++        return self.site_key and self.secret_key
++
++    def check_answer_from_form(self, form=None):
++        form = self.request.form if form is None else form
++
++        if not self.is_enabled():
++            return True
++
++        return self._submit(
++            response=form.get("g-recaptcha-response"),
++            remoteip=self.request.remote_addr
++        )
++
++    def _submit(self, response, remoteip):
++
++        def encode_if_necessary(s):
++            return s.encode("utf-8") if isinstance(s, unicode) else s
++
++        data = urllib.urlencode({
++            "secret": encode_if_necessary(self.secret_key),
++            "response":  encode_if_necessary(response),
++            "remoteip":  encode_if_necessary(remoteip),
++        })
++
++        request = urllib2.Request(
++            url=self.VERIFY_URL,
++            data=data,
++            headers={"Content-type": "application/x-www-form-urlencoded"}
++        )
++
++        try:
++            resp = urllib2.urlopen(request)
++            http_code = resp.getcode()
++            resp_json = json.loads(resp.read())
++            return resp_json["success"] if http_code == 200 else False
++        except urllib2.URLError as e:
++            logging.exception(e)
++            return False
++        finally:
++            resp.close()
++
++    def render(self, form=None):
++        """ Checks if ReCaptchas are enabled and returns HTML for one,
++            or an empty string if they are not enabled.
++
++            @return: unicode result html
++        """
++        if not self.is_enabled():
++            return u""
++
++        return dedent(u"""
++            <script src='//www.google.com/recaptcha/api.js'></script>
++            <div class="g-recaptcha" data-sitekey="{SITE_KEY}"></div>
++        """.format(SITE_KEY=self.site_key))

Added: head/www/moinmoin/files/extra-patch-verifyemail
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/moinmoin/files/extra-patch-verifyemail	Mon Jul 30 00:05:20 2018	(r475859)
@@ -0,0 +1,232 @@
+Description: Add support for requiring new accounts to be verified by email
+Origin: http://moinmo.in/MoinMoinPatch/VerifyAccountCreationByEmail
+Author: Steve McIntyre
+Last-Update: 2013-09-04
+
+--- ./MoinMoin/action/newaccount.py	2014-10-17 12:45:32.000000000 -0700
++++ ./MoinMoin/action/newaccount.py	2016-01-15 13:53:33.209638000 -0800
+@@ -12,5 +12,27 @@
+ from MoinMoin.security.textcha import TextCha
+ from MoinMoin.auth import MoinAuth
++from MoinMoin.mail import sendmail
++import subprocess
+ 
++def _send_verification_mail(request, user):
++    _ = request.getText
++    querystr = {'action': 'verifyaccount',
++                'i': user.id,
++                'v': user.account_verification}
++    page = Page(request, "FrontPage")
++    pagelink = "%(link)s" % {'link': request.getQualifiedURL(page.url(request, querystr))}
++    subject = _('[%(sitename)s] account verification check for new user %(username)s') % {
++            'sitename': request.page.cfg.sitename or request.url_root,
++            'username': user.name,
++        }
++
++    text = "Please verify your account by visiting this URL:\n\n  %(link)s\n\n" % {
++        'link': pagelink}
++
++    mailok, msg = sendmail.sendmail(request, user.email, subject, text, request.cfg.mail_from)
++    if mailok:
++        return (1, _("Verification message sent to %(email)s" % {'email': user.email}))
++    else:
++        return (mailok, msg)
+ 
+ def _create_user(request):
+@@ -43,6 +65,16 @@
+ 
+     # Name required to be unique. Check if name belong to another user.
+-    if user.getUserId(request, theuser.name):
+-        return _("This user name already belongs to somebody else.")
++    userid = user.getUserId(request, theuser.name)
++    if userid:
++        if request.cfg.require_email_verification and theuser.account_verification:
++            resendlink = request.page.url(request, querystr={
++                'action': 'newaccount',
++                'i': userid,
++                'resend': '1'})
++            return _('This user name already belongs to somebody else. If this is a new account'
++                     ' and you need another verification link, try <a href="%s">'
++                     'sending another one</a>. ' % resendlink)
++        else:
++            return _("This user name already belongs to somebody else.")
+ 
+     # try to get the password and pw repeat
+@@ -73,16 +105,39 @@
+     theuser.email = email.strip()
+     if not theuser.email and 'email' not in request.cfg.user_form_remove:
+-        return _("Please provide your email address. If you lose your"
+-                 " login information, you can get it by email.")
++        if request.cfg.require_email_verification:
++            return _("Please provide your email address. You will need it"
++                     " to be able to confirm your registration.")
++        else:
++            return _("Please provide your email address. If you lose your"
++                     " login information, you can get it by email.")
+ 
+     # Email should be unique - see also MoinMoin/script/accounts/moin_usercheck.py
+     if theuser.email and request.cfg.user_email_unique:
+-        if user.get_by_email_address(request, theuser.email):
+-            return _("This email already belongs to somebody else.")
++        emailuser = user.get_by_email_address(request, theuser.email)
++        if emailuser:
++            if request.cfg.require_email_verification and theuser.account_verification:
++                resendlink = request.page.url(request, querystr={
++                    'action': 'newaccount',
++                    'i': emailuser.id,
++                    'resend': '1'})
++                return _('This email already belongs to somebody else. If this is a new account'
++                         ' and you need another verification link, try <a href="%s">'
++                         'sending another one</a>. ' % resendlink)
++            else:
++                return _("This email already belongs to somebody else.")
++
++    # Send verification links if desired
++    if request.cfg.require_email_verification:        
++        mailok, msg = _send_verification_mail(request, theuser)
++        if mailok:
++            result = _("User account created! Use the link in your email (%s) to verify your account"
++                       " then you will be able to use this account to login..." % theuser.email)
++        else:
++            request.theme.add_msg(_("Unable to send verification mail, %s. Account creation aborted." % msg), "error")
++    else:
++        result = _("User account created! You can use this account to login now...")
+ 
+     # save data
+     theuser.save()
+-
+-    result = _("User account created! You can use this account to login now...")
+     return result
+ 
+@@ -171,7 +226,18 @@
+     submitted = form.has_key('create')
+ 
++    uid = request.values.get('i', None)
++    resend = request.values.get('resend', None)
++
+     if submitted: # user pressed create button
+         request.theme.add_msg(_create_user(request), "dialog")
+         return page.send_page()
++    if resend and uid:
++        theuser = user.User(request, id=uid)
++        mailok, msg = _send_verification_mail(request, theuser)
++        if mailok:
++            request.theme.add_msg(_("Verification message re-sent to %s" % theuser.email), "dialog")
++        else:
++            request.theme.add_msg(_("Unable to re-send verification message, %s" % msg), "dialog")
++        return page.send_page()
+     else: # show create form
+         request.theme.send_title(_("Create Account"), pagename=pagename)
+--- ./MoinMoin/action/verifyaccount.py	1969-12-31 16:00:00.000000000 -0800
++++ ./MoinMoin/action/verifyaccount.py	2016-01-15 13:53:33.209957000 -0800
+@@ -0,0 +1,64 @@
++# -*- coding: iso-8859-1 -*-
++"""
++    MoinMoin - verify account action
++
++    @copyright: 2012 Steve McIntyre
++    @license: GNU GPL, see COPYING for details.
++"""
++
++from MoinMoin import user, wikiutil
++from MoinMoin.Page import Page
++from MoinMoin.widget import html
++from MoinMoin.auth import MoinAuth
++
++def execute(pagename, request):
++    found = False
++    for auth in request.cfg.auth:
++        if isinstance(auth, MoinAuth):
++            found = True
++            break
++
++    if not found:
++        # we will not have linked, so forbid access
++        request.makeForbidden(403, 'No MoinAuth in auth list')
++        return
++
++    page = Page(request, "FrontPage")
++    _ = request.getText
++
++    if not request.cfg.require_email_verification:
++        result = _("Verification not configured!")
++        request.theme.add_msg(result, "error")
++        return page.send_page()
++
++    uid = request.values.get('i', None)
++    verify = request.values.get('v', None)
++
++    # Grab user profile
++    theuser = user.User(request, id=uid)
++
++    # Compare the verification code
++    if not theuser.valid:
++        result = _("Unable to verify user account i=%s v=%s") % (uid, verify)
++        request.theme.add_msg(result, "error")
++        return page.send_page()
++
++    if not theuser.account_verification:
++        result = _("User account has been verified!")
++        request.theme.add_msg(result, "error")
++        return page.send_page()
++
++    if theuser.account_verification != verify:
++        result = _("Unable to verify user account i=%s v=%s") % (uid, verify)
++        request.theme.add_msg(result, "error")
++        return page.send_page()
++
++    # All looks sane. Mark verification as done, save data
++    theuser.account_verification = ""
++    theuser.save()
++
++    loginlink = request.page.url(request, querystr={'action': 'login'})
++    result = _('User account verified! You can use this account to <a href="%s">login</a> now...' % loginlink)
++    request.theme.add_msg(result, "dialog")
++    return page.send_page()
++
+--- ./MoinMoin/auth/__init__.py	2014-10-17 12:45:32.000000000 -0700
++++ ./MoinMoin/auth/__init__.py	2016-01-15 13:53:33.210285000 -0800
+@@ -250,6 +250,13 @@
+         check_surge_protect(request, action='auth-name', username=username)
+ 
+-        u = user.User(request, name=username, password=password, auth_method=self.name)
++        u = user.User(request, name=username, password=password, auth_method=self.name)            
+         if u.valid:
++            try:
++                verification = u.account_verification
++            except:
++                verification = False
++            if request.cfg.require_email_verification and verification:
++                logging.debug("%s: could not authenticate user %r (not verified yet)" % (self.name, username))
++                return ContinueLogin(user_obj, _("User account not verified yet."))
+             logging.debug("%s: successfully authenticated user %r (valid)" % (self.name, u.name))
+             log_attempt("auth/login (moin)", True, request, username)
+--- ./MoinMoin/config/multiconfig.py	2014-10-17 12:45:32.000000000 -0700
++++ ./MoinMoin/config/multiconfig.py	2016-01-15 13:53:33.210918000 -0800
+@@ -1097,4 +1097,6 @@
+     ('userprefs_disabled', [],
+      "Disable the listed user preferences plugins."),
++    ('require_email_verification', False ,
++     "Require verification of new user accounts."),
+   )),
+   # ==========================================================================
+--- ./MoinMoin/user.py	2014-10-17 12:45:32.000000000 -0700
++++ ./MoinMoin/user.py	2016-01-15 13:53:33.211435000 -0800
+@@ -24,4 +24,5 @@
+ from copy import deepcopy
+ import md5crypt
++import uuid
+ 
+ try:
+@@ -523,4 +524,10 @@
+             if password is not None:
+                 self.enc_password = encodePassword(self._cfg, password)
++            self.account_creation_date = str(time.time())
++            self.account_creation_host = self._request.remote_addr
++            if self._cfg.require_email_verification:
++                self.account_verification = uuid.uuid4()
++            else:
++                self.account_verification = ""
+ 
+         # "may" so we can say "if user.may.read(pagename):"
+

Modified: head/www/moinmoin/files/patch-setup.py
==============================================================================
--- head/www/moinmoin/files/patch-setup.py	Sun Jul 29 22:49:09 2018	(r475858)
+++ head/www/moinmoin/files/patch-setup.py	Mon Jul 30 00:05:20 2018	(r475859)
@@ -1,6 +1,6 @@
---- ./setup.py.orig	2010-04-30 10:09:50.411058590 -0400
-+++ ./setup.py	2010-04-30 10:10:32.801862294 -0400
-@@ -26,6 +26,7 @@
+--- setup.py.orig	2016-10-31 20:44:02 UTC
++++ setup.py
+@@ -26,6 +26,7 @@ def isbad(name):
      return (name.startswith('.') or
              name.startswith('#') or
              name.endswith('.pickle') or

Modified: head/www/moinmoin/pkg-descr
==============================================================================
--- head/www/moinmoin/pkg-descr	Sun Jul 29 22:49:09 2018	(r475858)
+++ head/www/moinmoin/pkg-descr	Mon Jul 30 00:05:20 2018	(r475859)
@@ -2,4 +2,4 @@ MoinMoin is a Python clone of WikiWiki, which is a com
 it's a discussion medium; it's a repository; it's a mail system;
 it's a tool for collaboration.
 
-WWW: http://moinmo.in/
+WWW: https://moinmo.in/

Modified: head/www/moinmoin/pkg-plist
==============================================================================
--- head/www/moinmoin/pkg-plist	Sun Jul 29 22:49:09 2018	(r475858)
+++ head/www/moinmoin/pkg-plist	Mon Jul 30 00:05:20 2018	(r475859)
@@ -170,6 +170,9 @@ bin/moin
 %%PYTHON_SITELIBDIR%%/MoinMoin/action/userprofile.py
 %%PYTHON_SITELIBDIR%%/MoinMoin/action/userprofile.pyc
 %%PYTHON_SITELIBDIR%%/MoinMoin/action/userprofile.%%PYTHON_PYOEXTENSION%%
+%%VERIFYEMAIL%%%%PYTHON_SITELIBDIR%%/MoinMoin/action/verifyaccount.py
+%%VERIFYEMAIL%%%%PYTHON_SITELIBDIR%%/MoinMoin/action/verifyaccount.pyc
+%%VERIFYEMAIL%%%%PYTHON_SITELIBDIR%%/MoinMoin/action/verifyaccount.%%PYTHON_PYOEXTENSION%%
 %%PYTHON_SITELIBDIR%%/MoinMoin/auth/_PHPsessionParser.py
 %%PYTHON_SITELIBDIR%%/MoinMoin/auth/_PHPsessionParser.pyc
 %%PYTHON_SITELIBDIR%%/MoinMoin/auth/_PHPsessionParser.%%PYTHON_PYOEXTENSION%%
@@ -1039,6 +1042,9 @@ bin/moin
 %%PYTHON_SITELIBDIR%%/MoinMoin/security/textcha.py
 %%PYTHON_SITELIBDIR%%/MoinMoin/security/textcha.pyc
 %%PYTHON_SITELIBDIR%%/MoinMoin/security/textcha.%%PYTHON_PYOEXTENSION%%
+%%RECAPTCHA%%%%PYTHON_SITELIBDIR%%/MoinMoin/security/sec_recaptcha.py
+%%RECAPTCHA%%%%PYTHON_SITELIBDIR%%/MoinMoin/security/sec_recaptcha.pyc
+%%RECAPTCHA%%%%PYTHON_SITELIBDIR%%/MoinMoin/security/sec_recaptcha.%%PYTHON_PYOEXTENSION%%
 %%PYTHON_SITELIBDIR%%/MoinMoin/stats/__init__.py
 %%PYTHON_SITELIBDIR%%/MoinMoin/stats/__init__.pyc
 %%PYTHON_SITELIBDIR%%/MoinMoin/stats/__init__.%%PYTHON_PYOEXTENSION%%



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807300005.w6U05Kmg037475>