Mock Version: 5.0 Mock Version: 5.0 Mock Version: 5.0 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -bs --noclean --target noarch --nodeps /builddir/build/SPECS/python-social-auth-core.spec'], chrootPath='/var/lib/mock/f40-build-2318967-58298/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=864000uid=996gid=135user='mockbuild'nspawn_args=[]unshare_net=TrueprintOutput=False) Executing command: ['bash', '--login', '-c', '/usr/bin/rpmbuild -bs --noclean --target noarch --nodeps /builddir/build/SPECS/python-social-auth-core.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'} and shell False Building target platforms: noarch Building for target noarch setting SOURCE_DATE_EPOCH=1706227200 Wrote: /builddir/build/SRPMS/python-social-auth-core-4.3.0-8.fc40.src.rpm Child return code was: 0 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -bb --noclean --target noarch --nodeps /builddir/build/SPECS/python-social-auth-core.spec'], chrootPath='/var/lib/mock/f40-build-2318967-58298/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=864000uid=996gid=135user='mockbuild'nspawn_args=[]unshare_net=TrueprintOutput=False) Executing command: ['bash', '--login', '-c', '/usr/bin/rpmbuild -bb --noclean --target noarch --nodeps /builddir/build/SPECS/python-social-auth-core.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'} and shell False Building target platforms: noarch Building for target noarch setting SOURCE_DATE_EPOCH=1706227200 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.XiPySS + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf social-auth-core-4.3.0 + /usr/lib/rpm/rpmuncompress -x /builddir/build/SOURCES/social-auth-core-4.3.0.tar.gz + STATUS=0 + '[' 0 -ne 0 ']' + cd social-auth-core-4.3.0 + rm -rf /builddir/build/BUILD/social-auth-core-4.3.0-SPECPARTS + /usr/bin/mkdir -p /builddir/build/BUILD/social-auth-core-4.3.0-SPECPARTS + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + rm -rf social_auth_core.egg-info + RPM_EC=0 ++ jobs -p + exit 0 Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.EYiJzc + umask 022 + cd /builddir/build/BUILD + CFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Werror=implicit-function-declaration -Werror=implicit-int -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer ' + export CFLAGS + CXXFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer ' + export CXXFLAGS + FFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer -I/usr/lib/gfortran/modules ' + export FFLAGS + FCFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer -I/usr/lib/gfortran/modules ' + export FCFLAGS + VALAFLAGS=-g + export VALAFLAGS + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd social-auth-core-4.3.0 + CFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Werror=implicit-function-declaration -Werror=implicit-int -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + /usr/bin/python3 setup.py build '--executable=/usr/bin/python3 -sP' running build running build_py creating build creating build/lib creating build/lib/social_core copying social_core/strategy.py -> build/lib/social_core copying social_core/storage.py -> build/lib/social_core copying social_core/store.py -> build/lib/social_core copying social_core/exceptions.py -> build/lib/social_core copying social_core/__init__.py -> build/lib/social_core copying social_core/utils.py -> build/lib/social_core copying social_core/actions.py -> build/lib/social_core creating build/lib/social_core/backends copying social_core/backends/digitalocean.py -> build/lib/social_core/backends copying social_core/backends/soundcloud.py -> build/lib/social_core/backends copying social_core/backends/douban.py -> build/lib/social_core/backends copying social_core/backends/monzo.py -> build/lib/social_core/backends copying social_core/backends/google_openidconnect.py -> build/lib/social_core/backends copying social_core/backends/pushbullet.py -> build/lib/social_core/backends copying social_core/backends/vk.py -> build/lib/social_core/backends copying social_core/backends/jawbone.py -> build/lib/social_core/backends copying social_core/backends/yahoo.py -> build/lib/social_core/backends copying social_core/backends/clef.py -> build/lib/social_core/backends copying social_core/backends/deezer.py -> build/lib/social_core/backends copying social_core/backends/khanacademy.py -> build/lib/social_core/backends copying social_core/backends/mailru.py -> build/lib/social_core/backends copying social_core/backends/github_enterprise.py -> build/lib/social_core/backends copying social_core/backends/spotify.py -> build/lib/social_core/backends copying social_core/backends/mailchimp.py -> build/lib/social_core/backends copying social_core/backends/launchpad.py -> build/lib/social_core/backends copying social_core/backends/arcgis.py -> build/lib/social_core/backends copying social_core/backends/stocktwits.py -> build/lib/social_core/backends copying social_core/backends/google.py -> build/lib/social_core/backends copying social_core/backends/runkeeper.py -> build/lib/social_core/backends copying social_core/backends/udata.py -> build/lib/social_core/backends copying social_core/backends/twitter.py -> build/lib/social_core/backends copying social_core/backends/xing.py -> build/lib/social_core/backends copying social_core/backends/globus.py -> build/lib/social_core/backends copying social_core/backends/live.py -> build/lib/social_core/backends copying social_core/backends/line.py -> build/lib/social_core/backends copying social_core/backends/tripit.py -> build/lib/social_core/backends copying social_core/backends/weixin.py -> build/lib/social_core/backends copying social_core/backends/patreon.py -> build/lib/social_core/backends copying social_core/backends/openstreetmap.py -> build/lib/social_core/backends copying social_core/backends/flickr.py -> build/lib/social_core/backends copying social_core/backends/zoom.py -> build/lib/social_core/backends copying social_core/backends/asana.py -> build/lib/social_core/backends copying social_core/backends/stackoverflow.py -> build/lib/social_core/backends copying social_core/backends/echosign.py -> build/lib/social_core/backends copying social_core/backends/untappd.py -> build/lib/social_core/backends copying social_core/backends/drip.py -> build/lib/social_core/backends copying social_core/backends/skyrock.py -> build/lib/social_core/backends copying social_core/backends/trello.py -> build/lib/social_core/backends copying social_core/backends/vault.py -> build/lib/social_core/backends copying social_core/backends/bungie.py -> build/lib/social_core/backends copying social_core/backends/mediawiki.py -> build/lib/social_core/backends copying social_core/backends/facebook.py -> build/lib/social_core/backends copying social_core/backends/grafana.py -> build/lib/social_core/backends copying social_core/backends/okta_openidconnect.py -> build/lib/social_core/backends copying social_core/backends/kakao.py -> build/lib/social_core/backends copying social_core/backends/meetup.py -> build/lib/social_core/backends copying social_core/backends/discord.py -> build/lib/social_core/backends copying social_core/backends/openshift.py -> build/lib/social_core/backends copying social_core/backends/rdio.py -> build/lib/social_core/backends copying social_core/backends/dailymotion.py -> build/lib/social_core/backends copying social_core/backends/saml.py -> build/lib/social_core/backends copying social_core/backends/nationbuilder.py -> build/lib/social_core/backends copying social_core/backends/reddit.py -> build/lib/social_core/backends copying social_core/backends/scistarter.py -> build/lib/social_core/backends copying social_core/backends/loginradius.py -> build/lib/social_core/backends copying social_core/backends/edmodo.py -> build/lib/social_core/backends copying social_core/backends/livejournal.py -> build/lib/social_core/backends copying social_core/backends/mapmyfitness.py -> build/lib/social_core/backends copying social_core/backends/openstackdev.py -> build/lib/social_core/backends copying social_core/backends/twilio.py -> build/lib/social_core/backends copying social_core/backends/mixcloud.py -> build/lib/social_core/backends copying social_core/backends/gitea.py -> build/lib/social_core/backends copying social_core/backends/evernote.py -> build/lib/social_core/backends copying social_core/backends/legacy.py -> build/lib/social_core/backends copying social_core/backends/uber.py -> build/lib/social_core/backends copying social_core/backends/open_id_connect.py -> build/lib/social_core/backends copying social_core/backends/linkedin.py -> build/lib/social_core/backends copying social_core/backends/moves.py -> build/lib/social_core/backends copying social_core/backends/podio.py -> build/lib/social_core/backends copying social_core/backends/flat.py -> build/lib/social_core/backends copying social_core/backends/coursera.py -> build/lib/social_core/backends copying social_core/backends/gitlab.py -> build/lib/social_core/backends copying social_core/backends/coding.py -> build/lib/social_core/backends copying social_core/backends/yammer.py -> build/lib/social_core/backends copying social_core/backends/classlink.py -> build/lib/social_core/backends copying social_core/backends/hubspot.py -> build/lib/social_core/backends copying social_core/backends/eveonline.py -> build/lib/social_core/backends copying social_core/backends/naver.py -> build/lib/social_core/backends copying social_core/backends/azuread_b2c.py -> build/lib/social_core/backends copying social_core/backends/base.py -> build/lib/social_core/backends copying social_core/backends/fence.py -> build/lib/social_core/backends copying social_core/backends/tumblr.py -> build/lib/social_core/backends copying social_core/backends/nk.py -> build/lib/social_core/backends copying social_core/backends/apple.py -> build/lib/social_core/backends copying social_core/backends/beats.py -> build/lib/social_core/backends copying social_core/backends/pinterest.py -> build/lib/social_core/backends copying social_core/backends/pocket.py -> build/lib/social_core/backends copying social_core/backends/disqus.py -> build/lib/social_core/backends copying social_core/backends/vend.py -> build/lib/social_core/backends copying social_core/backends/docker.py -> build/lib/social_core/backends copying social_core/backends/taobao.py -> build/lib/social_core/backends copying social_core/backends/steam.py -> build/lib/social_core/backends copying social_core/backends/suse.py -> build/lib/social_core/backends copying social_core/backends/azuread_tenant.py -> build/lib/social_core/backends copying social_core/backends/universe.py -> build/lib/social_core/backends copying social_core/backends/pixelpin.py -> build/lib/social_core/backends copying social_core/backends/cilogon.py -> build/lib/social_core/backends copying social_core/backends/dropbox.py -> build/lib/social_core/backends copying social_core/backends/sketchfab.py -> build/lib/social_core/backends copying social_core/backends/amazon.py -> build/lib/social_core/backends copying social_core/backends/coinbase.py -> build/lib/social_core/backends copying social_core/backends/musicbrainz.py -> build/lib/social_core/backends copying social_core/backends/foursquare.py -> build/lib/social_core/backends copying social_core/backends/vimeo.py -> build/lib/social_core/backends copying social_core/backends/keycloak.py -> build/lib/social_core/backends copying social_core/backends/justgiving.py -> build/lib/social_core/backends copying social_core/backends/goclio.py -> build/lib/social_core/backends copying social_core/backends/github.py -> build/lib/social_core/backends copying social_core/backends/mendeley.py -> build/lib/social_core/backends copying social_core/backends/mineid.py -> build/lib/social_core/backends copying social_core/backends/microsoft.py -> build/lib/social_core/backends copying social_core/backends/goclioeu.py -> build/lib/social_core/backends copying social_core/backends/openstack.py -> build/lib/social_core/backends copying social_core/backends/aol.py -> build/lib/social_core/backends copying social_core/backends/angel.py -> build/lib/social_core/backends copying social_core/backends/chatwork.py -> build/lib/social_core/backends copying social_core/backends/strava.py -> build/lib/social_core/backends copying social_core/backends/appsfuel.py -> build/lib/social_core/backends copying social_core/backends/withings.py -> build/lib/social_core/backends copying social_core/backends/itembase.py -> build/lib/social_core/backends copying social_core/backends/readability.py -> build/lib/social_core/backends copying social_core/backends/quizlet.py -> build/lib/social_core/backends copying social_core/backends/battlenet.py -> build/lib/social_core/backends copying social_core/backends/lyft.py -> build/lib/social_core/backends copying social_core/backends/fitbit.py -> build/lib/social_core/backends copying social_core/backends/qq.py -> build/lib/social_core/backends copying social_core/backends/dribbble.py -> build/lib/social_core/backends copying social_core/backends/behance.py -> build/lib/social_core/backends copying social_core/backends/wunderlist.py -> build/lib/social_core/backends copying social_core/backends/auth0.py -> build/lib/social_core/backends copying social_core/backends/persona.py -> build/lib/social_core/backends copying social_core/backends/ubuntu.py -> build/lib/social_core/backends copying social_core/backends/professionali.py -> build/lib/social_core/backends copying social_core/backends/__init__.py -> build/lib/social_core/backends copying social_core/backends/okta.py -> build/lib/social_core/backends copying social_core/backends/phabricator.py -> build/lib/social_core/backends copying social_core/backends/ngpvan.py -> build/lib/social_core/backends copying social_core/backends/yandex.py -> build/lib/social_core/backends copying social_core/backends/thisismyjam.py -> build/lib/social_core/backends copying social_core/backends/box.py -> build/lib/social_core/backends copying social_core/backends/discourse.py -> build/lib/social_core/backends copying social_core/backends/bitbucket.py -> build/lib/social_core/backends copying social_core/backends/username.py -> build/lib/social_core/backends copying social_core/backends/stripe.py -> build/lib/social_core/backends copying social_core/backends/twitch.py -> build/lib/social_core/backends copying social_core/backends/instagram.py -> build/lib/social_core/backends copying social_core/backends/orbi.py -> build/lib/social_core/backends copying social_core/backends/paypal.py -> build/lib/social_core/backends copying social_core/backends/atlassian.py -> build/lib/social_core/backends copying social_core/backends/exacttarget.py -> build/lib/social_core/backends copying social_core/backends/changetip.py -> build/lib/social_core/backends copying social_core/backends/osso.py -> build/lib/social_core/backends copying social_core/backends/elixir.py -> build/lib/social_core/backends copying social_core/backends/open_id.py -> build/lib/social_core/backends copying social_core/backends/lastfm.py -> build/lib/social_core/backends copying social_core/backends/odnoklassniki.py -> build/lib/social_core/backends copying social_core/backends/utils.py -> build/lib/social_core/backends copying social_core/backends/shopify.py -> build/lib/social_core/backends copying social_core/backends/gae.py -> build/lib/social_core/backends copying social_core/backends/weibo.py -> build/lib/social_core/backends copying social_core/backends/azuread.py -> build/lib/social_core/backends copying social_core/backends/upwork.py -> build/lib/social_core/backends copying social_core/backends/fedora.py -> build/lib/social_core/backends copying social_core/backends/five_hundred_px.py -> build/lib/social_core/backends copying social_core/backends/orcid.py -> build/lib/social_core/backends copying social_core/backends/belgiumeid.py -> build/lib/social_core/backends copying social_core/backends/shimmering.py -> build/lib/social_core/backends copying social_core/backends/email.py -> build/lib/social_core/backends copying social_core/backends/surveymonkey.py -> build/lib/social_core/backends copying social_core/backends/oauth.py -> build/lib/social_core/backends copying social_core/backends/slack.py -> build/lib/social_core/backends copying social_core/backends/eventbrite.py -> build/lib/social_core/backends copying social_core/backends/telegram.py -> build/lib/social_core/backends copying social_core/backends/cognito.py -> build/lib/social_core/backends copying social_core/backends/simplelogin.py -> build/lib/social_core/backends copying social_core/backends/qiita.py -> build/lib/social_core/backends copying social_core/backends/salesforce.py -> build/lib/social_core/backends copying social_core/backends/zotero.py -> build/lib/social_core/backends creating build/lib/social_core/pipeline copying social_core/pipeline/partial.py -> build/lib/social_core/pipeline copying social_core/pipeline/disconnect.py -> build/lib/social_core/pipeline copying social_core/pipeline/mail.py -> build/lib/social_core/pipeline copying social_core/pipeline/__init__.py -> build/lib/social_core/pipeline copying social_core/pipeline/user.py -> build/lib/social_core/pipeline copying social_core/pipeline/social_auth.py -> build/lib/social_core/pipeline copying social_core/pipeline/utils.py -> build/lib/social_core/pipeline copying social_core/pipeline/debug.py -> build/lib/social_core/pipeline creating build/lib/social_core/tests copying social_core/tests/strategy.py -> build/lib/social_core/tests copying social_core/tests/pipeline.py -> build/lib/social_core/tests copying social_core/tests/test_utils.py -> build/lib/social_core/tests copying social_core/tests/models.py -> build/lib/social_core/tests copying social_core/tests/test_partial.py -> build/lib/social_core/tests copying social_core/tests/test_storage.py -> build/lib/social_core/tests copying social_core/tests/test_pipeline.py -> build/lib/social_core/tests copying social_core/tests/__init__.py -> build/lib/social_core/tests copying social_core/tests/test_exceptions.py -> build/lib/social_core/tests creating build/lib/social_core/tests/actions copying social_core/tests/actions/test_login.py -> build/lib/social_core/tests/actions copying social_core/tests/actions/test_disconnect.py -> build/lib/social_core/tests/actions copying social_core/tests/actions/__init__.py -> build/lib/social_core/tests/actions copying social_core/tests/actions/test_associate.py -> build/lib/social_core/tests/actions copying social_core/tests/actions/actions.py -> build/lib/social_core/tests/actions creating build/lib/social_core/tests/backends copying social_core/tests/backends/test_zotero.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_box.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_apple.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_phabricator.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_amazon.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_chatwork.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_asana.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_email.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_coursera.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_musicbrainz.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_evernote.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_sketchfab.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_clef.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_orbi.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_steam.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_utils.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_github_enterprise.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_flat.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_angel.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_coinbase.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_yammer.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_five_hundred_px.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_mapmyfitness.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_twitter.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_globus.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_livejournal.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_vault.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_stackoverflow.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_dummy.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_instagram.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_itembase.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_foursquare.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_tumblr.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_eventbrite.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_xing.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_kakao.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_skyrock.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_gitea.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_dropbox.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_stocktwits.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/legacy.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_microsoft.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_dailymotion.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_live.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_slack.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_linkedin.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_dribbble.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_reddit.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_fitbit.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_edmodo.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_universe.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_quizlet.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_naver.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_cognito.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_thisismyjam.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_disqus.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_keycloak.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_uber.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_patreon.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_arcgis.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_pinterest.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_scistarter.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/base.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_zoom.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_flickr.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_udata.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_discourse.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_wunderlist.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_elixir.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_github.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_taobao.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_cilogon.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_broken.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_fence.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_nationbuilder.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_lyft.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_simplelogin.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_atlassian.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_bitbucket.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_khanacademy.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_twitch.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_drip.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_azuread_b2c.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_yandex.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_podio.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_deezer.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_grafana.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_auth0.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_ngpvan.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_tripit.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_spotify.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_orcid.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_readability.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_upwork.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_yahoo.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_okta.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_facebook.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_digitalocean.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_strava.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_open_id_connect.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/__init__.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_paypal.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_mixcloud.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_google.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_soundcloud.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_username.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_qiita.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_saml.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/open_id.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_gitlab.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_osso.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_mailru.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_mineid.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_stripe.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_azuread.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_behance.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/oauth.py -> build/lib/social_core/tests/backends copying social_core/tests/backends/test_vk.py -> build/lib/social_core/tests/backends running egg_info creating social_auth_core.egg-info writing social_auth_core.egg-info/PKG-INFO writing dependency_links to social_auth_core.egg-info/dependency_links.txt writing requirements to social_auth_core.egg-info/requires.txt writing top-level names to social_auth_core.egg-info/top_level.txt writing manifest file 'social_auth_core.egg-info/SOURCES.txt' reading manifest file 'social_auth_core.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' warning: no directories found matching 'examples' warning: no previously-included files matching '*' found under directory '.tox' warning: no previously-included files matching '*.pyc' found under directory 'social_core' adding license file 'LICENSE' writing manifest file 'social_auth_core.egg-info/SOURCES.txt' copying social_core/tests/requirements.txt -> build/lib/social_core/tests copying social_core/tests/testkey.pem -> build/lib/social_core/tests creating build/lib/social_core/tests/backends/data copying social_core/tests/backends/data/saml_config.json -> build/lib/social_core/tests/backends/data copying social_core/tests/backends/data/saml_response.txt -> build/lib/social_core/tests/backends/data + RPM_EC=0 ++ jobs -p + exit 0 Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.7KwJwI + umask 022 + cd /builddir/build/BUILD + '[' /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch '!=' / ']' + rm -rf /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch ++ dirname /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch + mkdir -p /builddir/build/BUILDROOT + mkdir /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch + CFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Werror=implicit-function-declaration -Werror=implicit-int -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer ' + export CFLAGS + CXXFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer ' + export CXXFLAGS + FFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer -I/usr/lib/gfortran/modules ' + export FFLAGS + FCFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer -I/usr/lib/gfortran/modules ' + export FCFLAGS + VALAFLAGS=-g + export VALAFLAGS + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd social-auth-core-4.3.0 + CFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Werror=implicit-function-declaration -Werror=implicit-int -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + /usr/bin/python3 setup.py install -O1 --skip-build --root /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch --prefix /usr running install /usr/lib/python3.12/site-packages/setuptools/_distutils/cmd.py:66: SetuptoolsDeprecationWarning: setup.py install is deprecated. !! ******************************************************************************** Please avoid running ``setup.py`` directly. Instead, use pypa/build, pypa/installer or other standards-based tools. Follow the current Python packaging guidelines when building Python RPM packages. See https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html and https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/ for details. ******************************************************************************** !! self.initialize_options() running install_lib creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12 creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core copying build/lib/social_core/strategy.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core copying build/lib/social_core/storage.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core copying build/lib/social_core/store.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core copying build/lib/social_core/exceptions.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline copying build/lib/social_core/pipeline/partial.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline copying build/lib/social_core/pipeline/disconnect.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline copying build/lib/social_core/pipeline/mail.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline copying build/lib/social_core/pipeline/__init__.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline copying build/lib/social_core/pipeline/user.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline copying build/lib/social_core/pipeline/social_auth.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline copying build/lib/social_core/pipeline/utils.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline copying build/lib/social_core/pipeline/debug.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/requirements.txt -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/strategy.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/pipeline.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/test_utils.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/testkey.pem -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/models.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/test_partial.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/test_storage.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/test_pipeline.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests copying build/lib/social_core/tests/__init__.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions copying build/lib/social_core/tests/actions/test_login.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions copying build/lib/social_core/tests/actions/test_disconnect.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions copying build/lib/social_core/tests/actions/__init__.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions copying build/lib/social_core/tests/actions/test_associate.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions copying build/lib/social_core/tests/actions/actions.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions copying build/lib/social_core/tests/test_exceptions.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_zotero.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_box.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_apple.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_phabricator.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_amazon.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_chatwork.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_asana.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_email.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_coursera.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_musicbrainz.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_evernote.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_sketchfab.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_clef.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_orbi.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_steam.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_utils.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_github_enterprise.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_flat.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_angel.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_coinbase.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_yammer.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_five_hundred_px.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_mapmyfitness.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_twitter.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_globus.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_livejournal.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_vault.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_stackoverflow.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_dummy.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_instagram.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_itembase.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_foursquare.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_tumblr.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_eventbrite.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_xing.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_kakao.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_skyrock.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_gitea.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_dropbox.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_stocktwits.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/legacy.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_microsoft.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_dailymotion.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_live.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_slack.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_linkedin.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_dribbble.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_reddit.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_fitbit.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_edmodo.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_universe.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_quizlet.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_naver.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_cognito.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_thisismyjam.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/data copying build/lib/social_core/tests/backends/data/saml_response.txt -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/data copying build/lib/social_core/tests/backends/data/saml_config.json -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/data copying build/lib/social_core/tests/backends/test_disqus.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_keycloak.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_uber.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_patreon.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_arcgis.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_pinterest.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_scistarter.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/base.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_zoom.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_flickr.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_udata.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_discourse.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_wunderlist.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_elixir.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_github.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_taobao.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_cilogon.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_broken.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_fence.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_nationbuilder.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_lyft.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_simplelogin.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_atlassian.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_bitbucket.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_khanacademy.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_twitch.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_drip.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_azuread_b2c.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_yandex.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_podio.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_deezer.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_grafana.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_auth0.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_ngpvan.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_tripit.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_spotify.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_orcid.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_readability.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_upwork.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_yahoo.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_okta.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_facebook.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_digitalocean.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_strava.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_open_id_connect.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/__init__.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_paypal.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_mixcloud.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_google.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_soundcloud.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_username.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_qiita.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_saml.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/open_id.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_gitlab.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_osso.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_mailru.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_mineid.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_stripe.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_azuread.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_behance.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/oauth.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/tests/backends/test_vk.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends copying build/lib/social_core/__init__.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core copying build/lib/social_core/utils.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/digitalocean.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/soundcloud.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/douban.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/monzo.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/google_openidconnect.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/pushbullet.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/vk.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/jawbone.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/yahoo.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/clef.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/deezer.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/khanacademy.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/mailru.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/github_enterprise.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/spotify.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/mailchimp.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/launchpad.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/arcgis.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/stocktwits.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/google.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/runkeeper.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/udata.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/twitter.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/xing.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/globus.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/live.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/line.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/tripit.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/weixin.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/patreon.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/openstreetmap.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/flickr.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/zoom.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/asana.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/stackoverflow.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/echosign.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/untappd.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/drip.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/skyrock.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/trello.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/vault.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/bungie.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/mediawiki.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/facebook.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/grafana.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/okta_openidconnect.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/kakao.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/meetup.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/discord.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/openshift.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/rdio.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/dailymotion.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/saml.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/nationbuilder.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/reddit.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/scistarter.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/loginradius.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/edmodo.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/livejournal.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/mapmyfitness.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/openstackdev.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/twilio.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/mixcloud.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/gitea.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/evernote.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/legacy.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/uber.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/open_id_connect.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/linkedin.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/moves.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/podio.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/flat.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/coursera.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/gitlab.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/coding.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/yammer.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/classlink.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/hubspot.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/eveonline.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/naver.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/azuread_b2c.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/base.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/fence.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/tumblr.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/nk.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/apple.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/beats.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/pinterest.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/pocket.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/disqus.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/vend.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/docker.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/taobao.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/steam.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/suse.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/azuread_tenant.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/universe.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/pixelpin.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/cilogon.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/dropbox.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/sketchfab.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/amazon.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/coinbase.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/musicbrainz.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/foursquare.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/vimeo.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/keycloak.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/justgiving.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/goclio.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/github.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/mendeley.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/mineid.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/microsoft.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/goclioeu.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/openstack.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/aol.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/angel.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/chatwork.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/strava.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/appsfuel.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/withings.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/itembase.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/readability.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/quizlet.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/battlenet.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/lyft.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/fitbit.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/qq.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/dribbble.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/behance.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/wunderlist.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/auth0.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/persona.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/ubuntu.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/professionali.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/__init__.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/okta.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/phabricator.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/ngpvan.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/yandex.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/thisismyjam.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/box.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/discourse.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/bitbucket.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/username.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/stripe.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/twitch.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/instagram.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/orbi.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/paypal.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/atlassian.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/exacttarget.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/changetip.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/osso.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/elixir.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/open_id.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/lastfm.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/odnoklassniki.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/utils.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/shopify.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/gae.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/weibo.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/azuread.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/upwork.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/fedora.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/five_hundred_px.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/orcid.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/belgiumeid.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/shimmering.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/email.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/surveymonkey.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/oauth.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/slack.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/eventbrite.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/telegram.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/cognito.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/simplelogin.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/qiita.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/salesforce.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/backends/zotero.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends copying build/lib/social_core/actions.py -> /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/strategy.py to strategy.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/storage.py to storage.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/store.py to store.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/exceptions.py to exceptions.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline/partial.py to partial.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline/disconnect.py to disconnect.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline/mail.py to mail.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline/__init__.py to __init__.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline/user.py to user.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline/social_auth.py to social_auth.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline/utils.py to utils.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/pipeline/debug.py to debug.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/strategy.py to strategy.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/pipeline.py to pipeline.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/test_utils.py to test_utils.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/models.py to models.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/test_partial.py to test_partial.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/test_storage.py to test_storage.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/test_pipeline.py to test_pipeline.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/__init__.py to __init__.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions/test_login.py to test_login.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions/test_disconnect.py to test_disconnect.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions/__init__.py to __init__.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions/test_associate.py to test_associate.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/actions/actions.py to actions.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/test_exceptions.py to test_exceptions.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_zotero.py to test_zotero.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_box.py to test_box.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_apple.py to test_apple.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_phabricator.py to test_phabricator.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_amazon.py to test_amazon.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_chatwork.py to test_chatwork.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_asana.py to test_asana.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_email.py to test_email.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_coursera.py to test_coursera.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_musicbrainz.py to test_musicbrainz.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_evernote.py to test_evernote.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_sketchfab.py to test_sketchfab.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_clef.py to test_clef.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_orbi.py to test_orbi.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_steam.py to test_steam.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_utils.py to test_utils.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_github_enterprise.py to test_github_enterprise.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_flat.py to test_flat.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_angel.py to test_angel.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_coinbase.py to test_coinbase.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_yammer.py to test_yammer.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_five_hundred_px.py to test_five_hundred_px.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_mapmyfitness.py to test_mapmyfitness.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_twitter.py to test_twitter.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_globus.py to test_globus.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_livejournal.py to test_livejournal.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_vault.py to test_vault.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_stackoverflow.py to test_stackoverflow.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_dummy.py to test_dummy.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_instagram.py to test_instagram.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_itembase.py to test_itembase.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_foursquare.py to test_foursquare.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_tumblr.py to test_tumblr.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_eventbrite.py to test_eventbrite.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_xing.py to test_xing.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_kakao.py to test_kakao.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_skyrock.py to test_skyrock.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_gitea.py to test_gitea.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_dropbox.py to test_dropbox.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_stocktwits.py to test_stocktwits.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/legacy.py to legacy.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_microsoft.py to test_microsoft.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_dailymotion.py to test_dailymotion.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_live.py to test_live.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_slack.py to test_slack.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_linkedin.py to test_linkedin.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_dribbble.py to test_dribbble.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_reddit.py to test_reddit.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_fitbit.py to test_fitbit.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_edmodo.py to test_edmodo.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_universe.py to test_universe.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_quizlet.py to test_quizlet.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_naver.py to test_naver.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_cognito.py to test_cognito.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_thisismyjam.py to test_thisismyjam.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_disqus.py to test_disqus.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_keycloak.py to test_keycloak.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_uber.py to test_uber.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_patreon.py to test_patreon.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_arcgis.py to test_arcgis.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_pinterest.py to test_pinterest.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_scistarter.py to test_scistarter.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/base.py to base.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_zoom.py to test_zoom.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_flickr.py to test_flickr.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_udata.py to test_udata.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_discourse.py to test_discourse.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_wunderlist.py to test_wunderlist.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_elixir.py to test_elixir.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_github.py to test_github.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_taobao.py to test_taobao.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_cilogon.py to test_cilogon.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_broken.py to test_broken.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_fence.py to test_fence.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_nationbuilder.py to test_nationbuilder.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_lyft.py to test_lyft.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_simplelogin.py to test_simplelogin.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_atlassian.py to test_atlassian.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_bitbucket.py to test_bitbucket.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_khanacademy.py to test_khanacademy.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_twitch.py to test_twitch.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_drip.py to test_drip.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_azuread_b2c.py to test_azuread_b2c.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_yandex.py to test_yandex.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_podio.py to test_podio.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_deezer.py to test_deezer.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_grafana.py to test_grafana.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_auth0.py to test_auth0.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_ngpvan.py to test_ngpvan.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_tripit.py to test_tripit.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_spotify.py to test_spotify.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_orcid.py to test_orcid.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_readability.py to test_readability.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_upwork.py to test_upwork.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_yahoo.py to test_yahoo.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_okta.py to test_okta.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_facebook.py to test_facebook.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_digitalocean.py to test_digitalocean.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_strava.py to test_strava.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_open_id_connect.py to test_open_id_connect.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/__init__.py to __init__.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_paypal.py to test_paypal.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_mixcloud.py to test_mixcloud.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_google.py to test_google.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_soundcloud.py to test_soundcloud.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_username.py to test_username.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_qiita.py to test_qiita.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_saml.py to test_saml.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/open_id.py to open_id.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_gitlab.py to test_gitlab.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_osso.py to test_osso.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_mailru.py to test_mailru.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_mineid.py to test_mineid.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_stripe.py to test_stripe.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_azuread.py to test_azuread.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_behance.py to test_behance.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/oauth.py to oauth.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends/test_vk.py to test_vk.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/__init__.py to __init__.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/utils.py to utils.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/digitalocean.py to digitalocean.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/soundcloud.py to soundcloud.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/douban.py to douban.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/monzo.py to monzo.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/google_openidconnect.py to google_openidconnect.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/pushbullet.py to pushbullet.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/vk.py to vk.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/jawbone.py to jawbone.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/yahoo.py to yahoo.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/clef.py to clef.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/deezer.py to deezer.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/khanacademy.py to khanacademy.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/mailru.py to mailru.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/github_enterprise.py to github_enterprise.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/spotify.py to spotify.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/mailchimp.py to mailchimp.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/launchpad.py to launchpad.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/arcgis.py to arcgis.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/stocktwits.py to stocktwits.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/google.py to google.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/runkeeper.py to runkeeper.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/udata.py to udata.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/twitter.py to twitter.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/xing.py to xing.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/globus.py to globus.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/live.py to live.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/line.py to line.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/tripit.py to tripit.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/weixin.py to weixin.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/patreon.py to patreon.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/openstreetmap.py to openstreetmap.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/flickr.py to flickr.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/zoom.py to zoom.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/asana.py to asana.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/stackoverflow.py to stackoverflow.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/echosign.py to echosign.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/untappd.py to untappd.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/drip.py to drip.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/skyrock.py to skyrock.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/trello.py to trello.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/vault.py to vault.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/bungie.py to bungie.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/mediawiki.py to mediawiki.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/facebook.py to facebook.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/grafana.py to grafana.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/okta_openidconnect.py to okta_openidconnect.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/kakao.py to kakao.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/meetup.py to meetup.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/discord.py to discord.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/openshift.py to openshift.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/rdio.py to rdio.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/dailymotion.py to dailymotion.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/saml.py to saml.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/nationbuilder.py to nationbuilder.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/reddit.py to reddit.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/scistarter.py to scistarter.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/loginradius.py to loginradius.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/edmodo.py to edmodo.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/livejournal.py to livejournal.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/mapmyfitness.py to mapmyfitness.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/openstackdev.py to openstackdev.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/twilio.py to twilio.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/mixcloud.py to mixcloud.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/gitea.py to gitea.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/evernote.py to evernote.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/legacy.py to legacy.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/uber.py to uber.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/open_id_connect.py to open_id_connect.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/linkedin.py to linkedin.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/moves.py to moves.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/podio.py to podio.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/flat.py to flat.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/coursera.py to coursera.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/gitlab.py to gitlab.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/coding.py to coding.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/yammer.py to yammer.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/classlink.py to classlink.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/hubspot.py to hubspot.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/eveonline.py to eveonline.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/naver.py to naver.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/azuread_b2c.py to azuread_b2c.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/base.py to base.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/fence.py to fence.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/tumblr.py to tumblr.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/nk.py to nk.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/apple.py to apple.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/beats.py to beats.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/pinterest.py to pinterest.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/pocket.py to pocket.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/disqus.py to disqus.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/vend.py to vend.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/docker.py to docker.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/taobao.py to taobao.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/steam.py to steam.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/suse.py to suse.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/azuread_tenant.py to azuread_tenant.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/universe.py to universe.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/pixelpin.py to pixelpin.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/cilogon.py to cilogon.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/dropbox.py to dropbox.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/sketchfab.py to sketchfab.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/amazon.py to amazon.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/coinbase.py to coinbase.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/musicbrainz.py to musicbrainz.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/foursquare.py to foursquare.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/vimeo.py to vimeo.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/keycloak.py to keycloak.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/justgiving.py to justgiving.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/goclio.py to goclio.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/github.py to github.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/mendeley.py to mendeley.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/mineid.py to mineid.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/microsoft.py to microsoft.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/goclioeu.py to goclioeu.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/openstack.py to openstack.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/aol.py to aol.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/angel.py to angel.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/chatwork.py to chatwork.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/strava.py to strava.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/appsfuel.py to appsfuel.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/withings.py to withings.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/itembase.py to itembase.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/readability.py to readability.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/quizlet.py to quizlet.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/battlenet.py to battlenet.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/lyft.py to lyft.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/fitbit.py to fitbit.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/qq.py to qq.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/dribbble.py to dribbble.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/behance.py to behance.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/wunderlist.py to wunderlist.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/auth0.py to auth0.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/persona.py to persona.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/ubuntu.py to ubuntu.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/professionali.py to professionali.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/__init__.py to __init__.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/okta.py to okta.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/phabricator.py to phabricator.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/ngpvan.py to ngpvan.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/yandex.py to yandex.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/thisismyjam.py to thisismyjam.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/box.py to box.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/discourse.py to discourse.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/bitbucket.py to bitbucket.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/username.py to username.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/stripe.py to stripe.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/twitch.py to twitch.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/instagram.py to instagram.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/orbi.py to orbi.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/paypal.py to paypal.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/atlassian.py to atlassian.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/exacttarget.py to exacttarget.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/changetip.py to changetip.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/osso.py to osso.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/elixir.py to elixir.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/open_id.py to open_id.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/lastfm.py to lastfm.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/odnoklassniki.py to odnoklassniki.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/utils.py to utils.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/shopify.py to shopify.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/gae.py to gae.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/weibo.py to weibo.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/azuread.py to azuread.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/upwork.py to upwork.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/fedora.py to fedora.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/five_hundred_px.py to five_hundred_px.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/orcid.py to orcid.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/belgiumeid.py to belgiumeid.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/shimmering.py to shimmering.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/email.py to email.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/surveymonkey.py to surveymonkey.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/oauth.py to oauth.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/slack.py to slack.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/eventbrite.py to eventbrite.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/telegram.py to telegram.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/cognito.py to cognito.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/simplelogin.py to simplelogin.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/qiita.py to qiita.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/salesforce.py to salesforce.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/backends/zotero.py to zotero.cpython-312.pyc byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/actions.py to actions.cpython-312.pyc writing byte-compilation script '/tmp/tmp_xwd65hz.py' /usr/bin/python3 /tmp/tmp_xwd65hz.py removing /tmp/tmp_xwd65hz.py running install_egg_info running egg_info writing social_auth_core.egg-info/PKG-INFO writing dependency_links to social_auth_core.egg-info/dependency_links.txt writing requirements to social_auth_core.egg-info/requires.txt writing top-level names to social_auth_core.egg-info/top_level.txt reading manifest file 'social_auth_core.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' warning: no directories found matching 'examples' warning: no previously-included files matching '*' found under directory '.tox' warning: no previously-included files matching '*.pyc' found under directory 'social_core' adding license file 'LICENSE' writing manifest file 'social_auth_core.egg-info/SOURCES.txt' Copying social_auth_core.egg-info to /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_auth_core-4.3.0-py3.12.egg-info running install_scripts + rm -rfv /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/bin/__pycache__ + rm -r /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages/social_core/tests/ + /usr/bin/find-debuginfo -j8 --strict-build-id -m -i --build-id-seed 4.3.0-8.fc40 --unique-debug-suffix -4.3.0-8.fc40.noarch --unique-debug-src-base python-social-auth-core-4.3.0-8.fc40.noarch --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 50000000 -S debugsourcefiles.list /builddir/build/BUILD/social-auth-core-4.3.0 find-debuginfo: starting Extracting debug info from 0 files Creating .debug symlinks for symlinks to ELF files find: ‘debug’: No such file or directory find-debuginfo: done + /usr/lib/rpm/check-buildroot + /usr/lib/rpm/redhat/brp-ldconfig + /usr/lib/rpm/brp-compress + /usr/lib/rpm/redhat/brp-strip-lto /usr/bin/strip + /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip + /usr/lib/rpm/check-rpaths + /usr/lib/rpm/redhat/brp-mangle-shebangs + /usr/lib/rpm/brp-remove-la-files + env /usr/lib/rpm/redhat/brp-python-bytecompile '' 1 0 -j8 Bytecompiling .py files below /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12 using python3.12 + /usr/lib/rpm/redhat/brp-python-hardlink Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.3f3gwC + umask 022 + cd /builddir/build/BUILD + CFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Werror=implicit-function-declaration -Werror=implicit-int -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer ' + export CFLAGS + CXXFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer ' + export CXXFLAGS + FFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer -I/usr/lib/gfortran/modules ' + export FFLAGS + FCFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer -I/usr/lib/gfortran/modules ' + export FCFLAGS + VALAFLAGS=-g + export VALAFLAGS + RUSTFLAGS='-Copt-level=3 -Cdebuginfo=2 -Ccodegen-units=1 -Cstrip=none -Cforce-frame-pointers=yes -Clink-arg=-Wl,-z,relro -Clink-arg=-Wl,-z,now --cap-lints=warn' + export RUSTFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd social-auth-core-4.3.0 + CFLAGS='-O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Werror=implicit-function-declaration -Werror=implicit-int -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fno-omit-frame-pointer ' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 ' + PATH=/builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin + PYTHONPATH=/builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib64/python3.12/site-packages:/builddir/build/BUILDROOT/python-social-auth-core-4.3.0-8.fc40.noarch/usr/lib/python3.12/site-packages + PYTHONDONTWRITEBYTECODE=1 + PYTEST_XDIST_AUTO_NUM_WORKERS=8 + /usr/bin/pytest social_core/tests/ ============================= test session starts ============================== platform linux -- Python 3.12.0, pytest-7.3.2, pluggy-1.3.0 rootdir: /builddir/build/BUILD/social-auth-core-4.3.0 plugins: cov-4.0.0 collected 511 items social_core/tests/test_exceptions.py ................... [ 3%] social_core/tests/test_partial.py .... [ 4%] social_core/tests/test_pipeline.py ............ [ 6%] social_core/tests/test_storage.py ............................ [ 12%] social_core/tests/test_utils.py ............................. [ 18%] social_core/tests/actions/test_associate.py ...... [ 19%] social_core/tests/actions/test_disconnect.py .... [ 19%] social_core/tests/actions/test_login.py ........ [ 21%] social_core/tests/backends/test_amazon.py .... [ 22%] social_core/tests/backends/test_angel.py .. [ 22%] social_core/tests/backends/test_apple.py .. [ 23%] social_core/tests/backends/test_arcgis.py .. [ 23%] social_core/tests/backends/test_asana.py .. [ 23%] social_core/tests/backends/test_atlassian.py .. [ 24%] social_core/tests/backends/test_auth0.py .. [ 24%] social_core/tests/backends/test_azuread.py ... [ 25%] social_core/tests/backends/test_azuread_b2c.py ... [ 25%] social_core/tests/backends/test_behance.py .. [ 26%] social_core/tests/backends/test_bitbucket.py ........ [ 27%] social_core/tests/backends/test_box.py ... [ 28%] social_core/tests/backends/test_broken.py .... [ 29%] social_core/tests/backends/test_chatwork.py .. [ 29%] social_core/tests/backends/test_cilogon.py .. [ 29%] social_core/tests/backends/test_clef.py .. [ 30%] social_core/tests/backends/test_cognito.py .. [ 30%] social_core/tests/backends/test_coinbase.py .. [ 31%] social_core/tests/backends/test_coursera.py .. [ 31%] social_core/tests/backends/test_dailymotion.py .. [ 31%] social_core/tests/backends/test_deezer.py .. [ 32%] social_core/tests/backends/test_digitalocean.py .. [ 32%] social_core/tests/backends/test_discourse.py .. [ 33%] social_core/tests/backends/test_disqus.py .. [ 33%] social_core/tests/backends/test_dribbble.py .. [ 33%] social_core/tests/backends/test_drip.py .. [ 34%] social_core/tests/backends/test_dropbox.py .. [ 34%] social_core/tests/backends/test_dummy.py ..................F......... [ 40%] social_core/tests/backends/test_edmodo.py .. [ 40%] social_core/tests/backends/test_elixir.py .FFF.F. [ 41%] social_core/tests/backends/test_email.py .. [ 42%] social_core/tests/backends/test_eventbrite.py . [ 42%] social_core/tests/backends/test_evernote.py ...... [ 43%] social_core/tests/backends/test_facebook.py ...... [ 44%] social_core/tests/backends/test_fence.py .FFF.F. [ 46%] social_core/tests/backends/test_fitbit.py .. [ 46%] social_core/tests/backends/test_five_hundred_px.py .. [ 46%] social_core/tests/backends/test_flat.py .. [ 47%] social_core/tests/backends/test_flickr.py .. [ 47%] social_core/tests/backends/test_foursquare.py .. [ 48%] social_core/tests/backends/test_gitea.py .... [ 48%] social_core/tests/backends/test_github.py ............. [ 51%] social_core/tests/backends/test_github_enterprise.py ............. [ 54%] social_core/tests/backends/test_gitlab.py .... [ 54%] social_core/tests/backends/test_globus.py .FFF.F. [ 56%] social_core/tests/backends/test_google.py ............FFF.F. [ 59%] social_core/tests/backends/test_grafana.py .. [ 60%] social_core/tests/backends/test_instagram.py .. [ 60%] social_core/tests/backends/test_itembase.py .. [ 60%] social_core/tests/backends/test_kakao.py .. [ 61%] social_core/tests/backends/test_keycloak.py ... [ 61%] social_core/tests/backends/test_khanacademy.py .. [ 62%] social_core/tests/backends/test_linkedin.py .... [ 63%] social_core/tests/backends/test_live.py .. [ 63%] social_core/tests/backends/test_livejournal.py ... [ 63%] social_core/tests/backends/test_lyft.py .. [ 64%] social_core/tests/backends/test_mailru.py .. [ 64%] social_core/tests/backends/test_mapmyfitness.py .. [ 65%] social_core/tests/backends/test_microsoft.py ... [ 65%] social_core/tests/backends/test_mineid.py .. [ 66%] social_core/tests/backends/test_mixcloud.py .. [ 66%] social_core/tests/backends/test_musicbrainz.py .. [ 66%] social_core/tests/backends/test_nationbuilder.py .. [ 67%] social_core/tests/backends/test_naver.py .. [ 67%] social_core/tests/backends/test_ngpvan.py ....... [ 69%] social_core/tests/backends/test_okta.py ..F.FFF.F. [ 71%] social_core/tests/backends/test_open_id_connect.py F.FFF.F.F.FFF.F. [ 74%] social_core/tests/backends/test_orbi.py .. [ 74%] social_core/tests/backends/test_orcid.py .. [ 74%] social_core/tests/backends/test_osso.py .. [ 75%] social_core/tests/backends/test_patreon.py .. [ 75%] social_core/tests/backends/test_paypal.py ...... [ 76%] social_core/tests/backends/test_phabricator.py .... [ 77%] social_core/tests/backends/test_pinterest.py .... [ 78%] social_core/tests/backends/test_podio.py .. [ 78%] social_core/tests/backends/test_qiita.py .. [ 79%] social_core/tests/backends/test_quizlet.py .. [ 79%] social_core/tests/backends/test_readability.py .. [ 80%] social_core/tests/backends/test_reddit.py ... [ 80%] social_core/tests/backends/test_saml.py ... [ 81%] social_core/tests/backends/test_scistarter.py .. [ 81%] social_core/tests/backends/test_simplelogin.py .. [ 81%] social_core/tests/backends/test_sketchfab.py .. [ 82%] social_core/tests/backends/test_skyrock.py .. [ 82%] social_core/tests/backends/test_slack.py ...... [ 83%] social_core/tests/backends/test_soundcloud.py .. [ 84%] social_core/tests/backends/test_spotify.py .. [ 84%] social_core/tests/backends/test_stackoverflow.py .. [ 85%] social_core/tests/backends/test_steam.py F.F. [ 85%] social_core/tests/backends/test_stocktwits.py .... [ 86%] social_core/tests/backends/test_strava.py .. [ 87%] social_core/tests/backends/test_stripe.py .. [ 87%] social_core/tests/backends/test_taobao.py .. [ 87%] social_core/tests/backends/test_thisismyjam.py .. [ 88%] social_core/tests/backends/test_tripit.py .... [ 89%] social_core/tests/backends/test_tumblr.py .. [ 89%] social_core/tests/backends/test_twitch.py .FFF.F... [ 91%] social_core/tests/backends/test_twitter.py .... [ 91%] social_core/tests/backends/test_uber.py .. [ 92%] social_core/tests/backends/test_udata.py .. [ 92%] social_core/tests/backends/test_universe.py .. [ 93%] social_core/tests/backends/test_upwork.py .. [ 93%] social_core/tests/backends/test_username.py .. [ 93%] social_core/tests/backends/test_utils.py ... [ 94%] social_core/tests/backends/test_vault.py F.FFF.F. [ 96%] social_core/tests/backends/test_vk.py .. [ 96%] social_core/tests/backends/test_wunderlist.py .. [ 96%] social_core/tests/backends/test_xing.py .. [ 97%] social_core/tests/backends/test_yahoo.py ... [ 97%] social_core/tests/backends/test_yammer.py .. [ 98%] social_core/tests/backends/test_yandex.py .... [ 99%] social_core/tests/backends/test_zoom.py ... [ 99%] social_core/tests/backends/test_zotero.py .. [100%] =================================== FAILURES =================================== _____________________ ExpirationTimeTest.test_expires_time _____________________ self = def test_expires_time(self): user = self.do_login() social = user.social[0] expiration = social.expiration_timedelta() > self.assertEqual(expiration <= DELTA, True) E AssertionError: False != True social_core/tests/backends/test_dummy.py:146: AssertionError ________________ ElixirOpenIdConnectTest.test_invalid_audience _________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2xvZ2luLmVsaXhpci1jemVjaC5vcmcvb2lkYy8iLCJub...vlZ1NAClUeDyy3W4DDDXmhh_erV7KOM4FGq5Ob9GRbtvEoHt9kV8kSNGsaCLk431NOveydwEFzFSID1W0C0G5D2G6nkbFfxGnt1OgZQsdw4iFUPIKHyYcw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {'verify_at_hash': False}, audience = 'a-key' issuer = 'https://login.elixir-czech.org/oidc/', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706432293, ...} audience = 'a-key', issuer = 'https://login.elixir-czech.org/oidc/' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706432293, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_audience(self): > self.authtoken_raised('Token error: Invalid audience', client_key='someone-else') social_core/tests/backends/test_open_id_connect.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid audience" does not match "Token error: Signature has expired" _______________ ElixirOpenIdConnectTest.test_invalid_issue_time ________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2xvZ2luLmVsaXhpci1jemVjaC5vcmcvb2lkYy8iLCJub...Zzki6B-58hYl5hAOOW2SEFVFKhsq7EoRdm1GL1ykR3IbwFshbNCSW6TZA4E3d4YaNvsZHJjMTpHAFU6ggBOCaaMasd8T5YTkbzkIuOIr-RBydfOt0DLyeg' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {'verify_at_hash': False}, audience = 'a-key' issuer = 'https://login.elixir-czech.org/oidc/', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432352, ...} audience = 'a-key', issuer = 'https://login.elixir-czech.org/oidc/' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432352, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issue_time(self): expiration_datetime = datetime.datetime.utcnow() - \ datetime.timedelta(hours=1) > self.authtoken_raised('Token error: Incorrect id_token: iat', issue_datetime=expiration_datetime) social_core/tests/backends/test_open_id_connect.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: iat" does not match "Token error: Signature has expired" _________________ ElixirOpenIdConnectTest.test_invalid_issuer __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IlVLV2dJMDNnM0UzMVFaSWZwU...g6_zdCcmFgA7zpwjpSQ2ZCjWDNm2O6JChwy36ipa9aaxwynDUC6Q8Da2PbC2eDI5fJquBEr2j16NYYW0Vfip12AnhNjWereK3BhDc58U7PoJ92A29sTshw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {'verify_at_hash': False}, audience = 'a-key' issuer = 'https://login.elixir-czech.org/oidc/', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432405, ...} audience = 'a-key', issuer = 'https://login.elixir-czech.org/oidc/' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432405, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issuer(self): > self.authtoken_raised('Token error: Invalid issuer', issuer='someone-else') social_core/tests/backends/test_open_id_connect.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid issuer" does not match "Token error: Signature has expired" __________________ ElixirOpenIdConnectTest.test_invalid_nonce __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3RrZXkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2xvZ2luLmVsaXhpci1jemVjaC5vcmcvb2lkYy...ycCVlSmcLmU7bHdMiAWQTK7deHebTltrru8f38g9Xt6orLHu5cQatR6cxExz7ybez1BUKDsuFAvuGN2n2GWYkZdRVYl9EDig0ASIiMHPvzjv-YQh3LQNNA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {'verify_at_hash': False}, audience = 'a-key' issuer = 'https://login.elixir-czech.org/oidc/', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432517, ...} audience = 'a-key', issuer = 'https://login.elixir-czech.org/oidc/' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432517, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_nonce(self): > self.authtoken_raised( 'Token error: Incorrect id_token: nonce', nonce='something-wrong', kid='testkey', ) social_core/tests/backends/test_open_id_connect.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: nonce" does not match "Token error: Signature has expired" _________________ FenceOpenIdConnectTest.test_invalid_audience _________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL25jaS1jcmRjLmRhdGFjb21tb25zLmlvLyIsIm5vbmNlI..._BWWrdbbRq3EOtLtTQr-dNIaFzpdeQYsdkBD1dGLEfjlFiOE9hHdB3uBgiWk7Ca1fxoQPpkdZucXG696iY1SnRsogV-7z1ebmd4pIvBoR25zgavG3RpEnA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {'verify_at_hash': False}, audience = 'a-key' issuer = 'https://nci-crdc.datacommons.io/', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706432732, ...} audience = 'a-key', issuer = 'https://nci-crdc.datacommons.io/', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706432732, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_audience(self): > self.authtoken_raised('Token error: Invalid audience', client_key='someone-else') social_core/tests/backends/test_open_id_connect.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid audience" does not match "Token error: Signature has expired" ________________ FenceOpenIdConnectTest.test_invalid_issue_time ________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL25jaS1jcmRjLmRhdGFjb21tb25zLmlvLyIsIm5vbmNlI...XyiPgGVbqREzS_O7nQR9EATSzYknS0ZltJh3IHh6ezIn7xC69hM5hYobfxv5fToxN651t51-L-Orx3JRqOoG2CvCOiEnkQUezr2OCs5wxGIXjagbjnIE7A' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {'verify_at_hash': False}, audience = 'a-key' issuer = 'https://nci-crdc.datacommons.io/', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432816, ...} audience = 'a-key', issuer = 'https://nci-crdc.datacommons.io/', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432816, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issue_time(self): expiration_datetime = datetime.datetime.utcnow() - \ datetime.timedelta(hours=1) > self.authtoken_raised('Token error: Incorrect id_token: iat', issue_datetime=expiration_datetime) social_core/tests/backends/test_open_id_connect.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: iat" does not match "Token error: Signature has expired" __________________ FenceOpenIdConnectTest.test_invalid_issuer __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IkQ0YTFSYVZGNE1iZFg2aEVYd...YGcGnWYStNTpsKGFS9aalECY4IQZW2pesKBkOf8x2P-GRRLcTiX9E2PWRAk3gxscRRt6Q879-ThKBeGfsf9jXAD3CRVoPEVhiK0Wn8QFAF4O38u2lcauBw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {'verify_at_hash': False}, audience = 'a-key' issuer = 'https://nci-crdc.datacommons.io/', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432894, ...} audience = 'a-key', issuer = 'https://nci-crdc.datacommons.io/', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706432894, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issuer(self): > self.authtoken_raised('Token error: Invalid issuer', issuer='someone-else') social_core/tests/backends/test_open_id_connect.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid issuer" does not match "Token error: Signature has expired" __________________ FenceOpenIdConnectTest.test_invalid_nonce ___________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3RrZXkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL25jaS1jcmRjLmRhdGFjb21tb25zLmlvLyIsIm...jr49nakOD5T6HCFhyWWNwXCv93uOiAJtWOTazuQZqlzlWkP5genhVLKngTmAhxl3_im6YKioKM2K1VqVSAJNcJ8FL0XkblNvwhCrhdlED15ZfZ5-LkGR8g' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {'verify_at_hash': False}, audience = 'a-key' issuer = 'https://nci-crdc.datacommons.io/', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433019, ...} audience = 'a-key', issuer = 'https://nci-crdc.datacommons.io/', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433019, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_nonce(self): > self.authtoken_raised( 'Token error: Incorrect id_token: nonce', nonce='something-wrong', kid='testkey', ) social_core/tests/backends/test_open_id_connect.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: nonce" does not match "Token error: Signature has expired" ________________ GlobusOpenIdConnectTest.test_invalid_audience _________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2F1dGguZ2xvYnVzLm9yZyIsIm5vbmNlIjoiSUo4eE1KR...XUT6oGy5GNTUqu32wCD4om_CdWfE22NyO900GX2wg2ZnpNRycuxAhPZ-dSosVSZRWrLu2fgqweGTRe5lpahC6okKAR0ZVRRuD4eGdfbTdVvOnuXrSV47Fw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256', 'RS512'], options = {}, audience = 'a-key' issuer = 'https://auth.globus.org', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706433373, ...} audience = 'a-key', issuer = 'https://auth.globus.org', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706433373, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_audience(self): > self.authtoken_raised('Token error: Invalid audience', client_key='someone-else') social_core/tests/backends/test_open_id_connect.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid audience" does not match "Token error: Signature has expired" _______________ GlobusOpenIdConnectTest.test_invalid_issue_time ________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2F1dGguZ2xvYnVzLm9yZyIsIm5vbmNlIjoiUzdRakV3N...sZmbh_7-wqaQEijUzd6RRl8JNoERnUaSkr5aTeeqseAzKng3ryALds5WF3lPi7kFHtCm8ML90t6pXJJxR3oqXDEW7ChucSiGNCnUOpYahTzxQXh95JlZQg' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256', 'RS512'], options = {}, audience = 'a-key' issuer = 'https://auth.globus.org', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433436, ...} audience = 'a-key', issuer = 'https://auth.globus.org', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433436, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issue_time(self): expiration_datetime = datetime.datetime.utcnow() - \ datetime.timedelta(hours=1) > self.authtoken_raised('Token error: Incorrect id_token: iat', issue_datetime=expiration_datetime) social_core/tests/backends/test_open_id_connect.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: iat" does not match "Token error: Signature has expired" _________________ GlobusOpenIdConnectTest.test_invalid_issuer __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IjJjRHQ4Y05sek0xdFI0cGhOR...5s6cHEe1OI6jKBCUOVetrtR1MgyReRq9085t-3vWPQwUBuUD8EllVykD9bjdUIwqZbjmwQrD0g4eKG7q0JGS_PAVxbdbHJmJAjXxj20t9TLRKuCj740g3w' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256', 'RS512'], options = {}, audience = 'a-key' issuer = 'https://auth.globus.org', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433498, ...} audience = 'a-key', issuer = 'https://auth.globus.org', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433498, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issuer(self): > self.authtoken_raised('Token error: Invalid issuer', issuer='someone-else') social_core/tests/backends/test_open_id_connect.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid issuer" does not match "Token error: Signature has expired" __________________ GlobusOpenIdConnectTest.test_invalid_nonce __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3RrZXkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGguZ2xvYnVzLm9yZyIsIm5vbmNlIjoic2...SycN_xqqF2ywq-_hKh7TP4LUaHPPWpqWbiYDkBskGs_GNfERGXsL1_xJqFDe6wPMC_PKXlLOdRfJdQQH-drqZOGkFrKNQpODxxze_MZzNTu4xKIV2pFdFQ' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256', 'RS512'], options = {}, audience = 'a-key' issuer = 'https://auth.globus.org', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433617, ...} audience = 'a-key', issuer = 'https://auth.globus.org', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433617, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_nonce(self): > self.authtoken_raised( 'Token error: Incorrect id_token: nonce', nonce='something-wrong', kid='testkey', ) social_core/tests/backends/test_open_id_connect.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: nonce" does not match "Token error: Signature has expired" ________________ GoogleOpenIdConnectTest.test_invalid_audience _________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwibm9uY2UiOiJ2S1BXMWgxTHFrM...LRq5OqJHPSGPapEN7YZKFFhV1ftQuEM8gdnDJuj3aDg4a_lRf9BXKCbH-5q5rrmsZXr5_i4lafUQwuINnGj_K7nUdfZhgYQNllVYWdC3x1vJyqRrBhx8WQ' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'accounts.google.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706433830, ...} audience = 'a-key', issuer = 'accounts.google.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706433830, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_audience(self): > self.authtoken_raised('Token error: Invalid audience', client_key='someone-else') social_core/tests/backends/test_open_id_connect.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid audience" does not match "Token error: Signature has expired" _______________ GoogleOpenIdConnectTest.test_invalid_issue_time ________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwibm9uY2UiOiJyOEdiNTJqSlNaN...IqE3fRjFXmh58L9IYIn9udpwcCr3aiOwZ4TBUVMsh_VCQrmPNo4LZRaL4O4rDQdIjRNyiCJmgUmEhOk-8DVqTEJE-yxXiBKpWvGkdd2kGjOjtO1R_wHFeg' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'accounts.google.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433885, ...} audience = 'a-key', issuer = 'accounts.google.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433885, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issue_time(self): expiration_datetime = datetime.datetime.utcnow() - \ datetime.timedelta(hours=1) > self.authtoken_raised('Token error: Incorrect id_token: iat', issue_datetime=expiration_datetime) social_core/tests/backends/test_open_id_connect.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: iat" does not match "Token error: Signature has expired" _________________ GoogleOpenIdConnectTest.test_invalid_issuer __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6InZLMWRxZEc1bjl6MXJTTGpkM...dpFL_oyGoD1e2qNH7AFkz2EggyrAxvOP5Qop0485PrksdhHX9-qbqwStq_oANfO36grxQ3IFQMukwrr898PIz1NLJEse-pYKB45VHy3wkWxF1Y3uN2eeNA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'accounts.google.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433948, ...} audience = 'a-key', issuer = 'accounts.google.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706433948, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issuer(self): > self.authtoken_raised('Token error: Invalid issuer', issuer='someone-else') social_core/tests/backends/test_open_id_connect.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid issuer" does not match "Token error: Signature has expired" __________________ GoogleOpenIdConnectTest.test_invalid_nonce __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3RrZXkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwibm9uY2UiOiJzb21ldG...hKXQEnPcWhHyMNqD1GxFv7Alp2-mGWtW-hxd3SU4nhkU4E_LM3GtqfLpC8M_BAh-_gsfI0cEiMXU2tDdrAcklzPbtXMCzDpb8awXYuFag31ok1vtjhev_w' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'accounts.google.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434053, ...} audience = 'a-key', issuer = 'accounts.google.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434053, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_nonce(self): > self.authtoken_raised( 'Token error: Incorrect id_token: nonce', nonce='something-wrong', kid='testkey', ) social_core/tests/backends/test_open_id_connect.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: nonce" does not match "Token error: Signature has expired" _________________ OktaOpenIdConnectTest.test_everything_works __________________ self = id_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2Rldi0wMDAwMDAub2t0YXByZXZpZXcuY29tL29hdXRoM...1cO7FufK2kz3FZ-Qg3bHeiHfz8qyUWQbTmEXQSMHGZGD10PeyXoiBBhnaomqWUjg7SlH4XX1lwB13o7QQdN5vUkNor31ejrl2KlzbRWxPS0xkYbBnsAGHw' access_token = 'foobar' def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2Rldi0wMDAwMDAub2t0YXByZXZpZXcuY29tL29hdXRoM...1cO7FufK2kz3FZ-Qg3bHeiHfz8qyUWQbTmEXQSMHGZGD10PeyXoiBBhnaomqWUjg7SlH4XX1lwB13o7QQdN5vUkNor31ejrl2KlzbRWxPS0xkYbBnsAGHw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://dev-000000.oktapreview.com/oauth2', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434385, ...} audience = 'a-key', issuer = 'https://dev-000000.oktapreview.com/oauth2' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434385, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: self = def test_everything_works(self): > self.do_login() social_core/tests/backends/test_okta.py:161: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/base.py:63: in do_login user = self.do_start() social_core/tests/backends/oauth.py:86: in do_start return self.backend.complete() social_core/backends/base.py:40: in complete return self.auth_complete(*args, **kwargs) social_core/utils.py:247: in wrapper return func(*args, **kwargs) social_core/backends/oauth.py:392: in auth_complete response = self.request_access_token( social_core/backends/open_id_connect.py:232: in request_access_token self.id_token = self.validate_and_return_id_token( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = id_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2Rldi0wMDAwMDAub2t0YXByZXZpZXcuY29tL29hdXRoM...1cO7FufK2kz3FZ-Qg3bHeiHfz8qyUWQbTmEXQSMHGZGD10PeyXoiBBhnaomqWUjg7SlH4XX1lwB13o7QQdN5vUkNor31ejrl2KlzbRWxPS0xkYbBnsAGHw' access_token = 'foobar' def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) except ExpiredSignatureError: > raise AuthTokenError(self, 'Signature has expired') E social_core.exceptions.AuthTokenError: Token error: Signature has expired social_core/backends/open_id_connect.py:216: AuthTokenError _________________ OktaOpenIdConnectTest.test_invalid_audience __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2Rldi0wMDAwMDAub2t0YXByZXZpZXcuY29tL29hdXRoM...wR1EkmI1DNcHkoagBV-sGNT2Tz35KzbrryFd7fDK1j_8iZbsJXMzIXC-dDT_O2u44y1c8q9hGc5hfKFMV97MMQEwR-xZ3uTfChzjKM1uVbMIXI2QD4IS8w' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://dev-000000.oktapreview.com/oauth2', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706434502, ...} audience = 'a-key', issuer = 'https://dev-000000.oktapreview.com/oauth2' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706434502, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_audience(self): > self.authtoken_raised('Token error: Invalid audience', client_key='someone-else') social_core/tests/backends/test_open_id_connect.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid audience" does not match "Token error: Signature has expired" ________________ OktaOpenIdConnectTest.test_invalid_issue_time _________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2Rldi0wMDAwMDAub2t0YXByZXZpZXcuY29tL29hdXRoM...Ao2B0O6gzqdlkegMaZxidYnKHNsjalwKIJrIFfDeQIJc_tYu9ovUqpQeHwTK8zLyRJ22RCjkdhMnp8BYEUa_qt9F_BIoAfzI7rA1NeLeiRQvArxGmL7P0Q' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://dev-000000.oktapreview.com/oauth2', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434561, ...} audience = 'a-key', issuer = 'https://dev-000000.oktapreview.com/oauth2' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434561, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issue_time(self): expiration_datetime = datetime.datetime.utcnow() - \ datetime.timedelta(hours=1) > self.authtoken_raised('Token error: Incorrect id_token: iat', issue_datetime=expiration_datetime) social_core/tests/backends/test_open_id_connect.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: iat" does not match "Token error: Signature has expired" __________________ OktaOpenIdConnectTest.test_invalid_issuer ___________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6InYyVjhlYldNRUJ2cXcxNGdsM...RxKnCGw6bnoENfWa-Jo9F-8MdNPNyv3gG4uOXo8KwqtnnbdyRbz68sBHAMkw5JlEooO9d-GcXNzelvi5LT3hPIT7E5uLzTcuCa535aU3FqbtpKT8tZIAsA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://dev-000000.oktapreview.com/oauth2', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434626, ...} audience = 'a-key', issuer = 'https://dev-000000.oktapreview.com/oauth2' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434626, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issuer(self): > self.authtoken_raised('Token error: Invalid issuer', issuer='someone-else') social_core/tests/backends/test_open_id_connect.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid issuer" does not match "Token error: Signature has expired" ___________________ OktaOpenIdConnectTest.test_invalid_nonce ___________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3RrZXkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2Rldi0wMDAwMDAub2t0YXByZXZpZXcuY29tL2...48rzb8q3pTRKThaAwv7uCemfkcTY8qnQGl2mwmT9eDu9SLhDwW74FrOanodaKqi2EFf5eQlOva5BICEJJMB5og8qLZDudEIWVWa_zq1M2HTn5uj19RkIug' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://dev-000000.oktapreview.com/oauth2', subject = None access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434747, ...} audience = 'a-key', issuer = 'https://dev-000000.oktapreview.com/oauth2' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434747, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_nonce(self): > self.authtoken_raised( 'Token error: Incorrect id_token: nonce', nonce='something-wrong', kid='testkey', ) social_core/tests/backends/test_open_id_connect.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: nonce" does not match "Token error: Signature has expired" _________________ BaseOpenIdConnectTest.test_everything_works __________________ self = id_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJ4M2VsVXZLSm04W...zb_mMS85ObJ9pq72wR0EJKlYJzV_aqs3b2xbBwUyrXVhL3ziTi91ejniLlMdTOi21VJ-eJ49zvBFC5DT7Djp25aHSH8KpLk_qtSjG4m4AjGTy5RmYKMGiQ' access_token = 'foobar' def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJ4M2VsVXZLSm04W...zb_mMS85ObJ9pq72wR0EJKlYJzV_aqs3b2xbBwUyrXVhL3ziTi91ejniLlMdTOi21VJ-eJ49zvBFC5DT7Djp25aHSH8KpLk_qtSjG4m4AjGTy5RmYKMGiQ' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434862, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706434862, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: self = def test_everything_works(self): > self.do_login() social_core/tests/backends/test_open_id_connect.py:238: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/base.py:63: in do_login user = self.do_start() social_core/tests/backends/oauth.py:86: in do_start return self.backend.complete() social_core/backends/base.py:40: in complete return self.auth_complete(*args, **kwargs) social_core/utils.py:247: in wrapper return func(*args, **kwargs) social_core/backends/oauth.py:392: in auth_complete response = self.request_access_token( social_core/backends/open_id_connect.py:232: in request_access_token self.id_token = self.validate_and_return_id_token( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = id_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJ4M2VsVXZLSm04W...zb_mMS85ObJ9pq72wR0EJKlYJzV_aqs3b2xbBwUyrXVhL3ziTi91ejniLlMdTOi21VJ-eJ49zvBFC5DT7Djp25aHSH8KpLk_qtSjG4m4AjGTy5RmYKMGiQ' access_token = 'foobar' def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) except ExpiredSignatureError: > raise AuthTokenError(self, 'Signature has expired') E social_core.exceptions.AuthTokenError: Token error: Signature has expired social_core/backends/open_id_connect.py:216: AuthTokenError _________________ BaseOpenIdConnectTest.test_invalid_audience __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJ5Y01NY2ZyMTBhN...7UY7QLb-9wtxvSl1s5ieVTtQKGU6hAtgfjQUIFt_9wOW5AIyWQik5wd7okrVRGHSu4USyy3xuCf-J7y3w7ugCRD-NNafXnAFb9T-YgYef-Ru8VwXEDN8Zw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706434977, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706434977, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_audience(self): > self.authtoken_raised('Token error: Invalid audience', client_key='someone-else') social_core/tests/backends/test_open_id_connect.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid audience" does not match "Token error: Signature has expired" ________________ BaseOpenIdConnectTest.test_invalid_issue_time _________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiI0cWd4YXFGNDJST...dAndm71TBoAWEBkFyplRbbzbtmPEQqjdl1gnVDd4dEfFti2urW1a7Erk8cje91MxLXH0M2GJuMTd0LUwPPV09EuZv9s3x2hItenbiuiBu6SJwSCv8tM8RA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435038, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435038, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issue_time(self): expiration_datetime = datetime.datetime.utcnow() - \ datetime.timedelta(hours=1) > self.authtoken_raised('Token error: Incorrect id_token: iat', issue_datetime=expiration_datetime) social_core/tests/backends/test_open_id_connect.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: iat" does not match "Token error: Signature has expired" __________________ BaseOpenIdConnectTest.test_invalid_issuer ___________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6Im9INmh0ZEhpQXlWTDR4MTRSS...6UWrT3b0MEVA0DauVBAzxaD1JOMIWMVommOpglMKSHmsHOBTq44DymnUYPlP-Ay7jeqcQd3-6tfFZVDMzhX6DsmfOb_pmHKwapB7ITZ5DzJLM9cz88VPOA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435096, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435096, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issuer(self): > self.authtoken_raised('Token error: Invalid issuer', issuer='someone-else') social_core/tests/backends/test_open_id_connect.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid issuer" does not match "Token error: Signature has expired" ___________________ BaseOpenIdConnectTest.test_invalid_nonce ___________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3RrZXkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJzb21ldG...vNutoWgwVr8P-sC279iBd53OD-Wseb6nbDAsVlfpUkpyl_71INr9H5Xua2WoXmG9n3_H5b_-aRzk7IFM2OtceRnLG9oRS9EDlywD31P4p6u4MoNOqM2_5Q' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435205, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435205, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_nonce(self): > self.authtoken_raised( 'Token error: Incorrect id_token: nonce', nonce='something-wrong', kid='testkey', ) social_core/tests/backends/test_open_id_connect.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: nonce" does not match "Token error: Signature has expired" ________________ ExampleOpenIdConnectTest.test_everything_works ________________ self = id_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJubGVHRVhGano1U...6HxQPxtYpyIrZQS_Ys4BK8M6Vq7wz2ZEwqG7NtKv7vq_X30O4jzlvBcK9p8tBy87hRNMGyPF9u8eiBuna8SszU5G2gHfAmLZmR_oN0hsZc1CgG-8Esx1wQ' access_token = 'foobar' def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJubGVHRVhGano1U...6HxQPxtYpyIrZQS_Ys4BK8M6Vq7wz2ZEwqG7NtKv7vq_X30O4jzlvBcK9p8tBy87hRNMGyPF9u8eiBuna8SszU5G2gHfAmLZmR_oN0hsZc1CgG-8Esx1wQ' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435321, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435321, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: self = def test_everything_works(self): > self.do_login() social_core/tests/backends/test_open_id_connect.py:270: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/base.py:63: in do_login user = self.do_start() social_core/tests/backends/oauth.py:86: in do_start return self.backend.complete() social_core/backends/base.py:40: in complete return self.auth_complete(*args, **kwargs) social_core/utils.py:247: in wrapper return func(*args, **kwargs) social_core/backends/oauth.py:392: in auth_complete response = self.request_access_token( social_core/backends/open_id_connect.py:232: in request_access_token self.id_token = self.validate_and_return_id_token( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = id_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJubGVHRVhGano1U...6HxQPxtYpyIrZQS_Ys4BK8M6Vq7wz2ZEwqG7NtKv7vq_X30O4jzlvBcK9p8tBy87hRNMGyPF9u8eiBuna8SszU5G2gHfAmLZmR_oN0hsZc1CgG-8Esx1wQ' access_token = 'foobar' def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) except ExpiredSignatureError: > raise AuthTokenError(self, 'Signature has expired') E social_core.exceptions.AuthTokenError: Token error: Signature has expired social_core/backends/open_id_connect.py:216: AuthTokenError ________________ ExampleOpenIdConnectTest.test_invalid_audience ________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJwcmlJd2xuWTdud...NwDUlHckx0tS5HoBKq8SEko_JWnDsjV21Ex9EPsHCcFrinGJBj2N04xMnPH7My3MICTF-Cb8PwY_3nzNeesAYUCYRyLc6u2zKcq0JqqYyiZpRFVS9S8_tA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706435439, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706435439, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_audience(self): > self.authtoken_raised('Token error: Invalid audience', client_key='someone-else') social_core/tests/backends/test_open_id_connect.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid audience" does not match "Token error: Signature has expired" _______________ ExampleOpenIdConnectTest.test_invalid_issue_time _______________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJzRUV1R3lGbTBXS...ZTfRyi_Jf_o_a04Jqrue-QtglM4C7iQ0x2bWuLXJLHV2bVCJ_49rLvE11VY22or54N5jIHQR52eCoHL0ejSP86NCbJED1V5WqDLAgPfS2vlS-15hqzg_Hw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435503, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435503, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issue_time(self): expiration_datetime = datetime.datetime.utcnow() - \ datetime.timedelta(hours=1) > self.authtoken_raised('Token error: Incorrect id_token: iat', issue_datetime=expiration_datetime) social_core/tests/backends/test_open_id_connect.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: iat" does not match "Token error: Signature has expired" _________________ ExampleOpenIdConnectTest.test_invalid_issuer _________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6ImVHWkNPNnhSdTlWVnRFQWN1N...9v_z0TxjFpjBTDN3zeiCLhqwXWQbr6dYyRGhv8BJlsTYRhdqOXtGRlkpDAbfvDcgs5sRVUXqVrssZE6FNwPLDnA32nLIZx63AFTFZf6mCuLv2XDRfdohPw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435563, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435563, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issuer(self): > self.authtoken_raised('Token error: Invalid issuer', issuer='someone-else') social_core/tests/backends/test_open_id_connect.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid issuer" does not match "Token error: Signature has expired" _________________ ExampleOpenIdConnectTest.test_invalid_nonce __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3RrZXkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJzb21ldG...ah5Hn4J7Ix33vzs-ayV5NHf-SNbTOBkNic9eYJhDSL1H0h_u_NO4eiOw9uh-yZJ2UzW-3zVrl5SJwKzaFeHtVzKt-vTeOVULvpD34tPsk7mPh8ZM6sUJrw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://example.com', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435679, ...} audience = 'a-key', issuer = 'https://example.com', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706435679, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_nonce(self): > self.authtoken_raised( 'Token error: Incorrect id_token: nonce', nonce='something-wrong', kid='testkey', ) social_core/tests/backends/test_open_id_connect.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: nonce" does not match "Token error: Signature has expired" __________________________ SteamOpenIdTest.test_login __________________________ self = def test_login(self): self._login_setup() > self.do_login() social_core/tests/backends/test_steam.py:100: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/base.py:63: in do_login user = self.do_start() social_core/tests/backends/open_id.py:103: in do_start return self.backend.complete() social_core/backends/base.py:40: in complete return self.auth_complete(*args, **kwargs) social_core/backends/open_id.py:166: in auth_complete self.process_error(response) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = data = def process_error(self, data): if not data: raise AuthException(self, 'OpenID relying party endpoint') elif data.status == FAILURE: > raise AuthFailed(self, data.message) E social_core.exceptions.AuthFailed: Authentication failed: Server denied check_authentication social_core/backends/open_id.py:174: AuthFailed ------------------------------ Captured log call ------------------------------- ERROR root:consumer.py:1118 check_authentication failed: 0.1 Traceback (most recent call last): File "/usr/lib/python3.12/site-packages/openid/fetchers.py", line 231, in fetch url_resource = self.urlopen(req) ^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/urllib/request.py", line 215, in urlopen return opener.open(url, data, timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/urllib/request.py", line 515, in open response = self._open(req, data) ^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/urllib/request.py", line 532, in _open result = self._call_chain(self.handle_open, protocol, protocol + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/urllib/request.py", line 492, in _call_chain result = func(*args) ^^^^^^^^^^^ File "/usr/lib64/python3.12/urllib/request.py", line 1392, in https_open return self.do_open(http.client.HTTPSConnection, req, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/urllib/request.py", line 1348, in do_open r = h.getresponse() ^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/http/client.py", line 1407, in getresponse response = self.response_class(self.sock, method=self._method) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/http/client.py", line 262, in __init__ self.fp = sock.makefile("rb") ^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/httpretty/core.py", line 709, in makefile raise socket.timeout(timeout) TimeoutError: 0.1 During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.12/site-packages/openid/fetchers.py", line 194, in fetch return self.fetcher.fetch(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/openid/fetchers.py", line 241, in fetch raise AssertionError(why) AssertionError: 0.1 During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.12/site-packages/openid/consumer/consumer.py", line 1115, in _checkAuth response = self._makeKVPost(request, server_url) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/openid/consumer/consumer.py", line 233, in makeKVPost resp = fetchers.fetch(server_url, body=request_message.toURLEncoded()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/openid/fetchers.py", line 49, in fetch return fetcher.fetch(url, body, headers) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/openid/fetchers.py", line 203, in fetch raise HTTPFetchingError(why=exc_inst) openid.fetchers.HTTPFetchingError: 0.1 ___________________ SteamOpenIdMissingSteamIdTest.test_login ___________________ self = url = 'https://steamcommunity.com/openid', body = None headers = {'Accept': 'text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml', 'User-Agent': 'python-openid/3.1.0 (linux) Python-urllib/3.12'} def fetch(self, url, body=None, headers=None): if not _allowedURL(url): raise ValueError('Bad URL scheme: %r' % (url, )) if headers is None: headers = {} headers.setdefault('User-Agent', "%s Python-urllib/%s" % (USER_AGENT, urllib.request.__version__)) if isinstance(body, str): body = bytes(body, encoding="utf-8") req = urllib.request.Request(url, data=body, headers=headers) url_resource = None try: > url_resource = self.urlopen(req) /usr/lib/python3.12/site-packages/openid/fetchers.py:231: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = , data = None timeout = def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, *, cafile=None, capath=None, cadefault=False, context=None): '''Open the URL url, which can be either a string or a Request object. *data* must be an object specifying additional data to be sent to the server, or None if no such data is needed. See Request for details. urllib.request module uses HTTP/1.1 and includes a "Connection:close" header in its HTTP requests. The optional *timeout* parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout setting will be used). This only works for HTTP, HTTPS and FTP connections. If *context* is specified, it must be a ssl.SSLContext instance describing the various SSL options. See HTTPSConnection for more details. The optional *cafile* and *capath* parameters specify a set of trusted CA certificates for HTTPS requests. cafile should point to a single file containing a bundle of CA certificates, whereas capath should point to a directory of hashed certificate files. More information can be found in ssl.SSLContext.load_verify_locations(). The *cadefault* parameter is ignored. This function always returns an object which can work as a context manager and has the properties url, headers, and status. See urllib.response.addinfourl for more detail on these properties. For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse object slightly modified. In addition to the three new methods above, the msg attribute contains the same information as the reason attribute --- the reason phrase returned by the server --- instead of the response headers as it is specified in the documentation for HTTPResponse. For FTP, file, and data URLs and requests explicitly handled by legacy URLopener and FancyURLopener classes, this function returns a urllib.response.addinfourl object. Note that None may be returned if no handler handles the request (though the default installed global OpenerDirector uses UnknownHandler to ensure this never happens). In addition, if proxy settings are detected (for example, when a *_proxy environment variable like http_proxy is set), ProxyHandler is default installed and makes sure the requests are handled through the proxy. ''' global _opener if cafile or capath or cadefault: import warnings warnings.warn("cafile, capath and cadefault are deprecated, use a " "custom context instead.", DeprecationWarning, 2) if context is not None: raise ValueError( "You can't pass both context and any of cafile, capath, and " "cadefault" ) if not _have_ssl: raise ValueError('SSL support not available') context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=cafile, capath=capath) # send ALPN extension to indicate HTTP/1.1 protocol context.set_alpn_protocols(['http/1.1']) https_handler = HTTPSHandler(context=context) opener = build_opener(https_handler) elif context: https_handler = HTTPSHandler(context=context) opener = build_opener(https_handler) elif _opener is None: _opener = opener = build_opener() else: opener = _opener > return opener.open(url, data, timeout) /usr/lib64/python3.12/urllib/request.py:215: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = fullurl = , data = None timeout = def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): # accept a URL or a Request object if isinstance(fullurl, str): req = Request(fullurl, data) else: req = fullurl if data is not None: req.data = data req.timeout = timeout protocol = req.type # pre-process request meth_name = protocol+"_request" for processor in self.process_request.get(protocol, []): meth = getattr(processor, meth_name) req = meth(req) sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method()) > response = self._open(req, data) /usr/lib64/python3.12/urllib/request.py:515: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = req = , data = None def _open(self, req, data=None): result = self._call_chain(self.handle_open, 'default', 'default_open', req) if result: return result protocol = req.type > result = self._call_chain(self.handle_open, protocol, protocol + '_open', req) /usr/lib64/python3.12/urllib/request.py:532: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = chain = {'data': [], 'file': [], 'http': [], ...} kind = 'https', meth_name = 'https_open' args = (,) handlers = [] handler = func = > def _call_chain(self, chain, kind, meth_name, *args): # Handlers raise an exception if no one else should try to handle # the request, or return None if they can't but another handler # could. Otherwise, they return the response. handlers = chain.get(kind, ()) for handler in handlers: func = getattr(handler, meth_name) > result = func(*args) /usr/lib64/python3.12/urllib/request.py:492: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = req = def https_open(self, req): > return self.do_open(http.client.HTTPSConnection, req, context=self._context) /usr/lib64/python3.12/urllib/request.py:1392: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = http_class = req = http_conn_args = {'context': } host = 'steamcommunity.com' h = headers = {'Accept': 'text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml', 'Connection': 'close', 'Host': 'steamcommunity.com', 'User-Agent': 'python-openid/3.1.0 (linux) Python-urllib/3.12'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) except OSError as err: # timeout error raise URLError(err) > r = h.getresponse() /usr/lib64/python3.12/urllib/request.py:1348: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def getresponse(self): """Get the response from the server. If the HTTPConnection is in the correct state, returns an instance of HTTPResponse or of whatever object is returned by the response_class variable. If a request has not been sent or if a previous response has not be handled, ResponseNotReady is raised. If the HTTP response indicates that the connection should be closed, then it will be closed before the response is returned. When the connection is closed, the underlying socket is closed. """ # if a prior response has been completed, then forget about it. if self.__response and self.__response.isclosed(): self.__response = None # if a prior response exists, then it must be completed (otherwise, we # cannot read this response's header to determine the connection-close # behavior) # # note: if a prior response existed, but was connection-close, then the # socket and response were made independent of this HTTPConnection # object since a new request requires that we open a whole new # connection # # this means the prior response had one of two states: # 1) will_close: this connection was reset and the prior socket and # response operate independently # 2) persistent: the response was retained and we await its # isclosed() status to become true. # if self.__state != _CS_REQ_SENT or self.__response: raise ResponseNotReady(self.__state) if self.debuglevel > 0: response = self.response_class(self.sock, self.debuglevel, method=self._method) else: > response = self.response_class(self.sock, method=self._method) /usr/lib64/python3.12/http/client.py:1407: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = sock = httpretty.core.socket("steamcommunity.com:443"), debuglevel = 0 method = 'GET', url = None def __init__(self, sock, debuglevel=0, method=None, url=None): # If the response includes a content-length header, we need to # make sure that the client doesn't read more than the # specified number of bytes. If it does, it will block until # the server times out and closes the connection. This will # happen if a self.fp.read() is done (without a size) whether # self.fp is buffered or not. So, no self.fp.read() by # clients unless they know what they are doing. > self.fp = sock.makefile("rb") /usr/lib64/python3.12/http/client.py:262: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = httpretty.core.socket("steamcommunity.com:443"), mode = 'rb' bufsize = -1 def makefile(self, mode='r', bufsize=-1): """Returns this fake socket's own tempfile buffer. If there is an entry associated with the socket, the file descriptor gets filled in with the entry data before being returned. """ self._mode = mode self._bufsize = bufsize if self._entry: t = __internals__.create_thread( target=self._entry.fill_filekind, args=(self.fd,) ) # execute body callback and send http response in a # thread, wait for thread to finish within the timeout # set via socket.settimeout() t.start() if self.timeout == SOCKET_GLOBAL_DEFAULT_TIMEOUT: timeout = get_default_thread_timeout() else: timeout = self.timeout # fake socket timeout error by checking if the thread # finished in time. t.join(timeout) if t.is_alive(): # For more info check issue https://github.com/gabrielfalcao/HTTPretty/issues/430 > raise socket.timeout(timeout) E TimeoutError: 0.1 /usr/lib/python3.12/site-packages/httpretty/core.py:709: TimeoutError During handling of the above exception, another exception occurred: self = args = ('https://steamcommunity.com/openid', None, {'Accept': 'text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml', 'User-Agent': 'python-openid/3.1.0 (linux) Python-urllib/3.12'}) kwargs = {}, exc_cls = exc_inst = AssertionError(TimeoutError(0.1)) def fetch(self, *args, **kwargs): try: > return self.fetcher.fetch(*args, **kwargs) /usr/lib/python3.12/site-packages/openid/fetchers.py:194: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = url = 'https://steamcommunity.com/openid', body = None headers = {'Accept': 'text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml', 'User-Agent': 'python-openid/3.1.0 (linux) Python-urllib/3.12'} def fetch(self, url, body=None, headers=None): if not _allowedURL(url): raise ValueError('Bad URL scheme: %r' % (url, )) if headers is None: headers = {} headers.setdefault('User-Agent', "%s Python-urllib/%s" % (USER_AGENT, urllib.request.__version__)) if isinstance(body, str): body = bytes(body, encoding="utf-8") req = urllib.request.Request(url, data=body, headers=headers) url_resource = None try: url_resource = self.urlopen(req) with contextlib.closing(url_resource): return self._makeResponse(url_resource) except urllib.error.HTTPError as why: with contextlib.closing(why): resp = self._makeResponse(why) return resp except (urllib.error.URLError, http.client.BadStatusLine) as why: raise except Exception as why: > raise AssertionError(why) E AssertionError: 0.1 /usr/lib/python3.12/site-packages/openid/fetchers.py:241: AssertionError During handling of the above exception, another exception occurred: self = user_url = 'https://steamcommunity.com/openid', anonymous = False def begin(self, user_url, anonymous=False): """Start the OpenID authentication process. See steps 1-2 in the overview at the top of this file. @param user_url: Identity URL given by the user. This method performs a textual transformation of the URL to try and make sure it is normalized. For example, a user_url of example.com will be normalized to http://example.com/ normalizing and resolving any redirects the server might issue. @type user_url: unicode @param anonymous: Whether to make an anonymous request of the OpenID provider. Such a request does not ask for an authorization assertion for an OpenID identifier, but may be used with extensions to pass other data. e.g. "I don't care who you are, but I'd like to know your time zone." @type anonymous: bool @returns: An object containing the discovered information will be returned, with a method for building a redirect URL to the server, as described in step 3 of the overview. This object may also be used to add extension arguments to the request, using its L{addExtensionArg} method. @returntype: L{AuthRequest} @raises openid.consumer.discover.DiscoveryFailure: when I fail to find an OpenID server for this URL. If the C{yadis} package is available, L{openid.consumer.discover.DiscoveryFailure} is an alias for C{yadis.discover.DiscoveryFailure}. """ disco = Discovery(self.session, user_url, self.session_key_prefix) try: > service = disco.getNextService(self._discover) /usr/lib/python3.12/site-packages/openid/consumer/consumer.py:350: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = discover = def getNextService(self, discover): """Return the next authentication service for the pair of user_input and session. This function handles fallback. @param discover: a callable that takes a URL and returns a list of services @type discover: str -> [service] @return: the next available service """ manager = self.getManager() if manager is not None and not manager: self.destroyManager() if not manager: > yadis_url, services = discover(self.url) /usr/lib/python3.12/site-packages/openid/yadis/manager.py:106: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ identifier = 'https://steamcommunity.com/openid' def discover(identifier): if xri.identifierScheme(identifier) == "XRI": return discoverXRI(identifier) else: > return discoverURI(identifier) /usr/lib/python3.12/site-packages/openid/consumer/discover.py:465: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ uri = 'https://steamcommunity.com/openid' def discoverURI(uri): parsed = urllib.parse.urlparse(uri) if parsed[0] and parsed[1]: if parsed[0] not in ['http', 'https']: raise DiscoveryFailure('URI scheme is not HTTP or HTTPS', None) else: uri = 'http://' + uri uri = normalizeURL(uri) > claimed_id, openid_services = discoverYadis(uri) /usr/lib/python3.12/site-packages/openid/consumer/discover.py:456: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ uri = 'https://steamcommunity.com/openid' def discoverYadis(uri): """Discover OpenID services for a URI. Tries Yadis and falls back on old-style discovery if Yadis fails. @param uri: normalized identity URL @type uri: str @return: (claimed_id, services) @rtype: (str, list(OpenIDServiceEndpoint)) @raises DiscoveryFailure: when discovery fails. """ # Might raise a yadis.discover.DiscoveryFailure if no document # came back for that URI at all. I don't think falling back # to OpenID 1.0 discovery on the same URL will help, so don't # bother to catch it. > response = yadisDiscover(uri) /usr/lib/python3.12/site-packages/openid/consumer/discover.py:381: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ uri = 'https://steamcommunity.com/openid' def discover(uri): """Discover services for a given URI. @param uri: The identity URI as a well-formed http or https URI. The well-formedness and the protocol are not checked, but the results of this function are undefined if those properties do not hold. @return: DiscoveryResult object @raises Exception: Any exception that can be raised by fetching a URL with the given fetcher. @raises DiscoveryFailure: When the HTTP response does not have a 200 code. """ result = DiscoveryResult(uri) > resp = fetchers.fetch(uri, headers={'Accept': YADIS_ACCEPT_HEADER}) /usr/lib/python3.12/site-packages/openid/yadis/discover.py:75: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ url = 'https://steamcommunity.com/openid', body = None headers = {'Accept': 'text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml', 'User-Agent': 'python-openid/3.1.0 (linux) Python-urllib/3.12'} def fetch(url, body=None, headers=None): """Invoke the fetch method on the default fetcher. Most users should need only this method. @raises Exception: any exceptions that may be raised by the default fetcher """ fetcher = getDefaultFetcher() > return fetcher.fetch(url, body, headers) /usr/lib/python3.12/site-packages/openid/fetchers.py:49: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = args = ('https://steamcommunity.com/openid', None, {'Accept': 'text/html; q=0.3, application/xhtml+xml; q=0.5, application/xrds+xml', 'User-Agent': 'python-openid/3.1.0 (linux) Python-urllib/3.12'}) kwargs = {}, exc_cls = exc_inst = AssertionError(TimeoutError(0.1)) def fetch(self, *args, **kwargs): try: return self.fetcher.fetch(*args, **kwargs) except self.uncaught_exceptions: raise except: exc_cls, exc_inst = sys.exc_info()[:2] if exc_inst is None: # string exceptions exc_inst = exc_cls > raise HTTPFetchingError(why=exc_inst) E openid.fetchers.HTTPFetchingError: 0.1 /usr/lib/python3.12/site-packages/openid/fetchers.py:203: HTTPFetchingError During handling of the above exception, another exception occurred: def openid_request(self, params=None): """Return openid request""" try: > return self.consumer().begin(url_add_parameters(self.openid_url(), params)) social_core/backends/open_id.py:238: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = user_url = 'https://steamcommunity.com/openid', anonymous = False def begin(self, user_url, anonymous=False): """Start the OpenID authentication process. See steps 1-2 in the overview at the top of this file. @param user_url: Identity URL given by the user. This method performs a textual transformation of the URL to try and make sure it is normalized. For example, a user_url of example.com will be normalized to http://example.com/ normalizing and resolving any redirects the server might issue. @type user_url: unicode @param anonymous: Whether to make an anonymous request of the OpenID provider. Such a request does not ask for an authorization assertion for an OpenID identifier, but may be used with extensions to pass other data. e.g. "I don't care who you are, but I'd like to know your time zone." @type anonymous: bool @returns: An object containing the discovered information will be returned, with a method for building a redirect URL to the server, as described in step 3 of the overview. This object may also be used to add extension arguments to the request, using its L{addExtensionArg} method. @returntype: L{AuthRequest} @raises openid.consumer.discover.DiscoveryFailure: when I fail to find an OpenID server for this URL. If the C{yadis} package is available, L{openid.consumer.discover.DiscoveryFailure} is an alias for C{yadis.discover.DiscoveryFailure}. """ disco = Discovery(self.session, user_url, self.session_key_prefix) try: service = disco.getNextService(self._discover) except fetchers.HTTPFetchingError as why: > raise DiscoveryFailure('Error fetching XRDS document: %s' % (why.why, ), None) E openid.yadis.discover.DiscoveryFailure: Error fetching XRDS document: 0.1 /usr/lib/python3.12/site-packages/openid/consumer/consumer.py:352: DiscoveryFailure During handling of the above exception, another exception occurred: self = def test_login(self): self._login_setup(user_url='https://steamcommunity.com/openid/BROKEN') with self.assertRaises(AuthFailed): > self.do_login() social_core/tests/backends/test_steam.py:128: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/base.py:63: in do_login user = self.do_start() social_core/tests/backends/open_id.py:89: in do_start start = self.backend.start() social_core/backends/base.py:34: in start if self.uses_redirect(): social_core/backends/open_id.py:233: in uses_redirect return self.openid_request().shouldSendRedirect() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def openid_request(self, params=None): """Return openid request""" try: return self.consumer().begin(url_add_parameters(self.openid_url(), params)) except DiscoveryFailure as err: > raise AuthException(self, 'OpenID discovery error: {}'.format( err )) E social_core.exceptions.AuthException: OpenID discovery error: Error fetching XRDS document: 0.1 social_core/backends/open_id.py:241: AuthException ________________ TwitchOpenIdConnectTest.test_invalid_audience _________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2lkLnR3aXRjaC50di9vYXV0aDIiLCJub25jZSI6InRze...iTBWm1HaFz-QZ5sLzmgoRjhFjY6QFN9F3OqSdtbNJL0mdmZ8MceiXeKZ2-l3ew4FE3D9sXsBEpliwp8q6mSMT_ChBkRSjI8aoa_dOVldwLLUjfkcdUHVqA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://id.twitch.tv/oauth2', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706436212, ...} audience = 'a-key', issuer = 'https://id.twitch.tv/oauth2', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706436212, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_audience(self): > self.authtoken_raised('Token error: Invalid audience', client_key='someone-else') social_core/tests/backends/test_open_id_connect.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid audience" does not match "Token error: Signature has expired" _______________ TwitchOpenIdConnectTest.test_invalid_issue_time ________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2lkLnR3aXRjaC50di9vYXV0aDIiLCJub25jZSI6ImI3R...m3l3R3TOeJ-kBLU1-uyIU2WqvROi6ICG1LLthtQT1v6ohHjrXx7xq6rIuSXfZPyatMYhecniIv8aSgpOv7qRxA-P6pFjpMqVQ7OAEnKeoDNsArr9QonJiQ' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://id.twitch.tv/oauth2', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436276, ...} audience = 'a-key', issuer = 'https://id.twitch.tv/oauth2', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436276, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issue_time(self): expiration_datetime = datetime.datetime.utcnow() - \ datetime.timedelta(hours=1) > self.authtoken_raised('Token error: Incorrect id_token: iat', issue_datetime=expiration_datetime) social_core/tests/backends/test_open_id_connect.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: iat" does not match "Token error: Signature has expired" _________________ TwitchOpenIdConnectTest.test_invalid_issuer __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IjBzbzNVN2xmS254OGl4Q1RYc...g_cbewENXKams0Xweo3ipJIp0sgV05kd2yoBPS0xhtywCJViH_Nwt1zCYMcsUb_VckcUOxGXQDss63zW2cEi7Oe2_FEQiUcyp1kvlo2ZJY9-Gb5_K55evg' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://id.twitch.tv/oauth2', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436333, ...} audience = 'a-key', issuer = 'https://id.twitch.tv/oauth2', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436333, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issuer(self): > self.authtoken_raised('Token error: Invalid issuer', issuer='someone-else') social_core/tests/backends/test_open_id_connect.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid issuer" does not match "Token error: Signature has expired" __________________ TwitchOpenIdConnectTest.test_invalid_nonce __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3RrZXkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2lkLnR3aXRjaC50di9vYXV0aDIiLCJub25jZS...9tSvZCiPRbFy2AT10qm6EfRqSJkc0Nez6atgYgpwSsUbH0xLp2BT5yrDVLegN6fZJfqQACgEzXMSZ2pMpUjvBhCuln21ShheUHudVStuLI-AhEDk7DmVXA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://id.twitch.tv/oauth2', subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436457, ...} audience = 'a-key', issuer = 'https://id.twitch.tv/oauth2', subject = None algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436457, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_nonce(self): > self.authtoken_raised( 'Token error: Incorrect id_token: nonce', nonce='something-wrong', kid='testkey', ) social_core/tests/backends/test_open_id_connect.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: nonce" does not match "Token error: Signature has expired" _________________ VaultOpenIdConnectTest.test_everything_works _________________ self = id_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL3ZhdWx0LmV4YW1wbGUubmV0OjgyMDAvdjEvaWRlbnRpd...A4w1q8UVDwI1QdAxXPegh6srjVI9MxFjsSGdzZw3bXqjyly6Qn3n49UL5hrqxR6sbuyuJNFaNsJTyxd5gOebHZRB9aLIYrBL_blmcWnVWtCfkS09LqyUJw' access_token = 'foobar' def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL3ZhdWx0LmV4YW1wbGUubmV0OjgyMDAvdjEvaWRlbnRpd...A4w1q8UVDwI1QdAxXPegh6srjVI9MxFjsSGdzZw3bXqjyly6Qn3n49UL5hrqxR6sbuyuJNFaNsJTyxd5gOebHZRB9aLIYrBL_blmcWnVWtCfkS09LqyUJw' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436640, ...} audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436640, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: self = def test_everything_works(self): > self.do_login() social_core/tests/backends/test_vault.py:41: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/base.py:63: in do_login user = self.do_start() social_core/tests/backends/oauth.py:86: in do_start return self.backend.complete() social_core/backends/base.py:40: in complete return self.auth_complete(*args, **kwargs) social_core/utils.py:247: in wrapper return func(*args, **kwargs) social_core/backends/oauth.py:392: in auth_complete response = self.request_access_token( social_core/backends/open_id_connect.py:232: in request_access_token self.id_token = self.validate_and_return_id_token( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = id_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL3ZhdWx0LmV4YW1wbGUubmV0OjgyMDAvdjEvaWRlbnRpd...A4w1q8UVDwI1QdAxXPegh6srjVI9MxFjsSGdzZw3bXqjyly6Qn3n49UL5hrqxR6sbuyuJNFaNsJTyxd5gOebHZRB9aLIYrBL_blmcWnVWtCfkS09LqyUJw' access_token = 'foobar' def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) except ExpiredSignatureError: > raise AuthTokenError(self, 'Signature has expired') E social_core.exceptions.AuthTokenError: Token error: Signature has expired social_core/backends/open_id_connect.py:216: AuthTokenError _________________ VaultOpenIdConnectTest.test_invalid_audience _________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL3ZhdWx0LmV4YW1wbGUubmV0OjgyMDAvdjEvaWRlbnRpd...QVb88mhcazfv2jfmm3bmxhNlOtlx7e7VTY26AGhDRogb7-2JCZ_HNzvf2tQcDdpmVSqBYgje8Ay7nlS8ZW2cA-oOhfpRMMGcVtJYzg9O4fc-h5-Y9pzoGg' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706436770, ...} audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'someone-else', 'azp': 'someone-else', 'exp': 1706436770, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_audience(self): > self.authtoken_raised('Token error: Invalid audience', client_key='someone-else') social_core/tests/backends/test_open_id_connect.py:187: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid audience" does not match "Token error: Signature has expired" ________________ VaultOpenIdConnectTest.test_invalid_issue_time ________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL3ZhdWx0LmV4YW1wbGUubmV0OjgyMDAvdjEvaWRlbnRpd...eyCJRis_7cJOiSP4m6r9FpvVCxYTm_lkkrA0ZBGmPD6My85xBr5qwFMytkR3FaLlcRqsOIteEiuUVCCgW1fAzn8zlu3AQ1wQEW895LjFOX1JW3iqUxX2aQ' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436838, ...} audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436838, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issue_time(self): expiration_datetime = datetime.datetime.utcnow() - \ datetime.timedelta(hours=1) > self.authtoken_raised('Token error: Incorrect id_token: iat', issue_datetime=expiration_datetime) social_core/tests/backends/test_open_id_connect.py:193: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: iat" does not match "Token error: Signature has expired" __________________ VaultOpenIdConnectTest.test_invalid_issuer __________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6bnVsbCwidHlwIjoiSldUIn0.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6Ik12YXNwam9vVnlZdDlCSEtCN...YkDMSlhDOgw3WLQEPtWaiw7xqlqmag8T13OG7mvZ6GvmfVajE6UGy2unOIYBhLDmmFW42r1XUiTfhAakPRMhuMc4Wt0hVeMr-kOFXG9h41CArYKB6NRJ6w' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436904, ...} audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706436904, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_issuer(self): > self.authtoken_raised('Token error: Invalid issuer', issuer='someone-else') social_core/tests/backends/test_open_id_connect.py:183: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Invalid issuer" does not match "Token error: Signature has expired" __________________ VaultOpenIdConnectTest.test_invalid_nonce ___________________ def validate_and_return_id_token(self, id_token, access_token): """ Validates the id_token according to the steps at http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. """ client_id, client_secret = self.get_key_and_secret() key = self.find_valid_key(id_token) if not key: raise AuthTokenError(self, 'Signature verification failed') rsakey = jwk.construct(key) try: > claims = jwt.decode( id_token, rsakey.to_pem().decode('utf-8'), algorithms=self.setting('JWT_ALGORITHMS', self.JWT_ALGORITHMS), audience=client_id, issuer=self.id_token_issuer(), access_token=access_token, options=self.setting('JWT_DECODE_OPTIONS', self.JWT_DECODE_OPTIONS), ) social_core/backends/open_id_connect.py:206: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3RrZXkiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3ZhdWx0LmV4YW1wbGUubmV0OjgyMDAvdjEvaW...fVDXqQ7-avNjyYLR506jotJ96-VACmiXtNLf09Z7IvcBv-0ggljAMd3of1w8hqj0w5MthCk_2tbNd22iITSUv1XGobJmymtBUV-Punch73z-oXONgla9UA' key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApUfcJ8WFrVue98Ygzb6K\nEQXHBzi8HavCu8VENB2As94...ahcwl3ze2tMK6g\nJxa/TdCf1y99Yq6oilmVvZJ8kwWWnbPE+oDmOVPVnEyTvYVCvN4rBT1DQ+x0F1mo\n2QIDAQAB\n-----END PUBLIC KEY-----\n' algorithms = ['RS256'], options = {}, audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, access_token = 'foobar' def decode(token, key, algorithms=None, options=None, audience=None, issuer=None, subject=None, access_token=None): """Verifies a JWT string's signature and validates reserved claims. Args: token (str): A signed JWS to be verified. key (str or dict): A key to attempt to verify the payload with. Can be individual JWK or JWK set. algorithms (str or list): Valid algorithms that should be used to verify the JWS. audience (str): The intended audience of the token. If the "aud" claim is included in the claim set, then the audience must be included and must equal the provided claim. issuer (str or iterable): Acceptable value(s) for the issuer of the token. If the "iss" claim is included in the claim set, then the issuer must be given and the claim in the token must be among the acceptable values. subject (str): The subject of the token. If the "sub" claim is included in the claim set, then the subject must be included and must equal the provided claim. access_token (str): An access token string. If the "at_hash" claim is included in the claim set, then the access_token must be included, and it must match the "at_hash" claim. options (dict): A dictionary of options for skipping validation steps. defaults = { 'verify_signature': True, 'verify_aud': True, 'verify_iat': True, 'verify_exp': True, 'verify_nbf': True, 'verify_iss': True, 'verify_sub': True, 'verify_jti': True, 'verify_at_hash': True, 'require_aud': False, 'require_iat': False, 'require_exp': False, 'require_nbf': False, 'require_iss': False, 'require_sub': False, 'require_jti': False, 'require_at_hash': False, 'leeway': 0, } Returns: dict: The dict representation of the claims set, assuming the signature is valid and all requested data validation passes. Raises: JWTError: If the signature is invalid in any way. ExpiredSignatureError: If the signature has expired. JWTClaimsError: If any claim is invalid in any way. Examples: >>> payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' >>> jwt.decode(payload, 'secret', algorithms='HS256') """ defaults = { "verify_signature": True, "verify_aud": True, "verify_iat": True, "verify_exp": True, "verify_nbf": True, "verify_iss": True, "verify_sub": True, "verify_jti": True, "verify_at_hash": True, "require_aud": False, "require_iat": False, "require_exp": False, "require_nbf": False, "require_iss": False, "require_sub": False, "require_jti": False, "require_at_hash": False, "leeway": 0, } if options: defaults.update(options) verify_signature = defaults.get("verify_signature", True) try: payload = jws.verify(token, key, algorithms, verify=verify_signature) except JWSError as e: raise JWTError(e) # Needed for at_hash verification algorithm = jws.get_unverified_header(token)["alg"] try: claims = json.loads(payload.decode("utf-8")) except ValueError as e: raise JWTError("Invalid payload string: %s" % e) if not isinstance(claims, Mapping): raise JWTError("Invalid payload string: must be a json object") > _validate_claims( claims, audience=audience, issuer=issuer, subject=subject, algorithm=algorithm, access_token=access_token, options=defaults, ) /usr/lib/python3.12/site-packages/jose/jwt.py:157: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706437035, ...} audience = 'a-key' issuer = 'https://vault.example.net:8200/v1/identity/oidc/provider/default' subject = None, algorithm = 'RS256', access_token = 'foobar' options = {'leeway': 0, 'require_at_hash': False, 'require_aud': False, 'require_exp': False, ...} def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm=None, access_token=None, options=None): leeway = options.get("leeway", 0) if isinstance(leeway, timedelta): leeway = timedelta_total_seconds(leeway) required_claims = [e[len("require_") :] for e in options.keys() if e.startswith("require_") and options[e]] for require_claim in required_claims: if require_claim not in claims: raise JWTError('missing required key "%s" among claims' % require_claim) else: options["verify_" + require_claim] = True # override verify when required if not isinstance(audience, ((str,), type(None))): raise JWTError("audience must be a string or None") if options.get("verify_iat"): _validate_iat(claims) if options.get("verify_nbf"): _validate_nbf(claims, leeway=leeway) if options.get("verify_exp"): > _validate_exp(claims, leeway=leeway) /usr/lib/python3.12/site-packages/jose/jwt.py:481: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ claims = {'at_hash': 'w6uP8Tcg6K2QR905Rms8iQ', 'aud': 'a-key', 'azp': 'a-key', 'exp': 1706437035, ...} leeway = 0 def _validate_exp(claims, leeway=0): """Validates that the 'exp' claim is valid. The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the "exp" claim requires that the current date/time MUST be before the expiration date/time listed in the "exp" claim. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL. Args: claims (dict): The claims dictionary to validate. leeway (int): The number of seconds of skew that is allowed. """ if "exp" not in claims: return try: exp = int(claims["exp"]) except ValueError: raise JWTClaimsError("Expiration Time claim (exp) must be an integer.") now = timegm(datetime.utcnow().utctimetuple()) if exp < (now - leeway): > raise ExpiredSignatureError("Signature has expired.") E jose.exceptions.ExpiredSignatureError: Signature has expired. /usr/lib/python3.12/site-packages/jose/jwt.py:314: ExpiredSignatureError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/builddir/build/BUILD/social-auth-core-4.3.0/social_core/backends/open_id_connect.py", line 206, in validate_and_return_id_token claims = jwt.decode( ^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 157, in decode _validate_claims( File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 481, in _validate_claims _validate_exp(claims, leeway=leeway) File "/usr/lib/python3.12/site-packages/jose/jwt.py", line 314, in _validate_exp raise ExpiredSignatureError("Signature has expired.") jose.exceptions.ExpiredSignatureError: Signature has expired. During handling of the above exception, another exception occurred: social_core.exceptions.AuthTokenError: Token error: Signature has expired During handling of the above exception, another exception occurred: self = def test_invalid_nonce(self): > self.authtoken_raised( 'Token error: Incorrect id_token: nonce', nonce='something-wrong', kid='testkey', ) social_core/tests/backends/test_open_id_connect.py:197: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ social_core/tests/backends/test_open_id_connect.py:157: in authtoken_raised with self.assertRaisesRegex(AuthTokenError, expected_message): E AssertionError: "Token error: Incorrect id_token: nonce" does not match "Token error: Signature has expired" =============================== warnings summary =============================== social_core/tests/models.py:53 /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/models.py:53: PytestCollectionWarning: cannot collect test class 'TestUserSocialAuth' because it has a __init__ constructor (from: social_core/tests/test_pipeline.py) class TestUserSocialAuth(UserMixin, BaseModel): social_core/tests/strategy.py:20 /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/strategy.py:20: PytestCollectionWarning: cannot collect test class 'TestStrategy' because it has a __init__ constructor (from: social_core/tests/test_pipeline.py) class TestStrategy(BaseStrategy): social_core/tests/models.py:53 /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/models.py:53: PytestCollectionWarning: cannot collect test class 'TestUserSocialAuth' because it has a __init__ constructor (from: social_core/tests/actions/test_disconnect.py) class TestUserSocialAuth(UserMixin, BaseModel): social_core/tests/strategy.py:20 /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/strategy.py:20: PytestCollectionWarning: cannot collect test class 'TestStrategy' because it has a __init__ constructor (from: social_core/tests/backends/test_broken.py) class TestStrategy(BaseStrategy): social_core/tests/backends/test_dummy.py:138 /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/backends/test_dummy.py:138: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). 'expires': time.mktime((datetime.datetime.utcnow() + social_core/tests/backends/test_livejournal.py:9 /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/backends/test_livejournal.py:9: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). JANRAIN_NONCE = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') social_core/tests/backends/test_ngpvan.py:9 /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/backends/test_ngpvan.py:9: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). JANRAIN_NONCE = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') social_core/tests/strategy.py:20 /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/strategy.py:20: PytestCollectionWarning: cannot collect test class 'TestStrategy' because it has a __init__ constructor (from: social_core/tests/backends/test_utils.py) class TestStrategy(BaseStrategy): social_core/tests/test_pipeline.py: 40 warnings social_core/tests/actions/test_associate.py: 36 warnings social_core/tests/actions/test_disconnect.py: 18 warnings social_core/tests/actions/test_login.py: 40 warnings social_core/tests/backends/test_amazon.py: 24 warnings social_core/tests/backends/test_angel.py: 12 warnings social_core/tests/backends/test_apple.py: 10 warnings social_core/tests/backends/test_arcgis.py: 12 warnings social_core/tests/backends/test_asana.py: 12 warnings social_core/tests/backends/test_atlassian.py: 14 warnings social_core/tests/backends/test_auth0.py: 12 warnings social_core/tests/backends/test_azuread.py: 14 warnings social_core/tests/backends/test_azuread_b2c.py: 17 warnings social_core/tests/backends/test_behance.py: 10 warnings social_core/tests/backends/test_bitbucket.py: 48 warnings social_core/tests/backends/test_box.py: 17 warnings social_core/tests/backends/test_chatwork.py: 12 warnings social_core/tests/backends/test_cilogon.py: 12 warnings social_core/tests/backends/test_clef.py: 12 warnings social_core/tests/backends/test_cognito.py: 12 warnings social_core/tests/backends/test_coinbase.py: 12 warnings social_core/tests/backends/test_coursera.py: 12 warnings social_core/tests/backends/test_dailymotion.py: 12 warnings social_core/tests/backends/test_deezer.py: 12 warnings social_core/tests/backends/test_digitalocean.py: 12 warnings social_core/tests/backends/test_discourse.py: 4 warnings social_core/tests/backends/test_disqus.py: 12 warnings social_core/tests/backends/test_dribbble.py: 12 warnings social_core/tests/backends/test_drip.py: 12 warnings social_core/tests/backends/test_dropbox.py: 12 warnings social_core/tests/backends/test_dummy.py: 137 warnings social_core/tests/backends/test_edmodo.py: 12 warnings social_core/tests/backends/test_elixir.py: 24 warnings social_core/tests/backends/test_email.py: 8 warnings social_core/tests/backends/test_eventbrite.py: 4 warnings social_core/tests/backends/test_evernote.py: 28 warnings social_core/tests/backends/test_facebook.py: 26 warnings social_core/tests/backends/test_fence.py: 24 warnings social_core/tests/backends/test_fitbit.py: 14 warnings social_core/tests/backends/test_five_hundred_px.py: 14 warnings social_core/tests/backends/test_flat.py: 12 warnings social_core/tests/backends/test_flickr.py: 12 warnings social_core/tests/backends/test_foursquare.py: 12 warnings social_core/tests/backends/test_gitea.py: 24 warnings social_core/tests/backends/test_github.py: 79 warnings social_core/tests/backends/test_github_enterprise.py: 79 warnings social_core/tests/backends/test_gitlab.py: 24 warnings social_core/tests/backends/test_globus.py: 24 warnings social_core/tests/backends/test_google.py: 84 warnings social_core/tests/backends/test_grafana.py: 12 warnings social_core/tests/backends/test_instagram.py: 12 warnings social_core/tests/backends/test_itembase.py: 12 warnings social_core/tests/backends/test_kakao.py: 12 warnings social_core/tests/backends/test_keycloak.py: 10 warnings social_core/tests/backends/test_khanacademy.py: 12 warnings social_core/tests/backends/test_linkedin.py: 24 warnings social_core/tests/backends/test_live.py: 12 warnings social_core/tests/backends/test_livejournal.py: 18 warnings social_core/tests/backends/test_lyft.py: 12 warnings social_core/tests/backends/test_mailru.py: 12 warnings social_core/tests/backends/test_mapmyfitness.py: 12 warnings social_core/tests/backends/test_microsoft.py: 17 warnings social_core/tests/backends/test_mineid.py: 12 warnings social_core/tests/backends/test_mixcloud.py: 12 warnings social_core/tests/backends/test_musicbrainz.py: 12 warnings social_core/tests/backends/test_nationbuilder.py: 12 warnings social_core/tests/backends/test_naver.py: 12 warnings social_core/tests/backends/test_ngpvan.py: 29 warnings social_core/tests/backends/test_okta.py: 62 warnings social_core/tests/backends/test_open_id_connect.py: 54 warnings social_core/tests/backends/test_orbi.py: 12 warnings social_core/tests/backends/test_orcid.py: 12 warnings social_core/tests/backends/test_osso.py: 12 warnings social_core/tests/backends/test_patreon.py: 12 warnings social_core/tests/backends/test_paypal.py: 17 warnings social_core/tests/backends/test_phabricator.py: 24 warnings social_core/tests/backends/test_pinterest.py: 24 warnings social_core/tests/backends/test_podio.py: 12 warnings social_core/tests/backends/test_qiita.py: 12 warnings social_core/tests/backends/test_quizlet.py: 10 warnings social_core/tests/backends/test_readability.py: 14 warnings social_core/tests/backends/test_reddit.py: 17 warnings social_core/tests/backends/test_saml.py: 2 warnings social_core/tests/backends/test_scistarter.py: 12 warnings social_core/tests/backends/test_simplelogin.py: 12 warnings social_core/tests/backends/test_sketchfab.py: 12 warnings social_core/tests/backends/test_skyrock.py: 14 warnings social_core/tests/backends/test_slack.py: 36 warnings social_core/tests/backends/test_soundcloud.py: 12 warnings social_core/tests/backends/test_spotify.py: 12 warnings social_core/tests/backends/test_stackoverflow.py: 12 warnings social_core/tests/backends/test_steam.py: 25 warnings social_core/tests/backends/test_stocktwits.py: 24 warnings social_core/tests/backends/test_strava.py: 12 warnings social_core/tests/backends/test_stripe.py: 10 warnings social_core/tests/backends/test_taobao.py: 12 warnings social_core/tests/backends/test_thisismyjam.py: 14 warnings social_core/tests/backends/test_tripit.py: 28 warnings social_core/tests/backends/test_tumblr.py: 14 warnings social_core/tests/backends/test_twitch.py: 36 warnings social_core/tests/backends/test_twitter.py: 28 warnings social_core/tests/backends/test_uber.py: 12 warnings social_core/tests/backends/test_udata.py: 12 warnings social_core/tests/backends/test_universe.py: 12 warnings social_core/tests/backends/test_upwork.py: 14 warnings social_core/tests/backends/test_username.py: 8 warnings social_core/tests/backends/test_vault.py: 27 warnings social_core/tests/backends/test_vk.py: 12 warnings social_core/tests/backends/test_wunderlist.py: 12 warnings social_core/tests/backends/test_xing.py: 14 warnings social_core/tests/backends/test_yahoo.py: 17 warnings social_core/tests/backends/test_yammer.py: 10 warnings social_core/tests/backends/test_yandex.py: 24 warnings social_core/tests/backends/test_zoom.py: 17 warnings social_core/tests/backends/test_zotero.py: 12 warnings /usr/lib/python3.12/site-packages/httpretty/core.py:1077: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). now = datetime.utcnow() social_core/tests/backends/test_amazon.py: 8 warnings social_core/tests/backends/test_pinterest.py: 8 warnings /usr/lib/python3.12/site-packages/urllib3/util/ssl_.py:290: DeprecationWarning: ssl.PROTOCOL_TLSv1 is deprecated context = SSLContext(ssl_version) social_core/tests/backends/test_dummy.py::ExpirationTimeTest::test_expires_time /builddir/build/BUILD/social-auth-core-4.3.0/social_core/storage.py:72: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). now = datetime.utcnow() social_core/tests/backends/test_dummy.py::ExpirationTimeTest::test_expires_time /builddir/build/BUILD/social-auth-core-4.3.0/social_core/storage.py:77: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC). return datetime.utcfromtimestamp(expires) - now social_core/tests/backends/test_elixir.py::ElixirOpenIdConnectTest::test_expired_signature social_core/tests/backends/test_fence.py::FenceOpenIdConnectTest::test_expired_signature social_core/tests/backends/test_globus.py::GlobusOpenIdConnectTest::test_expired_signature social_core/tests/backends/test_google.py::GoogleOpenIdConnectTest::test_expired_signature social_core/tests/backends/test_okta.py::OktaOpenIdConnectTest::test_expired_signature social_core/tests/backends/test_open_id_connect.py::BaseOpenIdConnectTest::test_expired_signature social_core/tests/backends/test_open_id_connect.py::ExampleOpenIdConnectTest::test_expired_signature social_core/tests/backends/test_twitch.py::TwitchOpenIdConnectTest::test_expired_signature social_core/tests/backends/test_vault.py::VaultOpenIdConnectTest::test_expired_signature /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/backends/test_open_id_connect.py:177: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). expiration_datetime = datetime.datetime.utcnow() - \ social_core/tests/backends/test_elixir.py: 7 warnings social_core/tests/backends/test_fence.py: 7 warnings social_core/tests/backends/test_globus.py: 7 warnings social_core/tests/backends/test_google.py: 7 warnings social_core/tests/backends/test_okta.py: 8 warnings social_core/tests/backends/test_open_id_connect.py: 16 warnings social_core/tests/backends/test_twitch.py: 7 warnings social_core/tests/backends/test_vault.py: 8 warnings /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/backends/test_open_id_connect.py:123: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). now = datetime.datetime.utcnow() social_core/tests/backends/test_elixir.py: 5 warnings social_core/tests/backends/test_fence.py: 5 warnings social_core/tests/backends/test_globus.py: 5 warnings social_core/tests/backends/test_google.py: 5 warnings social_core/tests/backends/test_okta.py: 6 warnings social_core/tests/backends/test_open_id_connect.py: 12 warnings social_core/tests/backends/test_twitch.py: 5 warnings social_core/tests/backends/test_vault.py: 6 warnings /usr/lib/python3.12/site-packages/jose/jwt.py:311: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). now = timegm(datetime.utcnow().utctimetuple()) social_core/tests/backends/test_elixir.py::ElixirOpenIdConnectTest::test_invalid_issue_time social_core/tests/backends/test_fence.py::FenceOpenIdConnectTest::test_invalid_issue_time social_core/tests/backends/test_globus.py::GlobusOpenIdConnectTest::test_invalid_issue_time social_core/tests/backends/test_google.py::GoogleOpenIdConnectTest::test_invalid_issue_time social_core/tests/backends/test_okta.py::OktaOpenIdConnectTest::test_invalid_issue_time social_core/tests/backends/test_open_id_connect.py::BaseOpenIdConnectTest::test_invalid_issue_time social_core/tests/backends/test_open_id_connect.py::ExampleOpenIdConnectTest::test_invalid_issue_time social_core/tests/backends/test_twitch.py::TwitchOpenIdConnectTest::test_invalid_issue_time social_core/tests/backends/test_vault.py::VaultOpenIdConnectTest::test_invalid_issue_time /builddir/build/BUILD/social-auth-core-4.3.0/social_core/tests/backends/test_open_id_connect.py:191: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). expiration_datetime = datetime.datetime.utcnow() - \ social_core/tests/backends/test_livejournal.py::LiveJournalOpenIdTest::test_failed_login /usr/lib/python3.12/site-packages/openid/oidutil.py:106: DeprecationWarning: defusedxml.cElementTree is deprecated, import from defusedxml.ElementTree instead. ElementTree = __import__(mod_name, None, None, ['unused']) social_core/tests/backends/test_saml.py::SAMLTest::test_login /usr/lib/python3.12/site-packages/onelogin/saml2/utils.py:394: DeprecationWarning: datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC). data = datetime.utcfromtimestamp(float(time)) social_core/tests/backends/test_saml.py::SAMLTest::test_metadata_generation /usr/lib/python3.12/site-packages/onelogin/saml2/utils.py:450: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). data = datetime.utcnow() + timedelta -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================== short test summary info ============================ FAILED social_core/tests/backends/test_dummy.py::ExpirationTimeTest::test_expires_time FAILED social_core/tests/backends/test_elixir.py::ElixirOpenIdConnectTest::test_invalid_audience FAILED social_core/tests/backends/test_elixir.py::ElixirOpenIdConnectTest::test_invalid_issue_time FAILED social_core/tests/backends/test_elixir.py::ElixirOpenIdConnectTest::test_invalid_issuer FAILED social_core/tests/backends/test_elixir.py::ElixirOpenIdConnectTest::test_invalid_nonce FAILED social_core/tests/backends/test_fence.py::FenceOpenIdConnectTest::test_invalid_audience FAILED social_core/tests/backends/test_fence.py::FenceOpenIdConnectTest::test_invalid_issue_time FAILED social_core/tests/backends/test_fence.py::FenceOpenIdConnectTest::test_invalid_issuer FAILED social_core/tests/backends/test_fence.py::FenceOpenIdConnectTest::test_invalid_nonce FAILED social_core/tests/backends/test_globus.py::GlobusOpenIdConnectTest::test_invalid_audience FAILED social_core/tests/backends/test_globus.py::GlobusOpenIdConnectTest::test_invalid_issue_time FAILED social_core/tests/backends/test_globus.py::GlobusOpenIdConnectTest::test_invalid_issuer FAILED social_core/tests/backends/test_globus.py::GlobusOpenIdConnectTest::test_invalid_nonce FAILED social_core/tests/backends/test_google.py::GoogleOpenIdConnectTest::test_invalid_audience FAILED social_core/tests/backends/test_google.py::GoogleOpenIdConnectTest::test_invalid_issue_time FAILED social_core/tests/backends/test_google.py::GoogleOpenIdConnectTest::test_invalid_issuer FAILED social_core/tests/backends/test_google.py::GoogleOpenIdConnectTest::test_invalid_nonce FAILED social_core/tests/backends/test_okta.py::OktaOpenIdConnectTest::test_everything_works FAILED social_core/tests/backends/test_okta.py::OktaOpenIdConnectTest::test_invalid_audience FAILED social_core/tests/backends/test_okta.py::OktaOpenIdConnectTest::test_invalid_issue_time FAILED social_core/tests/backends/test_okta.py::OktaOpenIdConnectTest::test_invalid_issuer FAILED social_core/tests/backends/test_okta.py::OktaOpenIdConnectTest::test_invalid_nonce FAILED social_core/tests/backends/test_open_id_connect.py::BaseOpenIdConnectTest::test_everything_works FAILED social_core/tests/backends/test_open_id_connect.py::BaseOpenIdConnectTest::test_invalid_audience FAILED social_core/tests/backends/test_open_id_connect.py::BaseOpenIdConnectTest::test_invalid_issue_time FAILED social_core/tests/backends/test_open_id_connect.py::BaseOpenIdConnectTest::test_invalid_issuer FAILED social_core/tests/backends/test_open_id_connect.py::BaseOpenIdConnectTest::test_invalid_nonce FAILED social_core/tests/backends/test_open_id_connect.py::ExampleOpenIdConnectTest::test_everything_works FAILED social_core/tests/backends/test_open_id_connect.py::ExampleOpenIdConnectTest::test_invalid_audience FAILED social_core/tests/backends/test_open_id_connect.py::ExampleOpenIdConnectTest::test_invalid_issue_time FAILED social_core/tests/backends/test_open_id_connect.py::ExampleOpenIdConnectTest::test_invalid_issuer FAILED social_core/tests/backends/test_open_id_connect.py::ExampleOpenIdConnectTest::test_invalid_nonce FAILED social_core/tests/backends/test_steam.py::SteamOpenIdTest::test_login FAILED social_core/tests/backends/test_steam.py::SteamOpenIdMissingSteamIdTest::test_login FAILED social_core/tests/backends/test_twitch.py::TwitchOpenIdConnectTest::test_invalid_audience FAILED social_core/tests/backends/test_twitch.py::TwitchOpenIdConnectTest::test_invalid_issue_time FAILED social_core/tests/backends/test_twitch.py::TwitchOpenIdConnectTest::test_invalid_issuer FAILED social_core/tests/backends/test_twitch.py::TwitchOpenIdConnectTest::test_invalid_nonce FAILED social_core/tests/backends/test_vault.py::VaultOpenIdConnectTest::test_everything_works FAILED social_core/tests/backends/test_vault.py::VaultOpenIdConnectTest::test_invalid_audience FAILED social_core/tests/backends/test_vault.py::VaultOpenIdConnectTest::test_invalid_issue_time FAILED social_core/tests/backends/test_vault.py::VaultOpenIdConnectTest::test_invalid_issuer FAILED social_core/tests/backends/test_vault.py::VaultOpenIdConnectTest::test_invalid_nonce ========== 43 failed, 468 passed, 2390 warnings in 5903.73s (1:38:23) ========== RPM build errors: error: Bad exit status from /var/tmp/rpm-tmp.3f3gwC (%check) Bad exit status from /var/tmp/rpm-tmp.3f3gwC (%check) Child return code was: 1 EXCEPTION: [Error('Command failed: \n # bash --login -c /usr/bin/rpmbuild -bb --noclean --target noarch --nodeps /builddir/build/SPECS/python-social-auth-core.spec\n', 1)] Traceback (most recent call last): File "/usr/lib/python3.11/site-packages/mockbuild/trace_decorator.py", line 93, in trace result = func(*args, **kw) ^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.11/site-packages/mockbuild/util.py", line 597, in do_with_status raise exception.Error("Command failed: \n # %s\n%s" % (command, output), child.returncode) mockbuild.exception.Error: Command failed: # bash --login -c /usr/bin/rpmbuild -bb --noclean --target noarch --nodeps /builddir/build/SPECS/python-social-auth-core.spec