Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-certbot-nginx for 
openSUSE:Factory checked in at 2021-03-08 15:19:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-certbot-nginx (Old)
 and      /work/SRC/openSUSE:Factory/.python-certbot-nginx.new.2378 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-certbot-nginx"

Mon Mar  8 15:19:56 2021 rev:25 rq:877607 version:1.13.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-certbot-nginx/python-certbot-nginx.changes    
    2021-01-08 17:40:30.233047753 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-certbot-nginx.new.2378/python-certbot-nginx.changes
      2021-03-08 15:21:15.578114537 +0100
@@ -1,0 +2,8 @@
+Mon Mar  8 08:42:04 UTC 2021 - Mark??ta Machov?? <[email protected]>
+
+- update to version 1.13.0
+  * Support for Python 2 has been removed.
+  * The nginx authenticator now configures all matching HTTP and HTTPS vhosts 
for the HTTP-01 
+    challenge. It is now compatible with external HTTPS redirection by a CDN 
or load balancer.
+
+-------------------------------------------------------------------

Old:
----
  certbot-nginx-1.11.0.tar.gz

New:
----
  certbot-nginx-1.13.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-certbot-nginx.spec ++++++
--- /var/tmp/diff_new_pack.qbsEbP/_old  2021-03-08 15:21:16.150114957 +0100
+++ /var/tmp/diff_new_pack.qbsEbP/_new  2021-03-08 15:21:16.150114957 +0100
@@ -17,8 +17,9 @@
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%define skip_python2 1
 Name:           python-certbot-nginx
-Version:        1.11.0
+Version:        1.13.0
 Release:        0
 Summary:        Nginx plugin for Certbot
 License:        Apache-2.0

++++++ certbot-nginx-1.11.0.tar.gz -> certbot-nginx-1.13.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-nginx-1.11.0/PKG-INFO 
new/certbot-nginx-1.13.0/PKG-INFO
--- old/certbot-nginx-1.11.0/PKG-INFO   2021-01-05 18:37:18.250445600 +0100
+++ new/certbot-nginx-1.13.0/PKG-INFO   2021-03-02 22:37:32.920871300 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: certbot-nginx
-Version: 1.11.0
+Version: 1.13.0
 Summary: Nginx plugin for Certbot
 Home-page: https://github.com/letsencrypt/letsencrypt
 Author: Certbot Project
@@ -14,8 +14,6 @@
 Classifier: License :: OSI Approved :: Apache Software License
 Classifier: Operating System :: POSIX :: Linux
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
@@ -27,4 +25,4 @@
 Classifier: Topic :: System :: Networking
 Classifier: Topic :: System :: Systems Administration
 Classifier: Topic :: Utilities
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*
+Requires-Python: >=3.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-nginx-1.11.0/certbot_nginx/_internal/configurator.py 
new/certbot-nginx-1.13.0/certbot_nginx/_internal/configurator.py
--- old/certbot-nginx-1.11.0/certbot_nginx/_internal/configurator.py    
2021-01-05 18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/certbot_nginx/_internal/configurator.py    
2021-03-02 22:37:04.000000000 +0100
@@ -1,3 +1,4 @@
+# pylint: disable=too-many-lines
 """Nginx Configuration"""
 from distutils.version import LooseVersion
 import logging
@@ -15,8 +16,10 @@
 from acme import crypto_util as acme_crypto_util
 from acme.magic_typing import Dict
 from acme.magic_typing import List
+from acme.magic_typing import Optional
 from acme.magic_typing import Set
 from acme.magic_typing import Text
+from acme.magic_typing import Tuple
 from certbot import crypto_util
 from certbot import errors
 from certbot import interfaces
@@ -105,7 +108,7 @@
         self.save_notes = ""
 
         # For creating new vhosts if no names match
-        self.new_vhost = None
+        self.new_vhost: Optional[obj.VirtualHost] = None
 
         # List of vhosts configured per wildcard domain on this run.
         # used by deploy_cert() and enhance()
@@ -116,7 +119,7 @@
         self._chall_out = 0
 
         # These will be set in the prepare function
