diff --git a/AUTHORS.md b/AUTHORS.md index d08b0b79f..78ed21215 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -166,6 +166,7 @@ Authors * [Luca Ebach](https://github.com/lucebac) * [Luca Olivetti](https://github.com/olivluca) * [Luke Rogers](https://github.com/lukeroge) +* [Lukhnos Liu](https://github.com/lukhnos) * [Maarten](https://github.com/mrtndwrd) * [Mads Jensen](https://github.com/atombrella) * [Maikel Martens](https://github.com/krukas) diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index b718aa6c0..45e4334bb 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -15,7 +15,10 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). ### Fixed -* +* Fixed a bug in Certbot where a CSR's SANs did not always follow the order of + the domain names that the user requested interactively. In some cases, the + resulting cert's common name might seem picked up randomly from the SANs + when it should be the first item the user had in mind. More details about these changes can be found on our GitHub repo. diff --git a/certbot/certbot/_internal/display/obj.py b/certbot/certbot/_internal/display/obj.py index 54c248b0c..39882f3fb 100644 --- a/certbot/certbot/_internal/display/obj.py +++ b/certbot/certbot/_internal/display/obj.py @@ -328,8 +328,9 @@ class FileDisplay: except ValueError: return [] - # Remove duplicates - indices_int = list(set(indices_int)) + # Remove duplicates. dict is used instead of set, since dict perserves + # insertion order as of Python 3.7 + indices_int = list(dict.fromkeys(indices_int).keys()) # Check all input is within range for index in indices_int: diff --git a/certbot/certbot/_internal/tests/display/obj_test.py b/certbot/certbot/_internal/tests/display/obj_test.py index be9bd3242..fa157e645 100644 --- a/certbot/certbot/_internal/tests/display/obj_test.py +++ b/certbot/certbot/_internal/tests/display/obj_test.py @@ -194,6 +194,25 @@ class FileOutputDisplayTest(unittest.TestCase): self.displayer._scrub_checklist_input(list_, TAGS)) assert set_tags == exp[i] + def test_scrub_checklist_maintain_indices_order(self): + # pylint: disable=protected-access + source_tags = ["T1", "T2", "T3", "T4", "T5", "T6", "T7", "T8", "T9"] + indices = [ + ["4", "9"], + ["9", "4"], + ["4", "9", "4"], + ["9", "4", "9"], + ] + exp = [ + ["T4", "T9"], + ["T9", "T4"], + ["T4", "T9"], + ["T9", "T4"], + ] + for i, list_ in enumerate(indices): + tags = self.displayer._scrub_checklist_input(list_, source_tags) + assert tags == exp[i] + @mock.patch("certbot._internal.display.util.input_with_timeout") def test_directory_select(self, mock_input): args = ["msg", "/var/www/html", "--flag", True]