from __future__ import absolute_import

from six.moves.urllib.parse import urlencode
from django.test import RequestFactory
from django.contrib.auth.models import AnonymousUser

from sentry.auth.helper import handle_new_user
from sentry.models import AuthProvider, InviteStatus, OrganizationMember
from sentry.testutils import TestCase
from sentry.utils.compat import mock


class HandleNewUserTest(TestCase):
    @mock.patch("sentry.analytics.record")
    def test_simple(self, mock_record):
        provider = "dummy"
        request = RequestFactory().post("/auth/sso/")
        request.user = AnonymousUser()

        auth_provider = AuthProvider.objects.create(
            organization=self.organization, provider=provider
        )
        identity = {"id": "1234", "email": "test@example.com", "name": "Morty"}

        auth_identity = handle_new_user(auth_provider, self.organization, request, identity)
        user = auth_identity.user

        assert user.email == identity["email"]
        assert OrganizationMember.objects.filter(organization=self.organization, user=user).exists()

        signup_record = [r for r in mock_record.call_args_list if r[0][0] == "user.signup"]
        assert signup_record == [
            mock.call(
                "user.signup", user_id=user.id, source="sso", provider=provider, referrer="in-app"
            )
        ]

    def test_associated_existing_member_invite_by_email(self):
        request = RequestFactory().post("/auth/sso/")
        request.user = AnonymousUser()

        provider = AuthProvider.objects.create(organization=self.organization, provider="dummy")
        identity = {"id": "1234", "email": "test@example.com", "name": "Morty"}

        member = OrganizationMember.objects.create(
            organization=self.organization, email=identity["email"]
        )

        auth_identity = handle_new_user(provider, self.organization, request, identity)

        assigned_member = OrganizationMember.objects.get(
            organization=self.organization, user=auth_identity.user
        )

        assert assigned_member.id == member.id

    def test_associated_existing_member_invite_request(self):
        request = RequestFactory().post("/auth/sso/")
        request.user = AnonymousUser()

        provider = AuthProvider.objects.create(organization=self.organization, provider="dummy")
        identity = {"id": "1234", "email": "test@example.com", "name": "Morty"}

        member = self.create_member(
            organization=self.organization,
            email=identity["email"],
            invite_status=InviteStatus.REQUESTED_TO_BE_INVITED.value,
        )

        auth_identity = handle_new_user(provider, self.organization, request, identity)

        assert OrganizationMember.objects.filter(
            organization=self.organization,
            user=auth_identity.user,
            invite_status=InviteStatus.APPROVED.value,
        ).exists()

        assert not OrganizationMember.objects.filter(id=member.id).exists()

    def test_associate_pending_invite(self):
        provider = AuthProvider.objects.create(organization=self.organization, provider="dummy")
        identity = {"id": "1234", "email": "test@example.com", "name": "Morty"}

        # The org member invite should have a non matching email, but the
        # member id and token will match from the cookie, allowing association
        member = OrganizationMember.objects.create(
            organization=self.organization, email="different.email@example.com", token="abc"
        )

        request = RequestFactory().post("/auth/sso/")
        request.user = AnonymousUser()
        request.COOKIES["pending-invite"] = urlencode(
            {"memberId": member.id, "token": member.token, "url": ""}
        )

        auth_identity = handle_new_user(provider, self.organization, request, identity)

        assigned_member = OrganizationMember.objects.get(
            organization=self.organization, user=auth_identity.user
        )

        assert assigned_member.id == member.id

