Skip to content
This repository was archived by the owner on Jun 12, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coverage

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# .coveragerc to control coverage.py
[run]
source = .
34 changes: 34 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
sudo: false
language: python
python:
- 3.6
- 3.7
- 3.8
- pypy3
addons:
apt:
packages:
-
install:
- pip install codecov
- pip install tox
- pip install isort
- pip install tox-travis
- pip install responses
script:
- codecov --version
- tox
- isort --check src tests
after_success:
- codecov
notifications:
email: false
deploy:
provider: pypi
on:
tags: true
distributions: bdist_wheel
skip_existing: true
user: __token__
password:
secure: AH3jGGXVjV/oOlg4cOnsN7pURlZ7JMcd3Prr69Q++rxfsrmFpxCPtQLpO0LUNPisfyctoImpY64auNMHh20AHdlnvXQu8k/YFZCVcyK6N2d66wgJbO9AOT21N6IkFGyW11K3lYIHzURv9RsTEhzSkOhKmPUack5UhSJ+yAUTZXpt6iZqXBvmxMNzNiCLQdUmTMj4HxxkUVPabpef8PLqyDXvAxJxOCss+QcJVZuWFs85Niw0scTkU4SWz2lhOxeqQNg8s+CEgje2KaIoRy2kETywK53G3RFkSp5ytIJPp8RQK039laeal5yjMsWP4KlbDhHrywyNN7yS69FwPuLC41ppde5G054WcuJTm60Y2uckGu6L3oTBMHsAtSfZuEym/qfDngxYADA+xrATJQF5XSrCz13IiBnoz8Y9zI7t9s66PZSBHg99L85jM45M2kJYCDKxNPffJ/JzCnAMTP0yiBMEQ/UfguMDfJMw+6oSPzGcZHuQVzjLO5mUni71X528Psd/iEYCyN+Vi1QbvDZjbNo/oOLtvegOcnu/H1tGWkH4uEXsg2giqkld2hrZi6K3KfcpPtltuP66Z6ohMqcLegqGUNr8mPMP2I58p7if/6xLEu1e7MNZuoV459bnWepoNMMug2NLq/WIPCiGLNCyV4tdbzqcZQLNwjc5ruFLoz8=
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ SPHINXBUILD = sphinx-build
SPHINXABUILD = sphinx-autobuild
BUILDDIR = doc/_build
DOCDIR = doc/
OIDCDIR = src/oidcmsg
OIDCDIR = src/oidcservice
TESTDIR = tests

help:
Expand Down Expand Up @@ -40,10 +40,10 @@ test:
.PHONY: test

isort:
@pipenv run isort --recursive $(OIDCDIR) $(TESTDIR)
@pipenv run isort $(OIDCDIR) $(TESTDIR)

check-isort:
@pipenv run isort --recursive --diff --check-only $(OIDCDIR) $(TESTDIR)
@pipenv run isort --diff --check-only $(OIDCDIR) $(TESTDIR)
.PHONY: isort check-isort

