Skip to content

Commit

Permalink
use gh actions (#8)
Browse files Browse the repository at this point in the history
* use gh actions

* use github actions for ci
  • Loading branch information
jugmac00 committed Jan 23, 2021
1 parent a13fe6a commit fa66994
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 139 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/main.yml
@@ -0,0 +1,50 @@
name: CI

# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events
push:
pull_request:
schedule:
- cron: '0 12 * * 0' # run once a week on Sunday

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
tests:
name: "Python ${{ matrix.python-version }}"
runs-on: "ubuntu-latest"

strategy:
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "pypy3"]

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: "actions/checkout@v2"
- uses: "actions/setup-python@v2"
with:
python-version: "${{ matrix.python-version }}"
- name: "Install dependencies"
run: |
set -xe
python -VV
python -m site
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade virtualenv tox tox-gh-actions
- name: "Run tox targets for ${{ matrix.python-version }}"
run: "python -m tox"

- name: "Report to coveralls"
# coverage is only created in the py39 environment
# --service=github is a workaround for bug
# https://github.com/coveralls-clients/coveralls-python/issues/251
if: "matrix.python-version == '3.9'"
run: |
pip install coveralls
coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15 changes: 15 additions & 0 deletions .pre-commit-config.yaml
@@ -0,0 +1,15 @@
repos:
- repo: https://github.com/psf/black
rev: 20.8b1
hooks:
- id: black
args: [--line-length=80]
- repo: https://gitlab.com/pycqa/flake8
rev: "3.8.4"
hooks:
- id: flake8
- repo: https://github.com/asottile/pyupgrade
rev: v2.7.4
hooks:
- id: pyupgrade
args: [--py36-plus]
31 changes: 0 additions & 31 deletions .travis.yml

This file was deleted.

6 changes: 4 additions & 2 deletions HISTORY.rst
Expand Up @@ -4,13 +4,15 @@ Changelog
0.0.3 (unreleased)
~~~~~~~~~~~~~~~~~~

- Add support for Python 3.6 - 3.8.
- Add support for Python 3.6 - 3.9.

- Remove support for Python versions < 3.6.

- Add Python 3.5 and make it the default test environment.
- Add Python 3.5 and make it the default test environment. (superseded)
[henri-hulski]

- Use GitHub Actions for CI.

0.0.2 (2016-04-18)
~~~~~~~~~~~~~~~~~~~

Expand Down
36 changes: 15 additions & 21 deletions README.rst
@@ -1,3 +1,17 @@
.. image:: https://github.com/morepath/more.itsdangerous/workflows/CI/badge.svg?branch=master
:target: https://github.com/morepath/more.itsdangerous/actions?workflow=CI
:alt: CI Status

.. image:: https://coveralls.io/repos/github/morepath/more.itsdangerous/badge.svg?branch=master
:target: https://coveralls.io/github/morepath/morepath_sqlamore.itsdangerouslchemy?branch=master

.. image:: https://img.shields.io/pypi/v/more.itsdangerous.svg
:target: https://pypi.org/project/more.itsdangerous/

.. image:: https://img.shields.io/pypi/pyversions/more.itsdangerous.svg
:target: https://pypi.org/project/more.itsdangerous/


More Itsdangerous
=================

Expand Down Expand Up @@ -65,7 +79,7 @@ Install tox and run it::

Limit the tests to a specific python version::

tox -e py38
tox -e py39

Conventions
-----------
Expand All @@ -76,26 +90,6 @@ More Itsdangerous follows PEP8 as close as possible. To test for it run::

More Itsdangerous uses `Semantic Versioning <http://semver.org/>`_

Build Status
------------

.. image:: https://travis-ci.com/morepath/more.itsdangerous.png
:target: https://travis-ci.com/morepath/more.itsdangerous
:alt: Build Status

Coverage
--------

.. image:: https://coveralls.io/repos/morepath/more.itsdangerous/badge.png?branch=master
:target: https://coveralls.io/r/morepath/more.itsdangerous?branch=master
:alt: Project Coverage

Latests PyPI Release
--------------------
.. image:: https://img.shields.io/pypi/v/more.itsdangerous.svg
:target: https://crate.io/packages/more.itsdangerous
:alt: Latest PyPI Release

License
-------
more.itsdangerous is released under the revised BSD license
2 changes: 1 addition & 1 deletion more/__init__.py
@@ -1 +1 @@
__import__('pkg_resources').declare_namespace(__name__)
__import__("pkg_resources").declare_namespace(__name__)
2 changes: 1 addition & 1 deletion more/itsdangerous/__init__.py
@@ -1,3 +1,3 @@
from more.itsdangerous.identity_policy import IdentityPolicy

__all__ = ['IdentityPolicy']
__all__ = ["IdentityPolicy"]
26 changes: 13 additions & 13 deletions more/itsdangerous/identity_policy.py
Expand Up @@ -5,7 +5,7 @@


class IdentityPolicy:
""" A Morepath IdentityPolicy that stores attributes of the identity
"""A Morepath IdentityPolicy that stores attributes of the identity
as cookies with a signature.
You probably want to override this class in your application, to fit it
Expand All @@ -16,7 +16,7 @@ class IdentityPolicy:
"""

def __init__(self, max_age=3600, secure=True, httponly=True):
""" Configures the identity policy with the following values:
"""Configures the identity policy with the following values:
:max_age:
The max age of both the signature and the cookie in seconds.
Expand All @@ -37,7 +37,7 @@ def __init__(self, max_age=3600, secure=True, httponly=True):

@morepath.reify
def secret(self):
""" The secret used to for the signatures.
"""The secret used to for the signatures.
As long as the secret is not stored anywhere, the signed values all
become invalid every time the secret is changed. Currently, that
Expand All @@ -54,7 +54,7 @@ def identity_class(self):

@property
def required_keys(self):
""" The attributes of the identity which are signed and stored as
"""The attributes of the identity which are signed and stored as
cookies.
This is useful to add additional values that are present on your
Expand All @@ -68,11 +68,11 @@ def required_keys(self):
"""

