Skip to content

Commit 87a93aa

Browse files
kaushikaryan04pandafynemesifier
authored
[change] SAML now creates EmailAddress objects #523
Closes #523 --------- Co-authored-by: Gagan Deep <[email protected]> Co-authored-by: Federico Capoano <[email protected]>
1 parent dc8580f commit 87a93aa

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

openwisp_radius/saml/views.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
from urllib.parse import parse_qs, quote, urlencode, urlparse
33

44
import swapper
5+
from allauth.account.models import EmailAddress
56
from allauth.account.utils import send_email_confirmation
67
from django import forms
78
from django.conf import settings
89
from django.contrib.auth import get_user_model, logout
910
from django.contrib.auth.mixins import LoginRequiredMixin
10-
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
11+
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied, ValidationError
1112
from django.shortcuts import get_object_or_404, redirect, render
1213
from django.urls import reverse
1314
from django.views.generic import UpdateView
@@ -78,6 +79,19 @@ def post_login_hook(self, request, user, session_info):
7879
)
7980
registered_user.full_clean()
8081
registered_user.save()
82+
# The user is just created, it will not have an email address
83+
if user.email:
84+
try:
85+
email_address = EmailAddress(
86+
user=user, email=user.email, primary=True, verified=True
87+
)
88+
email_address.full_clean()
89+
email_address.save()
90+
except ValidationError:
91+
logger.exception(
92+
f'Failed email validation for "{user}"'
93+
' during SAML user creation'
94+
)
8195

8296
def customize_relay_state(self, relay_state):
8397
"""

openwisp_radius/tests/test_saml/test_views.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,20 @@ class TestAssertionConsumerServiceView(TestSamlMixin, TestCase):
6060
def _get_relay_state(self, redirect_url, org_slug):
6161
return f'{redirect_url}?org={org_slug}'
6262

63-
def _get_saml_response_for_acs_view(self, relay_state):
63+
def _get_saml_response_for_acs_view(self, relay_state, uid='[email protected]'):
6464
response = self.client.get(self.login_url, {'RelayState': relay_state})
6565
saml2_req = saml2_from_httpredirect_request(response.url)
6666
session_id = get_session_id_from_saml2(saml2_req)
6767
self.add_outstanding_query(session_id, relay_state)
68-
return auth_response(session_id, '[email protected]'), relay_state
68+
return auth_response(session_id, uid), relay_state
6969

7070
def _post_successful_auth_assertions(self, query_params, org_slug):
7171
self.assertEqual(User.objects.count(), 1)
7272
user_id = self.client.session[SESSION_KEY]
7373
user = User.objects.get(id=user_id)
74+
self.assertEqual(
75+
user.emailaddress_set.filter(verified=True, primary=True).count(), 1
76+
)
7477
self.assertEqual(user.username, '[email protected]')
7578
self.assertEqual(OrganizationUser.objects.count(), 1)
7679
org_user = OrganizationUser.objects.get(user_id=user_id)
@@ -105,6 +108,28 @@ def test_organization_slug_present(self):
105108
query_params = parse_qs(urlparse(response.url).query)
106109
self._post_successful_auth_assertions(query_params, org_slug)
107110

111+
@capture_any_output()
112+
def test_invalid_email_raise_validation_error(self):
113+
invalid_email = 'invalid_email@example'
114+
relay_state = self._get_relay_state(
115+
redirect_url='https://captive-portal.example.com', org_slug='default'
116+
)
117+
saml_response, relay_state = self._get_saml_response_for_acs_view(
118+
relay_state, uid=invalid_email
119+
)
120+
with patch('logging.Logger.exception') as mocked_logger:
121+
self.client.post(
122+
reverse('radius:saml2_acs'),
123+
{
124+
'SAMLResponse': self.b64_for_post(saml_response),
125+
'RelayState': relay_state,
126+
},
127+
)
128+
mocked_logger.assert_called_once_with(
129+
'Failed email validation for "invalid_email@example" during'
130+
' SAML user creation'
131+
)
132+
108133
@capture_any_output()
109134
def test_relay_state_relative_path(self):
110135
expected_redirect_path = '/radius/saml2/additional-info/'

0 commit comments

Comments
 (0)