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/f39-build-2229735-53148/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=1689897600 Wrote: /builddir/build/SRPMS/python-social-auth-core-4.3.0-6.fc39.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/f39-build-2229735-53148/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=1689897600 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.BmV64K + 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.2gqqbL + umask 022 + cd /builddir/build/BUILD + CFLAGS='-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 -fstack-clash-protection -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 -fstack-clash-protection -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 -fstack-clash-protection -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 -fstack-clash-protection -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 -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 -fstack-clash-protection -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.TbigkX + umask 022 + cd /builddir/build/BUILD + '[' /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.noarch '!=' / ']' + rm -rf /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.noarch ++ dirname /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.noarch + mkdir -p /builddir/build/BUILDROOT + mkdir /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.noarch + CFLAGS='-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 -fstack-clash-protection -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 -fstack-clash-protection -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 -fstack-clash-protection -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 -fstack-clash-protection -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 -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 -fstack-clash-protection -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-6.fc39.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, pypa/build 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-6.fc39.noarch/usr creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.noarch/usr/lib creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.noarch/usr/lib/python3.12 creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.noarch/usr/lib/python3.12/site-packages creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.noarch/usr/lib/python3.12/site-packages/social_core creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.noarch/usr/lib/python3.12/site-packages/social_core/pipeline creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.noarch/usr/lib/python3.12/site-packages/social_core/tests creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.noarch/usr/lib/python3.12/site-packages/social_core/tests creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.noarch/usr/lib/python3.12/site-packages/social_core/tests/backends creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.noarch/usr/lib/python3.12/site-packages/social_core creating /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.noarch/usr/lib/python3.12/site-packages/social_core byte-compiling /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.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-6.fc39.noarch/usr/lib/python3.12/site-packages/social_core/actions.py to actions.cpython-312.pyc writing byte-compilation script '/tmp/tmph1tnbgxw.py' /usr/bin/python3 /tmp/tmph1tnbgxw.py removing /tmp/tmph1tnbgxw.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' adding license file 'LICENSE' warning: no previously-included files matching '*.pyc' found under directory 'social_core' 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-6.fc39.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-6.fc39.noarch/usr/bin/__pycache__ + rm -r /builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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-6.fc39 --unique-debug-suffix -4.3.0-6.fc39.noarch --unique-debug-src-base python-social-auth-core-4.3.0-6.fc39.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-6.fc39.noarch/usr/lib/python3.12 using python3.12 + /usr/lib/rpm/redhat/brp-python-hardlink Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.sTQWiM + umask 022 + cd /builddir/build/BUILD + CFLAGS='-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 -fstack-clash-protection -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 -fstack-clash-protection -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 -fstack-clash-protection -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 -fstack-clash-protection -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 -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 -fstack-clash-protection -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-6.fc39.noarch/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin + PYTHONPATH=/builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.noarch/usr/lib64/python3.12/site-packages:/builddir/build/BUILDROOT/python-social-auth-core-4.3.0-6.fc39.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.2.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 .... [ 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...diIWQJiFVa0nCApD9fTiZnEj_DGLXtOF5_pW6mRJw1HtKn-0XIuGe8QkT2T4-AjnlzZ9kQPcky81UfE7vl9M-HyJSMdubqcv_yIOol2Xn4GdlPXLSasQVw' 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': 1705085344, ...} 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': 1705085344, ...} 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...m9WawTEdAn3zzTYSwACNPhS62pczLdp4jKSRUEm217LohzA2JH2Vq53kktawylHxlkl8zk2G1i0E5W12yfXsgzVghecDqKhI7kTqfBwiXXO5bFgJb-Bu6Q' 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': 1705085384, ...} 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': 1705085384, ...} 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.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IjdBTFBpS3lkb2tQaTNwYVhlQ...sAFJN8yTLExLv5xrQBP90BBSvIye0W3lLHZXlzlKFNpLji6FWjcDRZZlwsIeEYhV2yI9YHFh79YvDnVM6HLH902ze_ta0ixZOhvuQRqrnv-wzyskvJq4sw' 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': 1705085426, ...} 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': 1705085426, ...} 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...EVVK4zOnQHfjTA7blxIrThZsPKALTCTvbUpRXVs5oamitp68ChWYbGQiN9KyH9LzE79D3H_ncoWdouLoofa9aFoXtklocdZincGAZowO95OeTHwZHIZ2Xw' 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': 1705085513, ...} 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': 1705085513, ...} 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...9E8inUsLwwvXJMwXUC80Ow8Vo65PxopHTPpk2zETey0Hzxyltxs8hIRpWasPdDbHczh0R3AoNsk3yFD19YyIAPmdTFEsEDYh4cF3hNFcHh33esj3KYs3Aw' 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': 1705085703, ...} 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': 1705085703, ...} 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...IqEydc6hzBO1OAugM7_CDOTqNgkpmV7ZK_7rnh_YMHzamnKDUnYFiUghNxily_n0ftEU9WphMLzbMivE0u_IgqgcwxKrtBtF0-POIHTH1GY0WGuK_qls_A' 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': 1705085749, ...} 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': 1705085749, ...} 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.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IkRMYm5lSTRxSTFhQlRQOEhhV...7zWirNKF3brWCu7-NhEjWfOr-VQJToPMupn8VZBhYAusXA7yflI119oRNBcIII-WL6vEZQAklnXlvWqP50nKgCvggUprynnVFtFa3hUCHpXviTuj7vdZ7w' 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': 1705085797, ...} 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': 1705085797, ...} 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...QRRgypCeI4T4l7GqvolqCkzkqxE_kTfXKl6nqWcQ3kKUxV_EIjKZ_fQZViPX7BGqCWqg-mRL2Sv6ifGa6MX1U6eoOd93HLGXYqWZxsItat2VwLLOEs3Rmg' 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': 1705085884, ...} 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': 1705085884, ...} 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.eyJpc3MiOiJodHRwczovL2F1dGguZ2xvYnVzLm9yZyIsIm5vbmNlIjoiOUhaTEpNe...ERVAYyWBYM4E86OhtZJ27wnv0FsQrS4thx8YY2BoJve1RUqLkRkH371pmiioo-wAKdVgrTIK02TEDKgnmhxXGCn1DFeWyGBeXsejzgjt6DcUpeEk1GnX-Q' 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': 1705086215, ...} 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': 1705086215, ...} 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.eyJpc3MiOiJodHRwczovL2F1dGguZ2xvYnVzLm9yZyIsIm5vbmNlIjoiN29jWkxVc...B3-pMjK8UlkumZEhQn0mhARpf7cv8494JXi0urbkwKQz4iv3HqHBowPGNUI5S5sC2ai29BIJZu2mqwBmfelybz_qj_clOujf_qSYO6VvF86aDLxonMKFyA' 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': 1705086258, ...} 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': 1705086258, ...} 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.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IjlBV241cHJaOWlibExsV1d1U...BENCYM4uXuN_ZixXYE_Y1UOZ5AZQ4GyzYv8St84ZNmqx5j3hNk33gRflNMyZX9ID_FOYAOtFMfyuaAjieKDfctpzxJ7oTQZ4YSz2YUqCfOzxphF-Ue98lg' 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': 1705086300, ...} 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': 1705086300, ...} 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...gpRi5bhI6G-7PnJCjqG1s1lVmzAdeSkWopkyQrV-rWAWaJEf9Ps5o2WumGKO_tTVWEE3-HM1M3BFqb4VJ-hnQeS-F8DotNHCsIXUZstxUxcye8eGWDSFUQ' 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': 1705086381, ...} 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': 1705086381, ...} 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.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwibm9uY2UiOiJyUnhtMWZrb0I2S...MqG8_AgfDZ8lBP5VinK-jb1bcyRJgZGtcBSkF3KVq7pMre8p2QtYyJ18l8FgLApNKJlherHWgpoOsFaR4nJKouEj5BsQ74uE7UyXGA5iQodC9_P9cMn0lA' 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': 1705086554, ...} 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': 1705086554, ...} 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.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwibm9uY2UiOiJXRDhnY3dHMjNMN...SuoasaNyeEkMVErVRUuKONo8Vz1ouI5JCYBOoOq4LVhTn1kPhrVXYEVNrQfFMczLjJ5V6tWofo805DZmH3VafnD-89hiQ32KJ0vo3GX11NLaZoHX1NRf9Q' 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': 1705086600, ...} 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': 1705086600, ...} 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.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IjNXUkhKOHJlNGllSWxyaUtoa...0ZW4g3S1VX5D57L2COkW2z_zZO_fwkCkaWk6np55evmXxUigLpl7S1cNSI4dfuuUryjbu5RbaUGRwzmVdSvjd7Yal139dwjKb5zdDG024DSzT3zxklD8_Q' 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': 1705086642, ...} 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': 1705086642, ...} 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...SKrUkVO6lHTO_orcFuYRN3HB_dIauam46mRQ7ez6ChEez9jwnkiYnyXv_GWMi21Yp3fbwKUGyRtaFxMK38YzlsdzpKV_1gKBRf1irMwlqMF4TVgo-KkDHA' 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': 1705086727, ...} 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': 1705086727, ...} 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...9rrc4_UsGqrXjqC9aw-CNVxL3OvHyhPi1uxpX3XJOcQIoB4Aexosp6wo4JuRkBKq8pykJAnyxBZxBx8Tgd8WK97zjWF9pXmPUaJ01AsB88IBCGTbjKLaaQ' 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...9rrc4_UsGqrXjqC9aw-CNVxL3OvHyhPi1uxpX3XJOcQIoB4Aexosp6wo4JuRkBKq8pykJAnyxBZxBx8Tgd8WK97zjWF9pXmPUaJ01AsB88IBCGTbjKLaaQ' 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': 1705087022, ...} 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': 1705087022, ...} 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...9rrc4_UsGqrXjqC9aw-CNVxL3OvHyhPi1uxpX3XJOcQIoB4Aexosp6wo4JuRkBKq8pykJAnyxBZxBx8Tgd8WK97zjWF9pXmPUaJ01AsB88IBCGTbjKLaaQ' 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...2wj_z8Kk8RO2SROGTxcSGDluVDMesVtwIcB0BOMIuszuTKXXiRWT71hxgd23CFLU_BpG26q3eUJuNt_0WrHgxF4beSxEFaKt2xiE2M-RsnWhp4gwrM43CA' 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': 1705087118, ...} 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': 1705087118, ...} 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...tudeCkM5UJiMkoGYVnXzfi9U54ywL9K9K9eeWJC6CAUyLopkJ9BHONzBSsxV8k9Vz91LFntgeBVqFq7htlT8TZrBpmSESz1uLMi8ExFtYKheAzggKIKvig' 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': 1705087164, ...} 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': 1705087164, ...} 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.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IlExRzZHY1hHSVhVQ1U3ekNQS...GLdFb67KpWPKNMRoEkTylcI8o6Arte-EmFLnDhrQ2DXEvn4Rk3bRs7i5EYuWQvXI3VpoO8uCDnWNaXUSHFp1WPSp1PW4L712cN1CwiK3kexIPBPvm7io0g' 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': 1705087211, ...} 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': 1705087211, ...} 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...qzGWilnvx6QQWqfwOO3TjztbKSXayKLSFQLmIQ4r4TVkGCnM3UH-1y26lExU7EOzmDJV05y5ZvoKxw593oqB3RT-XUCT6eVelsET0a8twnknHuyjeWdlSA' 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': 1705087300, ...} 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': 1705087300, ...} 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJobWJLc2ZvcVFBT...Bl8fDcYzUhIOughqQ1UuOxitel12Ds44kKlJry_dPwCSCFgo_OCgNod3G52IPVYI8MMPK6Hugxf44ohesdtAZkJpa7ipwEiec8Awvn647qSSf_hZFSF-FQ' 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJobWJLc2ZvcVFBT...Bl8fDcYzUhIOughqQ1UuOxitel12Ds44kKlJry_dPwCSCFgo_OCgNod3G52IPVYI8MMPK6Hugxf44ohesdtAZkJpa7ipwEiec8Awvn647qSSf_hZFSF-FQ' 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': 1705087396, ...} 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': 1705087396, ...} 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJobWJLc2ZvcVFBT...Bl8fDcYzUhIOughqQ1UuOxitel12Ds44kKlJry_dPwCSCFgo_OCgNod3G52IPVYI8MMPK6Hugxf44ohesdtAZkJpa7ipwEiec8Awvn647qSSf_hZFSF-FQ' 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJ4NTlITlU5MnFaV...iGqjEZPWBSrkfVVckELe9ga5dcfvuLdodAm_C5O77lBYKDPhPxFaAPMPVxIr5njTX0Lpo1QnccTR4Z28STA06T3Pa81nKsgMu4ruVjL4p0PY0WKIwPuXMg' 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': 1705087491, ...} 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': 1705087491, ...} 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJ0bXRRcU9obkhxU...3p4dy8p4JF0m1Uyj_FeUur7Orpaob6M7RupGT-eeVjPqw4ym0gniDC8meaW7MmVsrvs460e8jt-HsBer0P5PP6z5s1GDkxhccbIIm4H0ziR1nX1JhkNq5g' 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': 1705087532, ...} 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': 1705087532, ...} 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.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6Inlpb0ZuN01mZWxUbVN4UG5UM...-bDLn8T-uMM3H5A81uviBw2iel54VYQ9vxCtxDsYtmXJ15NV8ejIy3G0rNOlfxfocILhtmFqpZbgdWvPkhGOLKUczwqQQea0q9rBV_voAxHIhTv5HN_MYA' 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': 1705087574, ...} 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': 1705087574, ...} 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...CrUEn3f6FeGaeTwYkZiXK1dGCfXsM5A9Sd07E-i-BvCyPS9dzEZehUyPu2-tcV197zV_Ar3XUr77cwanBrEZ4xVs-TjvIt-vLrI_Jhfe15vSDWQpWY5IvA' 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': 1705087655, ...} 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': 1705087655, ...} 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiI3UmZkV3lpdklJa...aXVBwbNlUO9DuZk_ertjg4SF6hHoCJ9K5MNJw3g4B6I48s5w3Z_86FmyH9cZbUMkh-PM0XW61bri2OcRTG0jjugSebeSP-xQtewE5B4zhfIma0geTG13ZA' 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiI3UmZkV3lpdklJa...aXVBwbNlUO9DuZk_ertjg4SF6hHoCJ9K5MNJw3g4B6I48s5w3Z_86FmyH9cZbUMkh-PM0XW61bri2OcRTG0jjugSebeSP-xQtewE5B4zhfIma0geTG13ZA' 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': 1705087735, ...} 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': 1705087735, ...} 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiI3UmZkV3lpdklJa...aXVBwbNlUO9DuZk_ertjg4SF6hHoCJ9K5MNJw3g4B6I48s5w3Z_86FmyH9cZbUMkh-PM0XW61bri2OcRTG0jjugSebeSP-xQtewE5B4zhfIma0geTG13ZA' 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJmOWZiVm9zM21YV...ok8hK8LMyWvOnOREYKuNbEuqzUu3cftBw6hxp7bR9zwbjMb-7t4pbfRcoVDiGqjLNUidDRITrQGi7b5LZnZ144EA6t_ZAv2G6Z0uHLO8cJYCIpiOOdu4Jw' 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': 1705087818, ...} 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': 1705087818, ...} 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.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwibm9uY2UiOiJ6NjJva1RlQUJnc...BCy7O3v6Rur93SS-kqxkWRWGJofTBxJeMpopG9opYv8Y1FUxwiP7ezsv9x499lZIxDxNFdX-HNjSU1cBcGITkcKVGDS-uMTcoxOeyp2wLZibxbTdoS_0ow' 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': 1705087856, ...} 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': 1705087856, ...} 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.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6InJVazFXN3JsQkJzdUNkWDRxT...w-dsYOUinWIrqOhA4-6FIkodI0Gf2IKJpg2W60UGrXd2pSxSEEGQjKxtGBdVcJ9946OCu9mkBVhbYXkU8SkbERqFs1mx5kdMgquh-3kPTJ6LDnOXJnRSkQ' 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': 1705087895, ...} 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': 1705087895, ...} 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...Tbf5OPZqZ9sXXbzVPnycAliwdp9ymb_qLBzgl9GxvQuYDGKDR455jR-ib-jNTlgLBFiehzIbqMsj3dS9GTexwGPwOZok5EFxvUkhdge0tPyFuRFmh5LJxA' 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': 1705087974, ...} 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': 1705087974, ...} 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" ________________ 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.eyJpc3MiOiJodHRwczovL2lkLnR3aXRjaC50di9vYXV0aDIiLCJub25jZSI6IjJoV...wgtIoPlS5oMao5ICknRqKDiMh55e1ZzpGhHRwbAlDGS59bHPYAbaKqT5XCMVqGP4F5UYseSJ3NyBZaRW7blRmrHrJvMKaMYxIp_BXnBRV_3sPvF2pv6Vpg' 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': 1705088407, ...} 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': 1705088407, ...} 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.eyJpc3MiOiJodHRwczovL2lkLnR3aXRjaC50di9vYXV0aDIiLCJub25jZSI6ImZua...lld6fIEjdXGBCFBtHspFAMr4ZC3UVIgOJPxwCXfWV0HvETiBdioynwt_zB7Iv2JcbmbbC6KDQMV1OEBUR5SboxqM7EQOLt1Dp4_UAOtXuSxmHmgW6k0EyA' 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': 1705088449, ...} 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': 1705088449, ...} 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.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6IlhjNGZQR1pKb2RWTWc1ZWVqV...P9XPd4ZUShbYICkCRJDr5rNsRj4pnlAsy93qTeEnf0aPmbr1TQn3n8o8tRY84iJe6n6R4MPu0mIMJm8Z_zNq0WmUrJnbwEwE2EFkJ5rsTfXf7iQMP2UvLw' 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': 1705088493, ...} 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': 1705088493, ...} 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..._Lgw5tPG2d-CBxLYyISsSqc1kodWQgkuqWlzBtLA3NTaw0m8Jsm9-yFoLikmYqxLNO0DMGCF4kjdaCvL3mSxECTqJbyhR3R-0h480sqQkLLJAWdyDxk3_g' 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': 1705088569, ...} 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': 1705088569, ...} 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...xh9XOPYtpNIujD8Vc1QbB3g7ICeLbGRH0yjEZrW6tzVkEETenbTsDN_VO8yOQMJCnclxcLjGuKWmaadpGcZBch8XBAvPGgx8HAJ0EWuAfC-oLWzsqWny2A' 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...xh9XOPYtpNIujD8Vc1QbB3g7ICeLbGRH0yjEZrW6tzVkEETenbTsDN_VO8yOQMJCnclxcLjGuKWmaadpGcZBch8XBAvPGgx8HAJ0EWuAfC-oLWzsqWny2A' 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': 1705088710, ...} 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': 1705088710, ...} 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...xh9XOPYtpNIujD8Vc1QbB3g7ICeLbGRH0yjEZrW6tzVkEETenbTsDN_VO8yOQMJCnclxcLjGuKWmaadpGcZBch8XBAvPGgx8HAJ0EWuAfC-oLWzsqWny2A' 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...B-QyvB2b7KejQ58HaAotWTdrH9FEJIz9oJh0__4dY7BZvXGdjcOhhf604T5Vqhk7Pse_HzMmLehJx1bdh_NbWXuNegzL_3bBUW-R_api9oDHEr3wSsNPxA' 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': 1705088802, ...} 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': 1705088802, ...} 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...HXpIhZbbeC5wDBCasYPmcutYc0uB4EqYF0MTQJk-kWd3PZ1uom0XrviDwinGs2pZztewbh5_cELs4a2H-AA3QssOE610ejwlDLr6prbjHwH5cfam4u4fFA' 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': 1705088845, ...} 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': 1705088845, ...} 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.eyJpc3MiOiJzb21lb25lLWVsc2UiLCJub25jZSI6ImhCZ3p3R21kQWpQeUNmQ1pMT...lO9nm5EtqjhwxwNYQj49bOmAeNDGu_Wc94Zxt0LL875Ggplr1lYpGDm6fw7UqdRQ_J5oWuEb67P1NxzJxCTiotgkRe6H1RMNR1NzQnA8toFxySWD6EFggg' 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': 1705088892, ...} 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': 1705088892, ...} 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...-QlSnpgiIenuzM_ywMss1bTZF9mYrKvC-TzbSSsrhPa8-WHr-EbS4eNj9WGSoHiBlfR0s3tujM_okRK6OIrjP9yA-nYZI50Fl0dtmzPZJPSVaqYsO_Gepg' 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': 1705088974, ...} 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': 1705088974, ...} 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: 30 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_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 ========== 41 failed, 470 passed, 2395 warnings in 4724.70s (1:18:44) ========== RPM build errors: error: Bad exit status from /var/tmp/rpm-tmp.sTQWiM (%check) Bad exit status from /var/tmp/rpm-tmp.sTQWiM (%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