-        self.parser = None
+        self.parser: Optional[parser.NginxParser] = None
         self.version = version
         self.openssl_version = openssl_version
         self._enhance_func = {"redirect": self._enable_redirect,
@@ -377,10 +380,13 @@
                     ipv6only_present = True
         return (ipv6_active, ipv6only_present)
 
-    def _vhost_from_duplicated_default(self, domain, allow_port_mismatch, 
port):
+    def _vhost_from_duplicated_default(self, domain: str, allow_port_mismatch: 
bool, port: str
+                                       ) -> obj.VirtualHost:
         """if allow_port_mismatch is False, only server blocks with matching 
ports will be
            used as a default server block template.
         """
+        assert self.parser is not None # prepare should already have been 
called here
+
         if self.new_vhost is None:
             default_vhost = self._get_default_vhost(domain, 
allow_port_mismatch, port)
             self.new_vhost = self.parser.duplicate_vhost(default_vhost,
@@ -509,7 +515,7 @@
                 match['rank'] += NO_SSL_MODIFIER
         return sorted(matches, key=lambda x: x['rank'])
 
-    def choose_redirect_vhosts(self, target_name, port, 
create_if_no_match=False):
+    def choose_redirect_vhosts(self, target_name: str, port: str) -> 
List[obj.VirtualHost]:
         """Chooses a single virtual host for redirect enhancement.
 
         Chooses the vhost most closely matching target_name that is
@@ -523,9 +529,6 @@
 
         :param str target_name: domain name
         :param str port: port number
-        :param bool create_if_no_match: If we should create a new vhost from 
default
-            when there is no match found. If we can't choose a default, raise a
-            MisconfigurationError.
 
         :returns: vhosts associated with name
         :rtype: list of :class:`~certbot_nginx._internal.obj.VirtualHost`
@@ -538,32 +541,75 @@
         else:
             matches = self._get_redirect_ranked_matches(target_name, port)
             vhosts = [x for x in [self._select_best_name_match(matches)]if x 
is not None]
-        if not vhosts and create_if_no_match:
-            vhosts = [self._vhost_from_duplicated_default(target_name, False, 
port)]
         return vhosts
 
-    def _port_matches(self, test_port, matching_port):
+    def choose_auth_vhosts(self, target_name: str) -> 
Tuple[List[obj.VirtualHost],
+                                                            
List[obj.VirtualHost]]:
+        """Returns a list of HTTP and HTTPS vhosts with a server_name matching 
target_name.
+
+        If no HTTP vhost exists, one will be cloned from the default vhost. If 
that fails, no HTTP
+        vhost will be returned.
+
+        :param str target_name: non-wildcard domain name
+
+        :returns: tuple of HTTP and HTTPS virtualhosts
+        :rtype: tuple of :class:`~certbot_nginx._internal.obj.VirtualHost`
+
+        """
+        vhosts = [m['vhost'] for m in self._get_ranked_matches(target_name) if 
m and 'vhost' in m]
+        http_vhosts = [vh for vh in vhosts if
+                       self._vhost_listening(vh, str(self.config.http01_port), 
False)]
+        https_vhosts = [vh for vh in vhosts if
+                        self._vhost_listening(vh, str(self.config.https_port), 
True)]
+
+        # If no HTTP vhost matches, try create one from the default_server on 
http01_port.
+        if not http_vhosts:
+            try:
+                http_vhosts = 
[self._vhost_from_duplicated_default(target_name, False,
+                                                                   
str(self.config.http01_port))]
+            except errors.MisconfigurationError:
+                http_vhosts = []
+
+        return http_vhosts, https_vhosts
+
+    def _port_matches(self, test_port: str, matching_port: str) -> bool:
         # test_port is a number, matching is a number or "" or None
         if matching_port == "" or matching_port is None:
             # if no port is specified, Nginx defaults to listening on port 80.
             return test_port == self.DEFAULT_LISTEN_PORT
         return test_port == matching_port
 
-    def _vhost_listening_on_port_no_ssl(self, vhost, port):
-        found_matching_port = False
+    def _vhost_listening(self, vhost: obj.VirtualHost, port: str, ssl: bool) 
-> bool:
+        """Tests whether a vhost has an address listening on a port with SSL 
enabled or disabled.
+
+        :param `obj.VirtualHost` vhost: The vhost whose addresses will be 
tested
+        :param port str: The port number as a string that the address should 
be bound to
+        :param bool ssl: Whether SSL should be enabled or disabled on the 
address
+
+        :returns: Whether the vhost has an address listening on the port and 
protocol.
+        :rtype: bool
+
+        """
+        assert self.parser is not None # prepare should already have been 
called here
+
+        # if the 'ssl on' directive is present on the vhost, all its addresses 
have SSL enabled
+        all_addrs_are_ssl = self.parser.has_ssl_on_directive(vhost)
+
+        # if we want ssl vhosts: either 'ssl on' or 'addr.ssl' should be 
enabled
+        # if we want plaintext vhosts: neither 'ssl on' nor 'addr.ssl' should 
be enabled
+        _ssl_matches = lambda addr: addr.ssl or all_addrs_are_ssl if ssl else \
+                                    not addr.ssl and not all_addrs_are_ssl
+
+        # if there are no listen directives at all, Nginx defaults to
+        # listening on port 80.
         if not vhost.addrs:
-            # if there are no listen directives at all, Nginx defaults to
-            # listening on port 80.
-            found_matching_port = (port == self.DEFAULT_LISTEN_PORT)
-        else:
-            for addr in vhost.addrs:
-                if self._port_matches(port, addr.get_port()) and not addr.ssl:
-                    found_matching_port = True
+            return port == self.DEFAULT_LISTEN_PORT and ssl == 
all_addrs_are_ssl
+
+        return any(self._port_matches(port, addr.get_port()) and 
_ssl_matches(addr)
+                   for addr in vhost.addrs)
 
-        if found_matching_port:
-            # make sure we don't have an 'ssl on' directive
-            return not self.parser.has_ssl_on_directive(vhost)
-        return False
+    def _vhost_listening_on_port_no_ssl(self, vhost: obj.VirtualHost, port: 
str) -> bool:
+        return self._vhost_listening(vhost, port, False)
 
     def _get_redirect_ranked_matches(self, target_name, port):
         """Gets a ranked list of plaintextish port-listening vhosts matching 
target_name
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-nginx-1.11.0/certbot_nginx/_internal/http_01.py 
new/certbot-nginx-1.13.0/certbot_nginx/_internal/http_01.py
--- old/certbot-nginx-1.11.0/certbot_nginx/_internal/http_01.py 2021-01-05 
18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/certbot_nginx/_internal/http_01.py 2021-03-02 
22:37:04.000000000 +0100
@@ -5,6 +5,8 @@
 
 from acme import challenges
 from acme.magic_typing import List
+from acme.magic_typing import Optional
+from certbot import achallenges
 from certbot import errors
 from certbot.compat import os
 from certbot.plugins import common
@@ -138,13 +140,12 @@
     def _get_validation_path(self, achall):
         return os.sep + os.path.join(challenges.HTTP01.URI_ROOT_PATH, 
achall.chall.encode("token"))
 
-    def _make_server_block(self, achall):
+    def _make_server_block(self, achall: 
achallenges.KeyAuthorizationAnnotatedChallenge) -> List:
         """Creates a server block for a challenge.
+
         :param achall: Annotated HTTP-01 challenge
-        :type achall:
-            :class:`certbot.achallenges.KeyAuthorizationAnnotatedChallenge`
-        :param list addrs: addresses of challenged domain
-            :class:`list` of type :class:`~nginx.obj.Addr`
+        :type achall: 
:class:`certbot.achallenges.KeyAuthorizationAnnotatedChallenge`
+
         :returns: server block for the challenge host
         :rtype: list
         """
@@ -172,34 +173,35 @@
         return location_directive
 
 
-    def _make_or_mod_server_block(self, achall):
-        """Modifies a server block to respond to a challenge.
+    def _make_or_mod_server_block(self, achall: 
achallenges.KeyAuthorizationAnnotatedChallenge
+                                  ) -> Optional[List]:
+        """Modifies server blocks to respond to a challenge. Returns a new 
HTTP server block
+           to add to the configuration if an existing one can't be found.
 
         :param achall: Annotated HTTP-01 challenge
-        :type achall:
-            :class:`certbot.achallenges.KeyAuthorizationAnnotatedChallenge`
+        :type achall: 
:class:`certbot.achallenges.KeyAuthorizationAnnotatedChallenge`
+
+        :returns: new server block to be added, if any
+        :rtype: list
 
         """
-        try:
-            vhosts = self.configurator.choose_redirect_vhosts(achall.domain,
-                '%i' % self.configurator.config.http01_port, 
create_if_no_match=True)
-        except errors.MisconfigurationError:
+        http_vhosts, https_vhosts = 
self.configurator.choose_auth_vhosts(achall.domain)
+
+        new_vhost: Optional[list] = None
+        if not http_vhosts:
             # Couldn't find either a matching name+port server block
             # or a port+default_server block, so create a dummy block
-            return self._make_server_block(achall)
+            new_vhost = self._make_server_block(achall)
+
+        # Modify any existing server blocks
+        for vhost in set(http_vhosts + https_vhosts):
+            location_directive = [self._location_directive_for_achall(achall)]
+
+            self.configurator.parser.add_server_directives(vhost, 
location_directive)
+
+            rewrite_directive = [['rewrite', ' ', 
'^(/.well-known/acme-challenge/.*)',
+                                    ' ', '$1', ' ', 'break']]
+            self.configurator.parser.add_server_directives(vhost,
+                rewrite_directive, insert_at_top=True)
 
-        # len is max 1 because Nginx doesn't authenticate wildcards
-        # if len were or vhosts None, we would have errored
-        vhost = vhosts[0]
-
-        # Modify existing server block
-        location_directive = [self._location_directive_for_achall(achall)]
-
-        self.configurator.parser.add_server_directives(vhost,
-            location_directive)
-
-        rewrite_directive = [['rewrite', ' ', 
'^(/.well-known/acme-challenge/.*)',
-                                ' ', '$1', ' ', 'break']]
-        self.configurator.parser.add_server_directives(vhost,
-            rewrite_directive, insert_at_top=True)
-        return None
+        return new_vhost
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-nginx-1.11.0/certbot_nginx/_internal/nginxparser.py 
new/certbot-nginx-1.13.0/certbot_nginx/_internal/nginxparser.py
--- old/certbot-nginx-1.11.0/certbot_nginx/_internal/nginxparser.py     
2021-01-05 18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/certbot_nginx/_internal/nginxparser.py     
2021-03-02 22:37:04.000000000 +0100
@@ -15,12 +15,11 @@
 from pyparsing import stringEnd
 from pyparsing import White
 from pyparsing import ZeroOrMore
-import six
 from acme.magic_typing import IO, Any # pylint: disable=unused-import
 
 logger = logging.getLogger(__name__)
 
-class RawNginxParser(object):
+class RawNginxParser:
     # pylint: disable=pointless-statement
     """A class that parses nginx configuration with pyparsing."""
 
@@ -70,7 +69,7 @@
         """Returns the parsed tree as a list."""
         return self.parse().asList()
 
-class RawNginxDumper(object):
+class RawNginxDumper:
     """A class that dumps nginx configuration from the provided tree."""
     def __init__(self, blocks):
         self.blocks = blocks
@@ -79,7 +78,7 @@
         """Iterates the dumped nginx content."""
         blocks = blocks or self.blocks
         for b0 in blocks:
-            if isinstance(b0, six.string_types):
+            if isinstance(b0, str):
                 yield b0
                 continue
             item = copy.deepcopy(b0)
@@ -96,7 +95,7 @@
                 yield '}'
             else: # not a block - list of strings
                 semicolon = ";"
-                if isinstance(item[0], six.string_types) and item[0].strip() 
== '#': # comment
+                if isinstance(item[0], str) and item[0].strip() == '#': # 
comment
                     semicolon = ""
                 yield "".join(item) + semicolon
 
@@ -131,14 +130,14 @@
 
 
 def dumps(blocks):
-    # type: (UnspacedList) -> six.text_type
+    # type: (UnspacedList) -> str
     """Dump to a Unicode string.
 
     :param UnspacedList block: The parsed tree
-    :rtype: six.text_type
+    :rtype: str
 
     """
-    return six.text_type(RawNginxDumper(blocks.spaced))
+    return str(RawNginxDumper(blocks.spaced))
 
 
 def dump(blocks, _file):
@@ -154,7 +153,7 @@
     _file.write(dumps(blocks))
 
 
-spacey = lambda x: (isinstance(x, six.string_types) and x.isspace()) or x == ''
+spacey = lambda x: (isinstance(x, str) and x.isspace()) or x == ''
 
 class UnspacedList(list):
     """Wrap a list [of lists], making any whitespace entries magically 
invisible"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-nginx-1.11.0/certbot_nginx/_internal/obj.py 
new/certbot-nginx-1.13.0/certbot_nginx/_internal/obj.py
--- old/certbot-nginx-1.11.0/certbot_nginx/_internal/obj.py     2021-01-05 
18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/certbot_nginx/_internal/obj.py     2021-03-02 
22:37:04.000000000 +0100
@@ -1,7 +1,6 @@
 """Module contains classes used by the Nginx Configurator."""
 import re
 
-import six
 
 from certbot.plugins import common
 
@@ -144,7 +143,7 @@
         return False
 
 
-class VirtualHost(object):
+class VirtualHost:
     """Represents an Nginx Virtualhost.
 
     :ivar str filep: file path of VH
@@ -211,7 +210,7 @@
     def contains_list(self, test):
         """Determine if raw server block contains test list at top level
         """
-        for i in six.moves.range(0, len(self.raw) - len(test) + 1):
+        for i in range(0, len(self.raw) - len(test) + 1):
             if self.raw[i:i + len(test)] == test:
                 return True
         return False
@@ -250,7 +249,7 @@
     """Find a directive of type directive_name in directives. If match_content 
is given,
        Searches for `match_content` in the directive arguments.
     """
-    if not directives or isinstance(directives, six.string_types):
+    if not directives or isinstance(directives, str):
         return None
 
     # If match_content is None, just match on directive type. Otherwise, match 
on
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-nginx-1.11.0/certbot_nginx/_internal/parser.py 
new/certbot-nginx-1.13.0/certbot_nginx/_internal/parser.py
--- old/certbot-nginx-1.11.0/certbot_nginx/_internal/parser.py  2021-01-05 
18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/certbot_nginx/_internal/parser.py  2021-03-02 
22:37:04.000000000 +0100
@@ -7,10 +7,10 @@
 import re
 
 import pyparsing
-import six
 
 from acme.magic_typing import Dict
 from acme.magic_typing import List
+from acme.magic_typing import Optional
 from acme.magic_typing import Set
 from acme.magic_typing import Tuple
 from acme.magic_typing import Union
@@ -22,7 +22,7 @@
 logger = logging.getLogger(__name__)
 
 
-class NginxParser(object):
+class NginxParser:
     """Class handles the fine details of parsing the Nginx Configuration.
 
     :ivar str root: Normalized absolute path to the server root
@@ -362,8 +362,9 @@
         except errors.MisconfigurationError as err:
             raise errors.MisconfigurationError("Problem in %s: %s" % 
(filename, str(err)))
 
-    def duplicate_vhost(self, vhost_template, 
remove_singleton_listen_params=False,
-        only_directives=None):
+    def duplicate_vhost(self, vhost_template: obj.VirtualHost,
+                        remove_singleton_listen_params: bool = False,
+                        only_directives: Optional[List] = None) -> 
obj.VirtualHost:
         """Duplicate the vhost in the configuration files.
 
         :param :class:`~certbot_nginx._internal.obj.VirtualHost` 
vhost_template: The vhost
@@ -549,7 +550,7 @@
     """
     return (isinstance(entry, list) and
             len(entry) == 2 and entry[0] == 'include' and
-            isinstance(entry[1], six.string_types))
+            isinstance(entry[1], str))
 
 def _is_ssl_on_directive(entry):
     """Checks if an nginx parsed entry is an 'ssl on' directive.
@@ -654,7 +655,7 @@
     directive_name = directive[0]
     def can_append(loc, dir_name):
         """ Can we append this directive to the block? """
-        return loc is None or (isinstance(dir_name, six.string_types)
+        return loc is None or (isinstance(dir_name, str)
             and dir_name in REPEATABLE_DIRECTIVES)
 
     err_fmt = 'tried to insert directive "{0}" but found conflicting "{1}".'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-nginx-1.11.0/certbot_nginx/_internal/parser_obj.py 
new/certbot-nginx-1.13.0/certbot_nginx/_internal/parser_obj.py
--- old/certbot-nginx-1.11.0/certbot_nginx/_internal/parser_obj.py      
2021-01-05 18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/certbot_nginx/_internal/parser_obj.py      
2021-03-02 22:37:04.000000000 +0100
@@ -4,7 +4,6 @@
 import abc
 import logging
 
-import six
 
 from acme.magic_typing import List
 from certbot import errors
@@ -14,7 +13,7 @@
 COMMENT_BLOCK = ["#", COMMENT]
 
 
-class Parsable(object):
+class Parsable:
     """ Abstract base class for "Parsable" objects whose underlying 
representation
     is a tree of lists.
 
@@ -152,7 +151,7 @@
         if not isinstance(raw_list, list):
             raise errors.MisconfigurationError("Statements parsing expects a 
list!")
         # If there's a trailing whitespace in the list of statements, keep 
track of it.
-        if raw_list and isinstance(raw_list[-1], six.string_types) and 
raw_list[-1].isspace():
+        if raw_list and isinstance(raw_list[-1], str) and 
raw_list[-1].isspace():
             self._trailing_whitespace = raw_list[-1]
             raw_list = raw_list[:-1]
         self._data = [parse_raw(elem, self, add_spaces) for elem in raw_list]
@@ -184,7 +183,7 @@
 def _space_list(list_):
     """ Inserts whitespace between adjacent non-whitespace tokens. """
     spaced_statement = [] # type: List[str]
-    for i in reversed(six.moves.xrange(len(list_))):
+    for i in reversed(range(len(list_))):
         spaced_statement.insert(0, list_[i])
         if i > 0 and not list_[i].isspace() and not list_[i-1].isspace():
             spaced_statement.insert(0, " ")
@@ -206,7 +205,7 @@
         :returns: whether this lists is parseable by `Sentence`.
         """
         return isinstance(lists, list) and len(lists) > 0 and \
-            all(isinstance(elem, six.string_types) for elem in lists)
+            all(isinstance(elem, str) for elem in lists)
 
     def parse(self, raw_list, add_spaces=False):
         """ Parses a list of string types into this object.
@@ -214,7 +213,7 @@
         if add_spaces:
             raw_list = _space_list(raw_list)
         if not isinstance(raw_list, list) or \
-                any(not isinstance(elem, six.string_types) for elem in 
raw_list):
+                any(not isinstance(elem, str) for elem in raw_list):
             raise errors.MisconfigurationError("Sentence parsing expects a 
list of string types.")
         self._data = raw_list
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-nginx-1.11.0/certbot_nginx.egg-info/PKG-INFO 
new/certbot-nginx-1.13.0/certbot_nginx.egg-info/PKG-INFO
--- old/certbot-nginx-1.11.0/certbot_nginx.egg-info/PKG-INFO    2021-01-05 
18:37:18.000000000 +0100
+++ new/certbot-nginx-1.13.0/certbot_nginx.egg-info/PKG-INFO    2021-03-02 
22:37:32.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: certbot-nginx
-Version: 1.11.0
+Version: 1.13.0
 Summary: Nginx plugin for Certbot
 Home-page: https://github.com/letsencrypt/letsencrypt
 Author: Certbot Project
@@ -14,8 +14,6 @@
 Classifier: License :: OSI Approved :: Apache Software License
 Classifier: Operating System :: POSIX :: Linux
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
@@ -27,4 +25,4 @@
 Classifier: Topic :: System :: Networking
 Classifier: Topic :: System :: Systems Administration
 Classifier: Topic :: Utilities
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*
+Requires-Python: >=3.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-nginx-1.11.0/certbot_nginx.egg-info/SOURCES.txt 
new/certbot-nginx-1.13.0/certbot_nginx.egg-info/SOURCES.txt
--- old/certbot-nginx-1.11.0/certbot_nginx.egg-info/SOURCES.txt 2021-01-05 
18:37:18.000000000 +0100
+++ new/certbot-nginx-1.13.0/certbot_nginx.egg-info/SOURCES.txt 2021-03-02 
22:37:32.000000000 +0100
@@ -31,7 +31,6 @@
 tests/obj_test.py
 tests/parser_obj_test.py
 tests/parser_test.py
-tests/test_log_util.py
 tests/test_util.py
 tests/testdata/etc_nginx/broken.conf
 tests/testdata/etc_nginx/comment_in_file.conf
@@ -44,6 +43,7 @@
 tests/testdata/etc_nginx/nginx.conf
 tests/testdata/etc_nginx/server.conf
 tests/testdata/etc_nginx/valid_unicode_comments.conf
+tests/testdata/etc_nginx/sites-enabled/both.com
 tests/testdata/etc_nginx/sites-enabled/default
 tests/testdata/etc_nginx/sites-enabled/example.com
 tests/testdata/etc_nginx/sites-enabled/example.net
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-nginx-1.11.0/certbot_nginx.egg-info/requires.txt 
new/certbot-nginx-1.13.0/certbot_nginx.egg-info/requires.txt
--- old/certbot-nginx-1.11.0/certbot_nginx.egg-info/requires.txt        
2021-01-05 18:37:18.000000000 +0100
+++ new/certbot-nginx-1.13.0/certbot_nginx.egg-info/requires.txt        
2021-03-02 22:37:32.000000000 +0100
@@ -1,9 +1,6 @@
 acme>=1.4.0
 certbot>=1.6.0
-PyOpenSSL
-pyparsing>=1.5.5
-setuptools
+PyOpenSSL>=17.3.0
+pyparsing>=2.2.0
+setuptools>=39.0.1
 zope.interface
-
-[:python_version < "3.3"]
-mock
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-nginx-1.11.0/setup.py 
new/certbot-nginx-1.13.0/setup.py
--- old/certbot-nginx-1.11.0/setup.py   2021-01-05 18:37:06.000000000 +0100
+++ new/certbot-nginx-1.13.0/setup.py   2021-03-02 22:37:05.000000000 +0100
@@ -1,32 +1,19 @@
-from distutils.version import LooseVersion
-import sys
-
-from setuptools import __version__ as setuptools_version
 from setuptools import find_packages
 from setuptools import setup
 
-version = '1.11.0'
+version = '1.13.0'
 
 # Remember to update local-oldest-requirements.txt when changing the minimum
 # acme/certbot version.
 install_requires = [
     'acme>=1.4.0',
     'certbot>=1.6.0',
-    'PyOpenSSL',
-    'pyparsing>=1.5.5',  # Python3 support
-    'setuptools',
+    'PyOpenSSL>=17.3.0',
+    'pyparsing>=2.2.0',
+    'setuptools>=39.0.1',
     'zope.interface',
 ]
 
-setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= 
LooseVersion('36.2'))
-if setuptools_known_environment_markers:
-    install_requires.append('mock ; python_version < "3.3"')
-elif 'bdist_wheel' in sys.argv[1:]:
-    raise RuntimeError('Error, you are trying to build certbot wheels using an 
old version '
-                       'of setuptools. Version 36.2+ of setuptools is 
required.')
-elif sys.version_info < (3,3):
-    install_requires.append('mock')
-
 setup(
     name='certbot-nginx',
     version=version,
@@ -35,7 +22,7 @@
     author="Certbot Project",
     author_email='[email protected]',
     license='Apache License 2.0',
-    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, 
!=3.5.*',
+    python_requires='>=3.6',
     classifiers=[
         'Development Status :: 5 - Production/Stable',
         'Environment :: Plugins',
@@ -43,8 +30,6 @@
         'License :: OSI Approved :: Apache Software License',
         'Operating System :: POSIX :: Linux',
         'Programming Language :: Python',
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-nginx-1.11.0/tests/configurator_test.py 
new/certbot-nginx-1.13.0/tests/configurator_test.py
--- old/certbot-nginx-1.11.0/tests/configurator_test.py 2021-01-05 
18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/tests/configurator_test.py 2021-03-02 
22:37:04.000000000 +0100
@@ -39,7 +39,7 @@
 
     def test_prepare(self):
         self.assertEqual((1, 6, 2), self.config.version)
-        self.assertEqual(12, len(self.config.parser.parsed))
+        self.assertEqual(13, len(self.config.parser.parsed))
 
     @mock.patch("certbot_nginx._internal.configurator.util.exe_exists")
     @mock.patch("certbot_nginx._internal.configurator.subprocess.Popen")
@@ -89,7 +89,7 @@
             "155.225.50.69.nephoscale.net", "www.example.org", "another.alias",
              "migration.com", "summer.com", "geese.com", "sslon.com",
              "globalssl.com", "globalsslsetssl.com", "ipv6.com", "ipv6ssl.com",
-             "headers.com", "example.net"})
+             "headers.com", "example.net", "ssl.both.com"})
 
     def test_supported_enhancements(self):
         self.assertEqual(['redirect', 'ensure-http-header', 'staple-ocsp'],
@@ -935,7 +935,19 @@
                                                 prefer_ssl=False,
                                                 no_ssl_filter_port='80')
             # Check that the dialog was called with only port 80 vhosts
-            self.assertEqual(len(mock_select_vhs.call_args[0][0]), 6)
+            self.assertEqual(len(mock_select_vhs.call_args[0][0]), 8)
+
+    def test_choose_auth_vhosts(self):
+        """choose_auth_vhosts correctly selects duplicative and HTTP/HTTPS 
vhosts"""
+        http, https = self.config.choose_auth_vhosts('ssl.both.com')
+        self.assertEqual(len(http), 4)
+        self.assertEqual(len(https), 2)
+        self.assertEqual(http[0].names, {'ssl.both.com'})
+        self.assertEqual(http[1].names, {'ssl.both.com'})
+        self.assertEqual(http[2].names, {'ssl.both.com'})
+        self.assertEqual(http[3].names, {'*.both.com'})
+        self.assertEqual(https[0].names, {'ssl.both.com'})
+        self.assertEqual(https[1].names, {'*.both.com'})
 
 
 class InstallSslOptionsConfTest(util.NginxTest):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-nginx-1.11.0/tests/http_01_test.py 
new/certbot-nginx-1.13.0/tests/http_01_test.py
--- old/certbot-nginx-1.11.0/tests/http_01_test.py      2021-01-05 
18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/tests/http_01_test.py      2021-03-02 
22:37:04.000000000 +0100
@@ -6,7 +6,6 @@
     import mock
 except ImportError: # pragma: no cover
     from unittest import mock # type: ignore
-import six
 
 from acme import challenges
 from certbot import achallenges
@@ -45,6 +44,10 @@
             challb=acme_util.chall_to_challb(
                 challenges.HTTP01(token=b"kNdwjxOeX0I_A8DXt9Msmg"), "pending"),
             domain="migration.com", account_key=account_key),
