Skip to content

Commit

Permalink
Make password optional if client_cert is set (#678)
Browse files Browse the repository at this point in the history
Co-authored-by: Jason R. Coombs <jaraco@jaraco.com>
  • Loading branch information
future-cyborg and jaraco committed Aug 16, 2020
1 parent 62cec5b commit e872b05
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 15 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -28,3 +28,4 @@ Brian Rutledge <bhrutledge@gmail.com>
Peter Stensmyr <peter.stensmyr@gmail.com> (http://www.peterstensmyr.com)
Felipe Mulinari Rocha Campos <felipecampos@google.com>
Devesh Kumar Singh <deveshkusingh@gmail.com>
Yesha Maggi <yesha.maggic@gmail.com>
28 changes: 18 additions & 10 deletions tests/test_settings.py
Expand Up @@ -91,31 +91,39 @@ def test_identity_requires_sign():
settings.Settings(sign=False, identity="fakeid")


def test_password_not_required_if_client_cert(entered_password):
"""Don't set password when only client_cert is provided."""
test_client_cert = "/random/path"
settings_obj = settings.Settings(username="fakeuser", client_cert=test_client_cert)
assert not settings_obj.password
assert settings_obj.client_cert == test_client_cert


@pytest.mark.parametrize("client_cert", [None, ""])
def test_password_is_required_if_no_client_cert(client_cert, entered_password):
"""Set password when client_cert is not provided."""
settings_obj = settings.Settings(username="fakeuser", client_cert=client_cert)
assert settings_obj.password == "entered pw"


def test_client_cert_is_set_and_password_not_if_both_given(entered_password):
def test_client_cert_and_password_both_set_if_given():
"""Set password and client_cert when both are provided."""
client_cert = "/random/path"
settings_obj = settings.Settings(
username="fakeuser", password="anything", client_cert=client_cert
)
assert not settings_obj.password
assert settings_obj.password == "anything"
assert settings_obj.client_cert == client_cert


def test_password_required_if_no_client_cert_and_non_interactive():
"""Raise exception if no password or client_cert when non interactive."""
settings_obj = settings.Settings(username="fakeuser", non_interactive=True)
with pytest.raises(exceptions.NonInteractive):
settings_obj.password


def test_no_password_prompt_if_client_cert_and_non_interactive(entered_password):
"""Don't prompt for password when client_cert is provided and non interactive."""
client_cert = "/random/path"
settings_obj = settings.Settings(
username="fakeuser", client_cert=client_cert, non_interactive=True
)
assert not settings_obj.password


class TestArgumentParsing:
@staticmethod
def parse_args(args):
Expand Down
15 changes: 10 additions & 5 deletions twine/settings.py
Expand Up @@ -13,9 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import contextlib
import logging
import sys
from typing import Any
from typing import ContextManager
from typing import Optional
from typing import cast

Expand Down Expand Up @@ -144,11 +146,14 @@ def username(self) -> Optional[str]:

@property
def password(self) -> Optional[str]:
if self.client_cert:
return None

# Workaround for https://github.com/python/mypy/issues/5858
return cast(Optional[str], self.auth.password)
with self._allow_noninteractive():
# Workaround for https://github.com/python/mypy/issues/5858
return cast(Optional[str], self.auth.password)

def _allow_noninteractive(self) -> ContextManager[None]:
"""Bypass NonInteractive error when client cert is present."""
suppressed = (exceptions.NonInteractive,) if self.client_cert else ()
return contextlib.suppress(*suppressed)

@property
def verbose(self) -> bool:
Expand Down

0 comments on commit e872b05

Please sign in to comment.