Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues/523 saml auth create email address objects #544

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion openwisp_radius/saml/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
from urllib.parse import parse_qs, quote, urlencode, urlparse

import swapper
from allauth.account.models import EmailAddress
from allauth.account.utils import send_email_confirmation
from allauth.utils import valid_email_or_none
from django import forms
from django.conf import settings
from django.contrib.auth import get_user_model, logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied, ValidationError
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.views.generic import UpdateView
Expand Down Expand Up @@ -78,6 +80,19 @@ def post_login_hook(self, request, user, session_info):
)
registered_user.full_clean()
registered_user.save()
# The user is just created, it will not have an email address
if user.email:
try:
email_address = EmailAddress(
user=user, email=user.email, primary=True, verified=True
)
email_address.full_clean()
email_address.save()
except ValidationError:
logger.exception(
f'Failed email validation for "{user}"'
' during SAML user creation'
)

def customize_relay_state(self, relay_state):
"""
Expand Down
29 changes: 27 additions & 2 deletions openwisp_radius/tests/test_saml/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,20 @@ class TestAssertionConsumerServiceView(TestSamlMixin, TestCase):
def _get_relay_state(self, redirect_url, org_slug):
return f'{redirect_url}?org={org_slug}'

def _get_saml_response_for_acs_view(self, relay_state):
def _get_saml_response_for_acs_view(self, relay_state, uid='org_user@example.com'):
response = self.client.get(self.login_url, {'RelayState': relay_state})
saml2_req = saml2_from_httpredirect_request(response.url)
session_id = get_session_id_from_saml2(saml2_req)
self.add_outstanding_query(session_id, relay_state)
return auth_response(session_id, 'org_user@example.com'), relay_state
return auth_response(session_id, uid), relay_state

def _post_successful_auth_assertions(self, query_params, org_slug):
self.assertEqual(User.objects.count(), 1)
user_id = self.client.session[SESSION_KEY]
user = User.objects.get(id=user_id)
self.assertEqual(
user.emailaddress_set.filter(verified=True, primary=True).count(), 1
)
self.assertEqual(user.username, 'org_user@example.com')
self.assertEqual(OrganizationUser.objects.count(), 1)
org_user = OrganizationUser.objects.get(user_id=user_id)
Expand Down Expand Up @@ -105,6 +108,28 @@ def test_organization_slug_present(self):
query_params = parse_qs(urlparse(response.url).query)
self._post_successful_auth_assertions(query_params, org_slug)

@capture_any_output()
def test_invalid_email_raise_validation_error(self):
invalid_email = 'invalid_email@example'
relay_state = self._get_relay_state(
redirect_url='https://captive-portal.example.com', org_slug='default'
)
saml_response, relay_state = self._get_saml_response_for_acs_view(
relay_state, uid=invalid_email
)
with patch('logging.Logger.exception') as mocked_logger:
self.client.post(
reverse('radius:saml2_acs'),
{
'SAMLResponse': self.b64_for_post(saml_response),
'RelayState': relay_state,
},
)
mocked_logger.assert_called_once_with(
'Failed email validation for "invalid_email@example" during'
' SAML user creation'
)

@capture_any_output()
def test_relay_state_relative_path(self):
expected_redirect_path = '/radius/saml2/additional-info/'
Expand Down
Loading