+        achallenges.KeyAuthorizationAnnotatedChallenge(
+            challb=acme_util.chall_to_challb(
+                challenges.HTTP01(token=b"kNdwjxOeX0I_A8DXt9Msmg"), "pending"),
+            domain="ipv6ssl.com", account_key=account_key),
     ]
 
     def setUp(self):
@@ -78,8 +81,8 @@
 
         http_responses = self.http01.perform()
 
-        self.assertEqual(len(http_responses), 4)
-        for i in six.moves.range(4):
+        self.assertEqual(len(http_responses), 5)
+        for i in range(5):
             self.assertEqual(http_responses[i], acme_responses[i])
 
     def test_mod_config(self):
@@ -106,6 +109,43 @@
             #     self.assertEqual(vhost.addrs, set(v_addr2_print))
             # self.assertEqual(vhost.names, 
set([response.z_domain.decode('ascii')]))
 
+    
@mock.patch('certbot_nginx._internal.parser.NginxParser.add_server_directives')
+    def test_mod_config_http_and_https(self, mock_add_server_directives):
+        """A server_name with both HTTP and HTTPS vhosts should get modded in 
both vhosts"""
+        self.configuration.https_port = 443
+        self.http01.add_chall(self.achalls[3]) # migration.com
+        self.http01._mod_config()  # pylint: disable=protected-access
+
+        # Domain has an HTTP and HTTPS vhost
+        # 2 * 'rewrite' + 2 * 'return 200 keyauthz' = 4
+        self.assertEqual(mock_add_server_directives.call_count, 4)
+
+    @mock.patch('certbot_nginx._internal.parser.nginxparser.dump')
+    
@mock.patch('certbot_nginx._internal.parser.NginxParser.add_server_directives')
+    def test_mod_config_only_https(self, mock_add_server_directives, 
mock_dump):
+        """A server_name with only an HTTPS vhost should get modded"""
+        self.http01.add_chall(self.achalls[4]) # ipv6ssl.com
+        self.http01._mod_config() # pylint: disable=protected-access
+
+        # It should modify the existing HTTPS vhost
+        self.assertEqual(mock_add_server_directives.call_count, 2)
+        # since there was no suitable HTTP vhost or default HTTP vhost, a 
non-empty one
+        # should have been created and written to the challenge conf file
+        self.assertNotEqual(mock_dump.call_args[0][0], [])
+
+    
@mock.patch('certbot_nginx._internal.parser.NginxParser.add_server_directives')
+    def test_mod_config_deduplicate(self, mock_add_server_directives):
+        """A vhost that appears in both HTTP and HTTPS vhosts only gets modded 
once"""
+        achall = achallenges.KeyAuthorizationAnnotatedChallenge(
+            challb=acme_util.chall_to_challb(
+                challenges.HTTP01(token=b"kNdwjxOeX0I_A8DXt9Msmg"), "pending"),
+            domain="ssl.both.com", account_key=AUTH_KEY)
+        self.http01.add_chall(achall)
+        self.http01._mod_config() # pylint: disable=protected-access
+
+        # Should only get called 5 times, rather than 6, because two vhosts 
are the same
+        self.assertEqual(mock_add_server_directives.call_count, 5*2)
+
     
