Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F9344317
test_backends.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Subscribers
None
test_backends.py
View Options
# Copyright (C) 2020 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU Affero General Public License version 3, or any later version
# See top-level LICENSE file for more information
from
datetime
import
datetime
,
timedelta
from
django.contrib.auth
import
authenticate
,
get_backends
import
pytest
from
django.conf
import
settings
from
rest_framework.exceptions
import
AuthenticationFailed
from
swh.web.auth.backends
import
OIDCBearerTokenAuthentication
from
swh.web.auth.models
import
OIDCUser
from
swh.web.common.utils
import
reverse
from
.
import
sample_data
from
.keycloak_mock
import
mock_keycloak
def
_authenticate_user
(
request_factory
):
request
=
request_factory
.
get
(
reverse
(
"oidc-login-complete"
))
return
authenticate
(
request
=
request
,
code
=
"some-code"
,
code_verifier
=
"some-code-verifier"
,
redirect_uri
=
"https://localhost:5004"
,
)
def
_check_authenticated_user
(
user
,
decoded_token
):
assert
user
is
not
None
assert
isinstance
(
user
,
OIDCUser
)
assert
user
.
id
!=
0
assert
user
.
username
==
decoded_token
[
"preferred_username"
]
assert
user
.
password
==
""
assert
user
.
first_name
==
decoded_token
[
"given_name"
]
assert
user
.
last_name
==
decoded_token
[
"family_name"
]
assert
user
.
email
==
decoded_token
[
"email"
]
assert
user
.
is_staff
==
(
"/staff"
in
decoded_token
[
"groups"
])
assert
user
.
sub
==
decoded_token
[
"sub"
]
@pytest.mark.django_db
def
test_oidc_code_pkce_auth_backend_success
(
mocker
,
request_factory
):
kc_oidc_mock
=
mock_keycloak
(
mocker
)
oidc_profile
=
sample_data
.
oidc_profile
user
=
_authenticate_user
(
request_factory
)
decoded_token
=
kc_oidc_mock
.
decode_token
(
user
.
access_token
)
_check_authenticated_user
(
user
,
decoded_token
)
auth_datetime
=
datetime
.
fromtimestamp
(
decoded_token
[
"auth_time"
])
exp_datetime
=
datetime
.
fromtimestamp
(
decoded_token
[
"exp"
])
refresh_exp_datetime
=
auth_datetime
+
timedelta
(
seconds
=
oidc_profile
[
"refresh_expires_in"
]
)
assert
user
.
access_token
==
oidc_profile
[
"access_token"
]
assert
user
.
expires_at
==
exp_datetime
assert
user
.
id_token
==
oidc_profile
[
"id_token"
]
assert
user
.
refresh_token
==
oidc_profile
[
"refresh_token"
]
assert
user
.
refresh_expires_at
==
refresh_exp_datetime
assert
user
.
scope
==
oidc_profile
[
"scope"
]
assert
user
.
session_state
==
oidc_profile
[
"session_state"
]
backend_path
=
"swh.web.auth.backends.OIDCAuthorizationCodePKCEBackend"
assert
user
.
backend
==
backend_path
backend_idx
=
settings
.
AUTHENTICATION_BACKENDS
.
index
(
backend_path
)
assert
get_backends
()[
backend_idx
]
.
get_user
(
user
.
id
)
==
user
@pytest.mark.django_db
def
test_oidc_code_pkce_auth_backend_failure
(
mocker
,
request_factory
):
mock_keycloak
(
mocker
,
auth_success
=
False
)
user
=
_authenticate_user
(
request_factory
)
assert
user
is
None
@pytest.mark.django_db
def
test_drf_oidc_bearer_token_auth_backend_success
(
mocker
,
api_request_factory
):
url
=
reverse
(
"api-1-stat-counters"
)
drf_auth_backend
=
OIDCBearerTokenAuthentication
()
kc_oidc_mock
=
mock_keycloak
(
mocker
)
access_token
=
sample_data
.
oidc_profile
[
"access_token"
]
decoded_token
=
kc_oidc_mock
.
decode_token
(
access_token
)
request
=
api_request_factory
.
get
(
url
,
HTTP_AUTHORIZATION
=
f
"Bearer {access_token}"
)
user
,
_
=
drf_auth_backend
.
authenticate
(
request
)
_check_authenticated_user
(
user
,
decoded_token
)
# oidc_profile is not filled when authenticating through bearer token
assert
hasattr
(
user
,
"access_token"
)
and
user
.
access_token
is
None
@pytest.mark.django_db
def
test_drf_oidc_bearer_token_auth_backend_failure
(
mocker
,
api_request_factory
):
url
=
reverse
(
"api-1-stat-counters"
)
drf_auth_backend
=
OIDCBearerTokenAuthentication
()
# simulate a failed authentication with a bearer token in expected format
mock_keycloak
(
mocker
,
auth_success
=
False
)
access_token
=
sample_data
.
oidc_profile
[
"access_token"
]
request
=
api_request_factory
.
get
(
url
,
HTTP_AUTHORIZATION
=
f
"Bearer {access_token}"
)
with
pytest
.
raises
(
AuthenticationFailed
):
drf_auth_backend
.
authenticate
(
request
)
# simulate a failed authentication with an invalid bearer token format
mock_keycloak
(
mocker
)
request
=
api_request_factory
.
get
(
url
,
HTTP_AUTHORIZATION
=
f
"Bearer invalid-token-format"
)
with
pytest
.
raises
(
AuthenticationFailed
):
drf_auth_backend
.
authenticate
(
request
)
def
test_drf_oidc_auth_invalid_or_missing_auth_type
(
api_request_factory
):
url
=
reverse
(
"api-1-stat-counters"
)
drf_auth_backend
=
OIDCBearerTokenAuthentication
()
access_token
=
sample_data
.
oidc_profile
[
"access_token"
]
# Invalid authorization type
request
=
api_request_factory
.
get
(
url
,
HTTP_AUTHORIZATION
=
f
"Foo token"
)
with
pytest
.
raises
(
AuthenticationFailed
):
drf_auth_backend
.
authenticate
(
request
)
# Missing authorization type
request
=
api_request_factory
.
get
(
url
,
HTTP_AUTHORIZATION
=
f
"{access_token}"
)
with
pytest
.
raises
(
AuthenticationFailed
):
drf_auth_backend
.
authenticate
(
request
)
File Metadata
Details
Attached
Mime Type
text/x-python
Expires
Fri, Jul 4, 2:19 PM (1 d, 23 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3322806
Attached To
rDWAPPS Web applications
Event Timeline
Log In to Comment