[((415, 452), 'sentry.utils.compat.mock.patch', 'mock.patch', (['"""sentry.analytics.record"""'], {}), "('sentry.analytics.record')\n", (425, 452), False, 'from sentry.utils.compat import mock\n'), ((597, 612), 'django.contrib.auth.models.AnonymousUser', 'AnonymousUser', ([], {}), '()\n', (610, 612), False, 'from django.contrib.auth.models import AnonymousUser\n'), ((638, 716), 'sentry.models.AuthProvider.objects.create', 'AuthProvider.objects.create', ([], {'organization': 'self.organization', 'provider': 'provider'}), '(organization=self.organization, provider=provider)\n', (665, 716), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((844, 912), 'sentry.auth.helper.handle_new_user', 'handle_new_user', (['auth_provider', 'self.organization', 'request', 'identity'], {}), '(auth_provider, self.organization, request, identity)\n', (859, 912), False, 'from sentry.auth.helper import handle_new_user\n'), ((1510, 1525), 'django.contrib.auth.models.AnonymousUser', 'AnonymousUser', ([], {}), '()\n', (1523, 1525), False, 'from django.contrib.auth.models import AnonymousUser\n'), ((1546, 1623), 'sentry.models.AuthProvider.objects.create', 'AuthProvider.objects.create', ([], {'organization': 'self.organization', 'provider': '"""dummy"""'}), "(organization=self.organization, provider='dummy')\n", (1573, 1623), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((1722, 1817), 'sentry.models.OrganizationMember.objects.create', 'OrganizationMember.objects.create', ([], {'organization': 'self.organization', 'email': "identity['email']"}), "(organization=self.organization, email=\n    identity['email'])\n", (1755, 1817), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((1860, 1923), 'sentry.auth.helper.handle_new_user', 'handle_new_user', (['provider', 'self.organization', 'request', 'identity'], {}), '(provider, self.organization, request, identity)\n', (1875, 1923), False, 'from sentry.auth.helper import handle_new_user\n'), ((1951, 2043), 'sentry.models.OrganizationMember.objects.get', 'OrganizationMember.objects.get', ([], {'organization': 'self.organization', 'user': 'auth_identity.user'}), '(organization=self.organization, user=\n    auth_identity.user)\n', (1981, 2043), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((2249, 2264), 'django.contrib.auth.models.AnonymousUser', 'AnonymousUser', ([], {}), '()\n', (2262, 2264), False, 'from django.contrib.auth.models import AnonymousUser\n'), ((2285, 2362), 'sentry.models.AuthProvider.objects.create', 'AuthProvider.objects.create', ([], {'organization': 'self.organization', 'provider': '"""dummy"""'}), "(organization=self.organization, provider='dummy')\n", (2312, 2362), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((2667, 2730), 'sentry.auth.helper.handle_new_user', 'handle_new_user', (['provider', 'self.organization', 'request', 'identity'], {}), '(provider, self.organization, request, identity)\n', (2682, 2730), False, 'from sentry.auth.helper import handle_new_user\n'), ((3079, 3156), 'sentry.models.AuthProvider.objects.create', 'AuthProvider.objects.create', ([], {'organization': 'self.organization', 'provider': '"""dummy"""'}), "(organization=self.organization, provider='dummy')\n", (3106, 3156), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((3408, 3528), 'sentry.models.OrganizationMember.objects.create', 'OrganizationMember.objects.create', ([], {'organization': 'self.organization', 'email': '"""different.email@example.com"""', 'token': '"""abc"""'}), "(organization=self.organization, email=\n    'different.email@example.com', token='abc')\n", (3441, 3528), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((3624, 3639), 'django.contrib.auth.models.AnonymousUser', 'AnonymousUser', ([], {}), '()\n', (3637, 3639), False, 'from django.contrib.auth.models import AnonymousUser\n'), ((3684, 3752), 'six.moves.urllib.parse.urlencode', 'urlencode', (["{'memberId': member.id, 'token': member.token, 'url': ''}"], {}), "({'memberId': member.id, 'token': member.token, 'url': ''})\n", (3693, 3752), False, 'from six.moves.urllib.parse import urlencode\n'), ((3800, 3863), 'sentry.auth.helper.handle_new_user', 'handle_new_user', (['provider', 'self.organization', 'request', 'identity'], {}), '(provider, self.organization, request, identity)\n', (3815, 3863), False, 'from sentry.auth.helper import handle_new_user\n'), ((3891, 3983), 'sentry.models.OrganizationMember.objects.get', 'OrganizationMember.objects.get', ([], {'organization': 'self.organization', 'user': 'auth_identity.user'}), '(organization=self.organization, user=\n    auth_identity.user)\n', (3921, 3983), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((538, 554), 'django.test.RequestFactory', 'RequestFactory', ([], {}), '()\n', (552, 554), False, 'from django.test import RequestFactory\n'), ((1010, 1086), 'sentry.models.OrganizationMember.objects.filter', 'OrganizationMember.objects.filter', ([], {'organization': 'self.organization', 'user': 'user'}), '(organization=self.organization, user=user)\n', (1043, 1086), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((1235, 1332), 'sentry.utils.compat.mock.call', 'mock.call', (['"""user.signup"""'], {'user_id': 'user.id', 'source': '"""sso"""', 'provider': 'provider', 'referrer': '"""in-app"""'}), "('user.signup', user_id=user.id, source='sso', provider=provider,\n    referrer='in-app')\n", (1244, 1332), False, 'from sentry.utils.compat import mock\n'), ((1451, 1467), 'django.test.RequestFactory', 'RequestFactory', ([], {}), '()\n', (1465, 1467), False, 'from django.test import RequestFactory\n'), ((2190, 2206), 'django.test.RequestFactory', 'RequestFactory', ([], {}), '()\n', (2204, 2206), False, 'from django.test import RequestFactory\n'), ((2747, 2885), 'sentry.models.OrganizationMember.objects.filter', 'OrganizationMember.objects.filter', ([], {'organization': 'self.organization', 'user': 'auth_identity.user', 'invite_status': 'InviteStatus.APPROVED.value'}), '(organization=self.organization, user=\n    auth_identity.user, invite_status=InviteStatus.APPROVED.value)\n', (2780, 2885), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n'), ((3565, 3581), 'django.test.RequestFactory', 'RequestFactory', ([], {}), '()\n', (3579, 3581), False, 'from django.test import RequestFactory\n'), ((2957, 3004), 'sentry.models.OrganizationMember.objects.filter', 'OrganizationMember.objects.filter', ([], {'id': 'member.id'}), '(id=member.id)\n', (2990, 3004), False, 'from sentry.models import AuthProvider, InviteStatus, OrganizationMember\n')]