check-pylama:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ def run_tests(self):
classifiers=[
"Development Status :: 4 - Beta",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Topic :: Software Development :: Libraries :: Python Modules"],
install_requires=[
"pyyaml>=5.1.0",
Expand Down
11 changes: 5 additions & 6 deletions src/oidcservice/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@

# Since SystemRandom is not available on all systems
try:
import random.SystemRandom as rnd
import SystemRandom as rnd
except ImportError:
import random as rnd


__author__ = 'Roland Hedberg'
__version__ = '1.1.0'

__version__ = '1.1.1'

OIDCONF_PATTERN = "{}/.well-known/openid-configuration"
CC_METHOD = {
Expand All @@ -31,6 +29,8 @@
JWT_BEARER = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
SAML2_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:saml2-bearer"

BASECHR = string.ascii_letters + string.digits


def rndstr(size=16):
"""
Expand All @@ -39,8 +39,7 @@ def rndstr(size=16):
:param size: The length of the string
:return: string
"""
_basech = string.ascii_letters + string.digits
return "".join([rnd.choice(_basech) for _ in range(size)])
return "".join([rnd.choice(BASECHR) for _ in range(size)])


BASECH = string.ascii_letters + string.digits + '-._~'
Expand Down
35 changes: 23 additions & 12 deletions src/oidcservice/client_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@
from urllib.parse import quote_plus

from cryptojwt.exception import MissingKey
from cryptojwt.jws.jws import SIGNER_ALGS
from cryptojwt.jws.utils import alg2keytype
from oidcmsg.message import VREQUIRED
from oidcmsg.oauth2 import AccessTokenRequest
from oidcmsg.oauth2 import SINGLE_OPTIONAL_STRING
from oidcmsg.oauth2 import SINGLE_OPTIONAL_STRING, AccessTokenRequest
from oidcmsg.oidc import AuthnToken
from oidcmsg.time_util import utc_time_sans_frac

from oidcservice import DEF_SIGN_ALG
from oidcservice import JWT_BEARER
from oidcservice import rndstr
from oidcservice import sanitize
from oidcservice import DEF_SIGN_ALG, JWT_BEARER, rndstr, sanitize

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -128,7 +125,7 @@ def _with_or_without_client_id(request, service):
:param service: A :py:class:`oidcservice.service.Service` instance
"""
if isinstance(request, AccessTokenRequest) and request[
'grant_type'] == 'authorization_code':
'grant_type'] == 'authorization_code':
if 'client_id' not in request:
try:
request['client_id'] = service.service_context.get('client_id')
Expand Down Expand Up @@ -315,6 +312,7 @@ def construct(self, request=None, service=None, http_args=None,

class BearerBody(ClientAuthnMethod):
"""The bearer body authentication method."""

def modify_request(self, request, service, **kwargs):
"""
Modify the request if necessary.
Expand Down Expand Up @@ -450,11 +448,24 @@ def _get_audience_and_algorithm(self, context, **kwargs):
# audience for the signed JWT depends on which endpoint
# we're talking to.
if 'authn_endpoint' in kwargs and kwargs['authn_endpoint'] in ['token_endpoint']:
try:
algorithm = context.behaviour[
'token_endpoint_auth_signing_alg']
except (KeyError, AttributeError):
pass
reg_resp = context.get("registration_response")
if reg_resp:
algorithm = reg_resp.get("token_endpoint_auth_signing_alg")
else:
algorithm = context.client_preferences.get("token_endpoint_auth_signing_alg")
if algorithm is None:
_pi = context.get("provider_info")
try:
algs = _pi["token_endpoint_auth_signing_alg_values_supported"]
except KeyError:
algorithm = "RS256" # default
else:
for alg in algs: # pick the first one I support and have keys for
if alg in SIGNER_ALGS and self.get_signing_key_from_keyjar(alg,
context):
algorithm = alg
break

audience = context.get('provider_info')['token_endpoint']
else:
audience = context.get('provider_info')['issuer']
Expand Down
6 changes: 2 additions & 4 deletions src/oidcservice/oauth2/authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
from oidcmsg.oauth2 import ResponseMessage
from oidcmsg.time_util import time_sans_frac

from oidcservice.oauth2.utils import get_state_parameter
from oidcservice.oauth2.utils import pick_redirect_uris
from oidcservice.oauth2.utils import set_state_parameter
from oidcservice.oauth2.utils import (get_state_parameter, pick_redirect_uris,
set_state_parameter)
from oidcservice.service import Service


LOGGER = logging.getLogger(__name__)


Expand Down
1 change: 0 additions & 1 deletion src/oidcservice/oauth2/provider_info_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging

from cryptojwt.key_jar import KeyJar

from oidcmsg import oauth2
from oidcmsg.oauth2 import ResponseMessage

Expand Down
1 change: 0 additions & 1 deletion src/oidcservice/oauth2/refresh_access_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from oidcservice.oauth2.utils import get_state_parameter
from oidcservice.service import Service


LOGGER = logging.getLogger(__name__)


Expand Down
2 changes: 1 addition & 1 deletion src/oidcservice/oidc/access_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from oidcmsg.oidc import verified_claim_name
from oidcmsg.time_util import time_sans_frac

from oidcservice.oauth2 import access_token
from oidcservice.exception import ParameterError
from oidcservice.oauth2 import access_token
from oidcservice.oidc import IDT2REG

__author__ = 'Roland Hedberg'
Expand Down
3 changes: 1 addition & 2 deletions src/oidcservice/oidc/add_on/pkce.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
from cryptojwt.utils import b64e
from oidcmsg.message import Message

from oidcservice import CC_METHOD
from oidcservice import unreserved
from oidcservice import CC_METHOD, unreserved
from oidcservice.exception import Unsupported
from oidcservice.oauth2.utils import get_state_parameter

Expand Down
3 changes: 2 additions & 1 deletion src/oidcservice/oidc/add_on/pushed_authorization.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import logging

import requests
from cryptojwt import JWT
from oidcmsg.message import Message
from oidcmsg.oauth2 import JWTSecuredAuthorizationRequest

import requests

logger = logging.getLogger(__name__)


Expand Down
27 changes: 15 additions & 12 deletions src/oidcservice/oidc/authorization.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import logging

from oidcmsg import oidc
from oidcmsg.oidc import make_openid_request
from oidcmsg.oidc import verified_claim_name
from oidcmsg.time_util import time_sans_frac
from oidcmsg.time_util import utc_time_sans_frac
from oidcmsg.oidc import make_openid_request, verified_claim_name
from oidcmsg.time_util import time_sans_frac, utc_time_sans_frac

from oidcservice import rndstr
from oidcservice.exception import ParameterError
from oidcservice.oauth2 import authorization
from oidcservice.oauth2.utils import pick_redirect_uris
from oidcservice.oidc import IDT2REG
from oidcservice.oidc.utils import construct_request_uri
from oidcservice.oidc.utils import request_object_encryption
from oidcservice.oidc.utils import (construct_request_uri,
request_object_encryption)

__author__ = 'Roland Hedberg'

Expand Down Expand Up @@ -151,11 +149,12 @@ def construct_request_parameter(self, req, request_method, audience=None, expire
kwargs["keys"] = self.service_context.keyjar

_srv_cntx = self.service_context
kwargs['issuer'] = _srv_cntx.get('client_id')
# set the audience
if audience:
kwargs["recv"] = _srv_cntx.get('provider_info')[audience]
else:

# This is the issuer of the JWT, that is me !
if kwargs.get('issuer') is None:
kwargs['issuer'] = _srv_cntx.get('client_id')

if kwargs.get('recv') is None:
try:
kwargs['recv'] = _srv_cntx.get('provider_info')['issuer']
except KeyError:
Expand Down Expand Up @@ -214,11 +213,15 @@ def gather_verify_arguments(self):
"""
_ctx = self.service_context
kwargs = {
'client_id': _ctx.get('client_id'), 'iss': _ctx.get('issuer'),
'iss': _ctx.get('issuer'),
'keyjar': _ctx.keyjar, 'verify': True,
'skew': _ctx.clock_skew
}

_client_id = _ctx.get('client_id')
if _client_id:
kwargs['client_id'] = _client_id

if 'registration_response' in _ctx:
_reg_res = _ctx.get('registration_response')
for attr, param in IDT2REG.items():
Expand Down
3 changes: 1 addition & 2 deletions src/oidcservice/oidc/check_id.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging

from oidcmsg.oauth2 import Message
from oidcmsg.oauth2 import ResponseMessage
from oidcmsg.oauth2 import Message, ResponseMessage
from oidcmsg.oidc import session

from oidcservice.service import Service
Expand Down
3 changes: 1 addition & 2 deletions src/oidcservice/oidc/check_session.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging

from oidcmsg.oauth2 import Message
from oidcmsg.oauth2 import ResponseMessage
from oidcmsg.oauth2 import Message, ResponseMessage
from oidcmsg.oidc import session

from oidcservice.service import Service
Expand Down
3 changes: 1 addition & 2 deletions src/oidcservice/oidc/end_session.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging

from oidcmsg.oauth2 import Message
from oidcmsg.oauth2 import ResponseMessage
from oidcmsg.oauth2 import Message, ResponseMessage
from oidcmsg.oidc import session

from oidcservice import rndstr
Expand Down
2 changes: 1 addition & 1 deletion src/oidcservice/oidc/provider_info_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from oidcmsg import oidc
from oidcmsg.oauth2 import ResponseMessage

from oidcservice.oauth2 import provider_info_discovery
from oidcservice.exception import ConfigurationError
from oidcservice.oauth2 import provider_info_discovery

__author__ = 'Roland Hedberg'

Expand Down
1 change: 0 additions & 1 deletion src/oidcservice/oidc/read_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from oidcservice.service import Service


LOGGER = logging.getLogger(__name__)


Expand Down
1 change: 0 additions & 1 deletion src/oidcservice/oidc/userinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from oidcservice.oauth2.utils import get_state_parameter
from oidcservice.service import Service


logger = logging.getLogger(__name__)

UI2REG = {
Expand Down
9 changes: 3 additions & 6 deletions src/oidcservice/oidc/webfinger.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import logging
from urllib.parse import urlsplit
from urllib.parse import urlunsplit
from urllib.parse import urlsplit, urlunsplit

from oidcmsg import oidc
from oidcmsg.exception import MissingRequiredAttribute
from oidcmsg.oauth2 import Message
from oidcmsg.oauth2 import ResponseMessage
from oidcmsg.oauth2 import Message, ResponseMessage
from oidcmsg.oidc import JRD

from oidcservice.oidc import OIC_ISSUER
from oidcservice.oidc import WF_URL
from oidcservice.oidc import OIC_ISSUER, WF_URL
from oidcservice.service import Service

__author__ = 'Roland Hedberg'
Expand Down
Loading