diff --git a/.github/workflows/sievelib.yml b/.github/workflows/sievelib.yml index 17fc024..ed4328e 100644 --- a/.github/workflows/sievelib.yml +++ b/.github/workflows/sievelib.yml @@ -53,3 +53,31 @@ jobs: uses: codecov/codecov-action@v3 with: files: ./coverage.xml + + release: + if: github.event_name != 'pull_request' + needs: coverage + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Publish to Test PyPI + if: endsWith(github.event.ref, '/master') + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.test_pypi_password }} + repository_url: https://test.pypi.org/legacy/ + skip_existing: true + - name: Publish distribution to PyPI + if: startsWith(github.event.ref, 'refs/tags') || github.event_name == 'release' + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.pypi_password }} + skip_existing: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 88b1a2b..0000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: python - -cache: pip - -python: - - '3.5' - - '3.8' - -before_install: - - pip install codecov nose - -install: - - python setup.py -q install - -script: nosetests --with-coverage - -after_success: - - codecov - -deploy: - provider: pypi - user: tonio - password: - secure: Mb1Xiif6MnUmEC6c0lUcW3BEqxvmBeh8V46BkMznX7FgqG1jUcBTtvLLub7Hzh31gvL7xltcUCS9AMhu3CnJrxSLxkyzthpWMp/kib00WM5qmrw9o8ZWeJm+wFMfFJchZ7Nx61PL/17D/Qjaf6lNLYQudXW8Z+hZ1CcQic3B3Kw= - skip_cleanup: true - distributions: sdist bdist_wheel - on: - tags: true - python: '3.8' diff --git a/README.rst b/README.rst index e278c60..7bd2114 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ sievelib ======== -|travis| |codecov| |latest-version| +|workflow| |codecov| |latest-version| Client-side Sieve and Managesieve library written in Python. @@ -130,7 +130,7 @@ supported, with a simulated behaviour for server that do not support it. For the ``AUTHENTICATE`` command, supported mechanisms are ``DIGEST-MD5``, -``PLAIN`` and ``LOGIN``. +``PLAIN``, ``LOGIN`` and ``OAUTHBEARER``. Basic usage ^^^^^^^^^^^ @@ -154,7 +154,6 @@ Additional documentation is available with source code. .. |latest-version| image:: https://badge.fury.io/py/sievelib.svg :target: https://badge.fury.io/py/sievelib -.. |travis| image:: https://travis-ci.org/tonioo/sievelib.png?branch=master - :target: https://travis-ci.org/tonioo/sievelib +.. |workflow| image:: https://github.com/tonioo/sievelib/workflows/Sievelib/badge.svg .. |codecov| image:: http://codecov.io/github/tonioo/sievelib/coverage.svg?branch=master :target: http://codecov.io/github/tonioo/sievelib?branch=master diff --git a/sievelib/managesieve.py b/sievelib/managesieve.py index 6cb598f..91d0571 100644 --- a/sievelib/managesieve.py +++ b/sievelib/managesieve.py @@ -557,7 +557,7 @@ def capability(self): return None @authentication_required - def havespace(self, scriptname, scriptsize): + def havespace(self, scriptname: str, scriptsize: int) -> bool: """Ask for available space. See MANAGESIEVE specifications, section 2.5 diff --git a/sievelib/tests/test_managesieve.py b/sievelib/tests/test_managesieve.py index a8132e3..2d07e6a 100644 --- a/sievelib/tests/test_managesieve.py +++ b/sievelib/tests/test_managesieve.py @@ -8,14 +8,14 @@ CAPABILITIES = ( b'"IMPLEMENTATION" "Example1 ManageSieved v001"\r\n' b'"VERSION" "1.0"\r\n' - b'"SASL" "PLAIN SCRAM-SHA-1 GSSAPI"\r\n' + b'"SASL" "PLAIN SCRAM-SHA-1 GSSAPI OAUTHBEARER"\r\n' b'"SIEVE" "fileinto vacation"\r\n' b'"STARTTLS"\r\n' ) CAPABILITIES_WITHOUT_VERSION = ( b'"IMPLEMENTATION" "Example1 ManageSieved v001"\r\n' - b'"SASL" "PLAIN SCRAM-SHA-1 GSSAPI"\r\n' + b'"SASL" "PLAIN SCRAM-SHA-1 GSSAPI OAUTHBEARER"\r\n' b'"SIEVE" "fileinto vacation"\r\n' b'"STARTTLS"\r\n' ) @@ -64,6 +64,13 @@ def test_connection(self, mock_socket): mock_socket.return_value.recv.side_effect = (b"OK test\r\n", ) self.client.logout() + def test_auth_oauthbearer(self, mock_socket): + """Test OAUTHBEARER mechanism.""" + mock_socket.return_value.recv.side_effect = (AUTHENTICATION, ) + self.assertTrue( + self.client.connect(b"user", b"token", authmech="OAUTHBEARER") + ) + def test_capabilities(self, mock_socket): """Test capabilities command.""" self.authenticate(mock_socket)