def send_invitation(self, invite, request, **kwargs): current_site = kwargs.pop('site', Site.objects.get_current()) invite_url = reverse('geonode.invitations:accept-invite', args=[invite.key]) invite_url = request.build_absolute_uri(invite_url) ctx = kwargs ctx.update({ 'invite_url': invite_url, 'site_name': current_site.name, 'email': invite.email, 'key': invite.key, 'inviter': invite.inviter, }) email_template = 'invitations/email/email_invite' get_invitations_adapter().send_mail( email_template, invite.email, ctx) invite.sent = timezone.now() invite.save() signals.invite_url_sent.send( sender=invite.__class__, instance=invite, invite_url_sent=invite_url, inviter=invite.inviter)
def send_invitation(self, request, **kwargs): surveyor = Surveyor.objects.get(user=self.inviter) if not self.is_respondent: self.organisation = surveyor.organisation current_site = kwargs.pop('site', Site.objects.get_current()) invite_url = reverse('invitations:accept-invite', args=[self.key]) invite_url = request.build_absolute_uri(invite_url) ctx = kwargs ctx.update({ 'invite_url': invite_url, 'site_name': current_site.name, 'email': self.email, 'key': self.key, 'inviter': self.inviter, }) # Dictionary passed into the invitation for checks later. email_template = 'invitations/email/email_invite' get_invitations_adapter().send_mail(email_template, self.email, ctx) self.sent = timezone.now() self.save() signals.invite_url_sent.send(sender=self.__class__, instance=self, invite_url_sent=invite_url, inviter=self.inviter)
def send_invitation(self, request, **kwargs): current_site = (kwargs['site'] if 'site' in kwargs else Site.objects.get_current()) invite_url = reverse('invitations:accept-invite', args=[self.key]) invite_url = request.build_absolute_uri(invite_url) ctx = RequestContext(request, { 'invite_url': invite_url, 'site_name': current_site.name, 'email': self.email, 'key': self.key, 'inviter': self.inviter.email or 'a FireCARES department administrator', 'department': self.departmentinvitation.department }) email_template = 'invitations/email/email_invite' get_invitations_adapter().send_mail( email_template, self.email, ctx) self.sent = timezone.now() self.save() signals.invite_url_sent.send( sender=self.__class__, instance=self, invite_url_sent=invite_url, inviter=self.inviter)
def _notify_account_activated(self): """Notify user that its account has been activated by a staff member""" became_active = self.is_active and not self._previous_active_state if became_active and self.last_login is None: try: # send_notification(users=(self,), label="account_active") from invitations.adapters import get_invitations_adapter current_site = Site.objects.get_current() ctx = { 'username': self.username, 'current_site': current_site, 'site_name': current_site.name, 'email': self.email, 'inviter': self, } email_template = 'pinax/notifications/account_active/account_active' get_invitations_adapter().send_mail( email_template, self.email, ctx) except BaseException: import traceback traceback.print_exc()
def _notify_account_activated(self): """Notify user that its account has been activated by a staff member""" became_active = self.is_active and not self._previous_active_state if became_active and self.last_login is None: try: # send_notification(users=(self,), label="account_active") from invitations.adapters import get_invitations_adapter current_site = Site.objects.get_current() ctx = { 'username': self.username, 'current_site': current_site, 'site_name': current_site.name, 'email': self.email, 'inviter': self, } email_template = 'pinax/notifications/account_active/account_active' get_invitations_adapter().send_mail( email_template, self.email, ctx) except Exception: import traceback traceback.print_exc()
def post(self, *args, **kwargs): self.object = invitation = self.get_object() # Compatibility with older versions: return an HTTP 410 GONE if there # is an error. # Error conditions are: no key, expired key or # previously accepted key. if app_settings.GONE_ON_ACCEPT_ERROR and \ (not invitation or (invitation and (invitation.accepted or invitation.key_expired()))): return HttpResponse(status=410) # No invitation was found. if not invitation: # Newer behavior: show an error message and redirect. get_invitations_adapter().add_message( self.request, messages.ERROR, 'invitations/messages/invite_invalid.txt') return redirect(app_settings.LOGIN_REDIRECT) # The invitation was previously accepted, redirect to the login # view. if invitation.accepted: get_invitations_adapter().add_message( self.request, messages.ERROR, 'invitations/messages/invite_already_accepted.txt', {'email': invitation.email}) # Redirect to login since there's hopefully an account already. return redirect(app_settings.LOGIN_REDIRECT) # The key was expired. if invitation.key_expired(): get_invitations_adapter().add_message( self.request, messages.ERROR, 'invitations/messages/invite_expired.txt', {'email': invitation.email}) # Redirect to sign-up since they might be able to register anyway. return redirect(app_settings.SIGNUP_REDIRECT) get_invitations_adapter().stash_verified_email(self.request, invitation.email) get_invitations_adapter().add_message( self.request, messages.SUCCESS, 'invitations/messages/invite_accepted.txt', {'email': invitation.email}) return redirect(app_settings.SIGNUP_REDIRECT)
class TestAllAuthIntegrationAcceptAfterSignup: client = Client() adapter = get_invitations_adapter() @pytest.mark.parametrize('method', [ ('get'), ('post'), ]) def test_accept_invite_accepted_invitation_after_signup( self, settings, method, sent_invitation_by_user_a, user_a): settings.INVITATIONS_ACCEPT_INVITE_AFTER_SIGNUP = True client_with_method = getattr(self.client, method) resp = client_with_method(reverse( 'invitations:accept-invite', kwargs={'key': sent_invitation_by_user_a.key}), follow=True) assert resp.status_code == 200 invite = Invitation.objects.get(email='*****@*****.**') assert invite.inviter == user_a assert invite.accepted is False assert resp.request['PATH_INFO'] == reverse('account_signup') form = resp.context_data['form'] assert '*****@*****.**' == form.fields['email'].initial resp = self.client.post( reverse('account_signup'), { 'email': '*****@*****.**', 'username': '******', 'password1': 'password', 'password2': 'password' }) invite = Invitation.objects.get(email='*****@*****.**') assert invite.accepted is True
def setUpClass(cls): cls.user = get_user_model().objects.create_user( username='******', password='******') cls.invitation = Invitation.create( '*****@*****.**', inviter=cls.user) cls.adapter = get_invitations_adapter()
def clean_email(self): emails = self.cleaned_data["email"] emails = emails.replace(";", ",").split(",") for em in emails: email = get_invitations_adapter().clean_email(em.strip()) errors = { "already_invited": _(f"The e-mail address '{email}' has already been invited."), "already_accepted": _(f"The e-mail address '{email}' has already accepted an invite." ), "email_in_use": _(f"An active user is already using the e-mail address '{email}'" ), } try: self.validate_invitation(email) except (AlreadyInvited): raise forms.ValidationError(errors["already_invited"]) except (AlreadyAccepted): raise forms.ValidationError(errors["already_accepted"]) except (UserRegisteredEmail): raise forms.ValidationError(errors["email_in_use"]) return emails
def send_invitation(self, request): """Extend method to add the invite object to the template context.""" context = dict( inviter=self.inviter, inviter_name=self.inviter.get_full_name() or self.inviter.username, invite_message=self.message, invite_url=request.build_absolute_uri( reverse("ui-users-invites-accept", args=[self.key])), reason_for_sending= "This email was sent by user '{0}' to invite you to " "collaborate with them on Stencila Hub.".format( self.inviter.username), ) get_invitations_adapter().send_mail("invitations/email/email_invite", self.email, context) self.sent = timezone.now() self.save()
def setUpClass(cls): cls.user = get_user_model().objects.create_user(username='******', password='******') cls.invitation = Invitation.create('*****@*****.**', inviter=cls.user) cls.invitation.sent = timezone.now() cls.invitation.save() cls.adapter = get_invitations_adapter()
class TestAllAuthIntegration: client = Client() adapter = get_invitations_adapter() @pytest.mark.parametrize('method', [ ('get'), ('post'), ]) def test_accept_invite_allauth(self, method, settings, user_a, sent_invitation_by_user_a): client_with_method = getattr(self.client, method) resp = client_with_method(reverse( 'invitations:accept-invite', kwargs={'key': sent_invitation_by_user_a.key}), follow=True) invite = Invitation.objects.get(email='*****@*****.**') assert invite.accepted assert invite.inviter == user_a assert resp.request['PATH_INFO'] == reverse('account_signup') form = resp.context_data['form'] assert '*****@*****.**' == form.fields['email'].initial messages = resp.context['messages'] message_text = [message.message for message in messages] assert ('Invitation to - [email protected] - has been accepted' in message_text) resp = self.client.post( reverse('account_signup'), { 'email': '*****@*****.**', 'username': '******', 'password1': 'password', 'password2': 'password' }) allauth_email_obj = EmailAddress.objects.get(email='*****@*****.**') assert allauth_email_obj.verified is True def test_fetch_adapter(self): assert isinstance(self.adapter, InvitationsAdapter) def test_allauth_signup_open(self): signup_request = RequestFactory().get( reverse('account_signup', urlconf='allauth.account.urls')) assert self.adapter.is_open_for_signup(signup_request) is True @pytest.mark.django_db def test_allauth_adapter_invitations_only(self, settings): settings.INVITATIONS_INVITATION_ONLY = True signup_request = RequestFactory().get( reverse('account_signup', urlconf='allauth.account.urls')) assert self.adapter.is_open_for_signup(signup_request) is False response = self.client.get(reverse('account_signup')) assert 'Sign Up Closed' in response.content.decode('utf8')
def validate_email(self, email): email = get_invitations_adapter().clean_email(email) try: self._validate_invitation(email) except (AlreadyInvited): raise serializers.ValidationError(errors["already_invited"]) except (AlreadyAccepted): raise serializers.ValidationError(errors["already_accepted"]) except (UserRegisteredEmail): raise serializers.ValidationError(errors["email_in_use"]) return email
def accept_invitation(request, key): def get_object(): try: return InvitationModel.objects.get(key=key.lower()) except InvitationModel.DoesNotExist: return None invitation = get_object() login_data = {'LOGIN_REDIRECT': invitations_settings.LOGIN_REDIRECT} signup_data = {'SIGNUP_REDIRECT': invitations_settings.SIGNUP_REDIRECT} if invitations_settings.GONE_ON_ACCEPT_ERROR and \ (not invitation or (invitation and (invitation.accepted or invitation.key_expired()))): return Response(status=status.HTTP_410_GONE) if not invitation: get_invitations_adapter().add_message( request, messages.ERROR, 'invitations/messages/invite_invalid.txt') return Response(login_data, status=status.HTTP_200_OK) if invitation.accepted: get_invitations_adapter().add_message( request, messages.ERROR, 'invitations/messages/invite_already_accepted.txt', {'email': invitation.email}) return Response(login_data, status=status.HTTP_200_OK) if invitation.key_expired(): get_invitations_adapter().add_message( request, messages.ERROR, 'invitations/messages/invite_expired.txt', {'email': invitation.email}) return Response(signup_data, status=status.HTTP_200_OK) if not invitations_settings.ACCEPT_INVITE_AFTER_SIGNUP: invitation.accepted = True invitation.save() invite_accepted.send(sender=None, email=invitation.email) get_invitations_adapter().add_message( request, messages.SUCCESS, 'invitations/messages/invite_accepted.txt', {'email': invitation.email}) signup_data.update({'account_verified_email': invitation.email}) if OUTBOUND_REDIRECT_ENABLED: return redirect(ACCEPT_INVITE_OUTBOUND_REDIRECT) return Response(signup_data, status=status.HTTP_200_OK)
def validate_email(self, email_list): if len(email_list) == 0: raise serializers.ValidationError( _('You must add one or more email addresses')) for email in email_list: email = get_invitations_adapter().clean_email(email) try: self._validate_invitation(email) except (AlreadyInvited): raise serializers.ValidationError(errors["already_invited"]) except (AlreadyAccepted): raise serializers.ValidationError(errors["already_accepted"]) except (UserRegisteredEmail): raise serializers.ValidationError(errors["email_in_use"]) return email_list
def clean_email(self): emails = self.cleaned_data["email"] emails = emails.replace(";", ",").split(",") for em in emails: email = get_invitations_adapter().clean_email(em.strip()) errors = { "already_invited": _("The e-mail address '%(email)s' has already been" " invited." % {"email": email}), "already_accepted": _("The e-mail address '%(email)s' has already" " accepted an invite." % {"email": email}), "email_in_use": _("An active user is already using the" " e-mail address '%(email)s'" % {"email": email}), } try: self.validate_invitation(email) except(AlreadyInvited): raise forms.ValidationError(errors["already_invited"]) except(AlreadyAccepted): raise forms.ValidationError(errors["already_accepted"]) except(UserRegisteredEmail): raise forms.ValidationError(errors["email_in_use"]) return emails
def test_email_subject_prefix_settings_with_custom_override(self): adapter = get_invitations_adapter() result = adapter.format_email_subject('Bar') assert result == 'Bar'
def test_email_subject_prefix_settings_with_custom_override(self): adapter = get_invitations_adapter() result = adapter.format_email_subject("Bar", context={"site_name": "Foo.com"}) assert result == "Bar"
def test_email_subject_prefix_settings_with_custom_override(self): adapter = get_invitations_adapter() result = adapter.format_email_subject('Bar') assert result == 'Bar'
def test_email_subject_prefix_settings_with_site(self): adapter = get_invitations_adapter() with patch('invitations.adapters.Site') as MockSite: MockSite.objects.get_current.return_value.name = 'Foo.com' result = adapter.format_email_subject('Bar') assert result == '[Foo.com] Bar'
def test_fetch_adapter(self): adapter = get_invitations_adapter() assert isinstance(adapter, BaseInvitationsAdapter)
def setUp(cls): cls.adapter = get_invitations_adapter()
class TestAllAuthIntegration: client = Client() adapter = get_invitations_adapter() @pytest.mark.parametrize( "method", [ ("get"), ("post"), ], ) def test_accept_invite_allauth( self, method, settings, user_a, sent_invitation_by_user_a, ): client_with_method = getattr(self.client, method) resp = client_with_method( reverse( app_settings.CONFIRMATION_URL_NAME, kwargs={"key": sent_invitation_by_user_a.key}, ), follow=True, ) invite = Invitation.objects.get(email="*****@*****.**") assert invite.accepted assert invite.inviter == user_a assert resp.request["PATH_INFO"] == reverse("account_signup") form = resp.context_data["form"] assert "*****@*****.**" == form.fields["email"].initial messages = resp.context["messages"] message_text = [message.message for message in messages] assert "Invitation to - [email protected] - has been accepted" in message_text resp = self.client.post( reverse("account_signup"), { "email": "*****@*****.**", "username": "******", "password1": "password", "password2": "password", }, ) allauth_email_obj = EmailAddress.objects.get(email="*****@*****.**") assert allauth_email_obj.verified is True def test_fetch_adapter(self): assert isinstance(self.adapter, InvitationsAdapter) def test_allauth_signup_open(self): signup_request = RequestFactory().get( reverse("account_signup", urlconf="allauth.account.urls"), ) assert self.adapter.is_open_for_signup(signup_request) is True @pytest.mark.django_db def test_allauth_adapter_invitations_only(self, settings): settings.INVITATIONS_INVITATION_ONLY = True signup_request = RequestFactory().get( reverse("account_signup", urlconf="allauth.account.urls"), ) assert self.adapter.is_open_for_signup(signup_request) is False response = self.client.get(reverse("account_signup")) assert "Sign Up Closed" in response.content.decode("utf8")
def test_email_subject_prefix_settings_with_site(self): adapter = get_invitations_adapter() with patch('invitations.adapters.Site') as MockSite: MockSite.objects.get_current.return_value.name = 'Foo.com' result = adapter.format_email_subject('Bar') assert result == '[Foo.com] Bar'
class TestAllAuthIntegrationAcceptAfterSignup: client = Client() adapter = get_invitations_adapter() @pytest.mark.parametrize( "method", [ ("get"), ("post"), ], ) def test_accept_invite_accepted_invitation_after_signup( self, settings, method, sent_invitation_by_user_a, user_a, ): settings.INVITATIONS_ACCEPT_INVITE_AFTER_SIGNUP = True client_with_method = getattr(self.client, method) resp = client_with_method( reverse( app_settings.CONFIRMATION_URL_NAME, kwargs={"key": sent_invitation_by_user_a.key}, ), follow=True, ) assert resp.status_code == 200 invite = Invitation.objects.get(email="*****@*****.**") assert invite.inviter == user_a assert invite.accepted is False assert resp.request["PATH_INFO"] == reverse("account_signup") form = resp.context_data["form"] assert "*****@*****.**" == form.fields["email"].initial resp = self.client.post( reverse("account_signup"), { "email": "*****@*****.**", "username": "******", "password1": "password", "password2": "password", }, ) invite = Invitation.objects.get(email="*****@*****.**") assert invite.accepted is True @pytest.mark.parametrize( "method", [ ("get"), ("post"), ], ) def test_invite_accepted_after_signup_with_altered_case_email( self, settings, method, sent_invitation_by_user_a, user_a, ): settings.INVITATIONS_ACCEPT_INVITE_AFTER_SIGNUP = True client_with_method = getattr(self.client, method) resp = client_with_method( reverse( app_settings.CONFIRMATION_URL_NAME, kwargs={"key": sent_invitation_by_user_a.key}, ), follow=True, ) invite = Invitation.objects.get(email="*****@*****.**") assert invite.accepted is False form = resp.context_data["form"] assert "*****@*****.**" == form.fields["email"].initial resp = self.client.post( reverse("account_signup"), { "email": "*****@*****.**", "username": "******", "password1": "password", "password2": "password", }, ) invite = Invitation.objects.get(email="*****@*****.**") assert invite.accepted is True
def test_fetch_adapter(self): adapter = get_invitations_adapter() assert isinstance(adapter, BaseInvitationsAdapter)
def setUp(cls): cls.adapter = get_invitations_adapter()