@mock.patch("certbot_nginx._internal.configurator.NginxConfigurator.ipv6_info")
     def test_default_listen_addresses_no_memoization(self, ipv6_info):
         # pylint: disable=protected-access
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-nginx-1.11.0/tests/parser_test.py 
new/certbot-nginx-1.13.0/tests/parser_test.py
--- old/certbot-nginx-1.11.0/tests/parser_test.py       2021-01-05 
18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/tests/parser_test.py       2021-03-02 
22:37:04.000000000 +0100
@@ -51,6 +51,7 @@
         self.assertEqual({nparser.abs_path(x) for x in
                           ['foo.conf', 'nginx.conf', 'server.conf',
                            'sites-enabled/default',
+                           'sites-enabled/both.com',
                            'sites-enabled/example.com',
                            'sites-enabled/headers.com',
                            'sites-enabled/migration.com',
@@ -88,7 +89,7 @@
         parsed = nparser._parse_files(nparser.abs_path(
             'sites-enabled/example.com.test'))
         self.assertEqual(3, len(glob.glob(nparser.abs_path('*.test'))))
-        self.assertEqual(9, len(
+        self.assertEqual(10, len(
             glob.glob(nparser.abs_path('sites-enabled/*.test'))))
         self.assertEqual([[['server'], [['listen', '69.50.225.155:9000'],
                                         ['listen', '127.0.0.1'],
@@ -171,7 +172,7 @@
                                                   '*.www.example.com'},
                                  [], [2, 1, 0])
 
-        self.assertEqual(14, len(vhosts))
+        self.assertEqual(19, len(vhosts))
         example_com = [x for x in vhosts if 'example.com' in x.filep][0]
         self.assertEqual(vhost3, example_com)
         default = [x for x in vhosts if 'default' in x.filep][0]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-nginx-1.11.0/tests/test_log_util.py 
new/certbot-nginx-1.13.0/tests/test_log_util.py
--- old/certbot-nginx-1.11.0/tests/test_log_util.py     2021-01-05 
18:37:05.000000000 +0100
+++ new/certbot-nginx-1.13.0/tests/test_log_util.py     1970-01-01 
01:00:00.000000000 +0100
@@ -1,125 +0,0 @@
-"""Backport for `TestCase.assertLogs()`.
-
-Most of the idea and code are from CPython implementation.
-https://github.com/python/cpython/blob/b76518d43fb82ed9e5d27025d18c90a23d525c90/Lib/unittest/case.py
-"""
-import logging
-import collections
-
-__all__ = ['AssertLogsMixin']
-
-LoggingWatcher = collections.namedtuple('LoggingWatcher', ['records', 
'output'])
-
-
-class CapturingHandler(logging.Handler):
-    """
-    A logging handler capturing all (raw and formatted) logging output.
-    """
-
-    def __init__(self):
-        super(CapturingHandler, self).__init__()
-        self.watcher = LoggingWatcher([], [])
-
-    def flush(self):
-        pass
-
-    def emit(self, record):
-        self.watcher.records.append(record)
-        self.watcher.output.append(self.format(record))
-
-
-
-class AssertLogsContext(object):
-    """
-    A context manager used to implement `TestCase.assertLogs()`.
-    """
-
-    LOGGING_FORMAT = '%(levelname)s:%(name)s:%(message)s'
-
-    def __init__(self, test_case, logger_name, level):
-        self.test_case = test_case
-
-        self.logger_name = logger_name
-        self.logger_states = None
-        self.logger = None
-
-        if level:
-            # pylint: disable=protected-access,no-member
-            try:
-                # In Python 3.x
-                name_to_level = logging._nameToLevel  # type: ignore
-            except AttributeError:
-                # In Python 2.7
-                name_to_level = logging._levelNames  # type: ignore
-
-            self.level = name_to_level.get(level, level)
-        else:
-            self.level = logging.INFO
-
-        self.watcher = None
-
-    def _save_logger_states(self):
-        self.logger_states = (self.logger.handlers[:], self.logger.level, 
self.logger.propagate)
-
-    def _restore_logger_states(self):
-        self.logger.handlers, self.logger.level, self.logger.propagate = 
self.logger_states
-
-    def __enter__(self):
-        if isinstance(self.logger_name, logging.Logger):
-            self.logger = self.logger_name
-        else:
-            self.logger = logging.getLogger(self.logger_name)
-
-        formatter = logging.Formatter(self.LOGGING_FORMAT)
-
-        handler = CapturingHandler()
-        handler.setFormatter(formatter)
-
-        self._save_logger_states()
-        self.logger.handlers = [handler]
-        self.logger.setLevel(self.level)
-        self.logger.propagate = False
-
-        self.watcher = handler.watcher
-        return handler.watcher
-
-    def __exit__(self, exc_type, exc_value, tb):
-        self._restore_logger_states()
-
-        if exc_type is not None:
-            # let unexpected exceptions pass through
-            return
-
-        if not self.watcher.records:
-            self._raiseFailure(
-                "no logs of level {} or higher triggered on {}"
-                .format(logging.getLevelName(self.level), self.logger.name))
-
-    def _raiseFailure(self, message):
-        message = self.test_case._formatMessage(None, message)  # pylint: 
disable=protected-access
-        raise self.test_case.failureException(message)
-
-
-class AssertLogsMixin(object):
-    """
-    A mixin that implements `TestCase.assertLogs()`.
-    """
-
-    def assertLogs(self, logger=None, level=None):
-        """Fail unless a log message of level *level* or higher is emitted
-        on *logger_name* or its children.  If omitted, *level* defaults to
-        INFO and *logger* defaults to the root logger.
-        This method must be used as a context manager, and will yield
-        a recording object with two attributes: `output` and `records`.
-        At the end of the context manager, the `output` attribute will
-        be a list of the matching formatted log messages and the
-        `records` attribute will be a list of the corresponding LogRecord
-        objects.
-        Example::
-            with self.assertLogs('foo', level='INFO') as cm:
-                logging.getLogger('foo').info('first message')
-                logging.getLogger('foo.bar').error('second message')
-            self.assertEqual(cm.output, ['INFO:foo:first message',
-                                         'ERROR:foo.bar:second message'])
-        """
-        return AssertLogsContext(self, logger, level)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/certbot-nginx-1.11.0/tests/test_util.py 
new/certbot-nginx-1.13.0/tests/test_util.py
--- old/certbot-nginx-1.11.0/tests/test_util.py 2021-01-05 18:37:05.000000000 
+0100
+++ new/certbot-nginx-1.13.0/tests/test_util.py 2021-03-02 22:37:04.000000000 
+0100
@@ -17,10 +17,9 @@
 from certbot.tests import util as test_util
 from certbot_nginx._internal import configurator
 from certbot_nginx._internal import nginxparser
-import test_log_util
 
 
-class NginxTest(test_log_util.AssertLogsMixin, test_util.ConfigTestCase):
+class NginxTest(test_util.ConfigTestCase):
 
     def setUp(self):
         super(NginxTest, self).setUp()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/certbot-nginx-1.11.0/tests/testdata/etc_nginx/sites-enabled/both.com 
new/certbot-nginx-1.13.0/tests/testdata/etc_nginx/sites-enabled/both.com
--- old/certbot-nginx-1.11.0/tests/testdata/etc_nginx/sites-enabled/both.com    
1970-01-01 01:00:00.000000000 +0100
+++ new/certbot-nginx-1.13.0/tests/testdata/etc_nginx/sites-enabled/both.com    
2021-03-02 22:37:04.000000000 +0100
@@ -0,0 +1,32 @@
+server {
+  server_name ssl.both.com;
+}
+
+# a duplicate vhost
+server {
+  server_name ssl.both.com;
+}
+
+# a duplicate by means of wildcard
+server {
+  server_name *.both.com;
+}
+
+# combined HTTP and HTTPS
+server {
+  server_name ssl.both.com;
+  listen 80;
+  listen 5001 ssl;
+
+  ssl_certificate      cert.pem;
+  ssl_certificate_key  cert.key;
+}
+
+# HTTPS, duplicate by means of wildcard
+server {
+  server_name *.both.com;
+  listen 5001 ssl;
+
+  ssl_certificate      cert.pem;
+  ssl_certificate_key  cert.key;
+}

Reply via email to