return ('userid', )
return ("userid",)

@property
def cookie_settings(self):
""" Returns the default cookie settings.
"""Returns the default cookie settings.
See also:
Expand All @@ -81,13 +81,13 @@ def cookie_settings(self):
"""
return {
'max_age': self.max_age,
'secure': self.secure,
'httponly': self.httponly
"max_age": self.max_age,
"secure": self.secure,
"httponly": self.httponly,
}

def identify(self, request):
""" Returns the identity of the given request, if *all* cookies
"""Returns the identity of the given request, if *all* cookies
match, or None.
"""
Expand Down Expand Up @@ -115,7 +115,7 @@ def forget(self, response, request):
response.delete_cookie(key)

def sign(self, unsigned_value, salt):
""" Signs a value with a salt using itsdangerous.TimestampSigner and
"""Signs a value with a salt using itsdangerous.TimestampSigner and
returns the resulting signed value.
The salt might not be what you think it is:
Expand All @@ -124,7 +124,7 @@ def sign(self, unsigned_value, salt):
return TimestampSigner(self.secret, salt=salt).sign(unsigned_value)

def unsign(self, signed_value, salt):
""" Takes the signed value and returns it unsigned, if possible.
"""Takes the signed value and returns it unsigned, if possible.
If the signature is bad or if it expired, None is returned.
"""
Expand All @@ -138,7 +138,7 @@ def unsign(self, signed_value, salt):
unsigned = signer.unsign(signed_value, max_age=self.max_age)

# see http://pythonhosted.org/itsdangerous/#python-3-notes
return unsigned.decode('utf-8')
return unsigned.decode("utf-8")

except (SignatureExpired, BadSignature):
return None
55 changes: 27 additions & 28 deletions more/itsdangerous/tests/test_identity_policy.py
Expand Up @@ -24,59 +24,58 @@ def delete_cookie(self, key):
def test_signatures():
ip = IdentityPolicy()

assert ip.unsign(ip.sign('admin', 'username'), 'username') == 'admin'
assert ip.unsign(ip.sign('admin ', 'username'), 'username') == 'admin '
assert ip.unsign(ip.sign('admin', 'username'), 'role') is None
assert ip.unsign(ip.sign("admin", "username"), "username") == "admin"
assert ip.unsign(ip.sign("admin ", "username"), "username") == "admin "
assert ip.unsign(ip.sign("admin", "username"), "role") is None


def test_expired_signature():

ip = IdentityPolicy(max_age=0.1)
signed = ip.sign('admin', 'username')
signed = ip.sign("admin", "username")

assert ip.unsign(signed, 'username') == 'admin'
assert ip.unsign(signed, "username") == "admin"
time.sleep(1.0)
assert ip.unsign(signed, 'username') is None
assert ip.unsign(signed, "username") is None


def test_policy():
ip = IdentityPolicy()
identity = morepath.Identity(userid='aaron', role='admin')
identity = morepath.Identity(userid="aaron", role="admin")
request = TestRequest()
response = TestResponse()

ip.remember(response, request, identity)

assert 'userid' in response.cookies
assert 'role' not in response.cookies
assert "userid" in response.cookies
assert "role" not in response.cookies


def test_custom_policy():

class CustomIdentityPolicy(IdentityPolicy):
required_keys = ('userid', 'role')
required_keys = ("userid", "role")

ip = CustomIdentityPolicy()
identity = morepath.Identity(userid='aaron', role='admin')
identity = morepath.Identity(userid="aaron", role="admin")
request = TestRequest()
response = TestResponse()

ip.remember(response, request, identity)

assert response.cookies['userid'].startswith(b'aaron.')
assert response.cookies['role'].startswith(b'admin.')
assert response.cookie_args['userid'] == response.cookie_args['role'] == {
'max_age': 3600,
'secure': True,
'httponly': True
}
assert response.cookies["userid"].startswith(b"aaron.")
assert response.cookies["role"].startswith(b"admin.")
assert (
response.cookie_args["userid"]
== response.cookie_args["role"]
== {"max_age": 3600, "secure": True, "httponly": True}
)

request.cookies = response.cookies

assert ip.identify(request).userid == 'aaron'
assert ip.identify(request).role == 'admin'
assert ip.identify(request).userid == "aaron"
assert ip.identify(request).role == "admin"

del request.cookies['role']
del request.cookies["role"]

assert ip.identify(request) is None

Expand All @@ -87,11 +86,11 @@ class CustomIdentityPolicy(IdentityPolicy):

def test_cookie_settings():
ip = IdentityPolicy()
assert ip.cookie_settings['max_age'] == 3600
assert ip.cookie_settings['secure']
assert ip.cookie_settings['httponly']
assert ip.cookie_settings["max_age"] == 3600
assert ip.cookie_settings["secure"]
assert ip.cookie_settings["httponly"]

ip = IdentityPolicy(max_age=1, secure=False, httponly=False)
assert ip.cookie_settings['max_age'] == 1
assert not ip.cookie_settings['secure']
assert not ip.cookie_settings['httponly']
assert ip.cookie_settings["max_age"] == 1
assert not ip.cookie_settings["secure"]
assert not ip.cookie_settings["httponly"]

0 comments on commit fa66994

Please sign in to comment.