from __future__ import absolute_import import six from django.core.urlresolvers import reverse from sentry.models import AuthIdentity, AuthProvider from sentry.testutils import AuthProviderTestCase from sentry.utils.auth import SSO_SESSION_KEY from sentry.utils.linksign import generate_signed_link class AuthenticationTest(AuthProviderTestCase): def test_sso_auth_required(self): user = self.create_user('foo@example.com', is_superuser=False) organization = self.create_organization(name='foo') team = self.create_team(name='bar', organization=organization) project = self.create_project( name='baz', organization=organization, teams=[team]) member = self.create_member( user=user, organization=organization, teams=[team]) setattr(member.flags, 'sso:linked', True) member.save() group = self.create_group(project=project) self.create_event(group=group) auth_provider = AuthProvider.objects.create( organization=organization, provider='dummy', flags=0, ) AuthIdentity.objects.create( auth_provider=auth_provider, user=user, ) self.login_as(user) paths = ( u'/api/0/organizations/{}/'.format(organization.slug), u'/api/0/projects/{}/{}/'.format(organization.slug, project.slug), u'/api/0/teams/{}/{}/'.format(organization.slug, team.slug), u'/api/0/issues/{}/'.format(group.id), # this uses the internal API, which once upon a time was broken u'/api/0/issues/{}/events/latest/'.format(group.id), ) for path in paths: # we should be redirecting the user to the authentication form as they # haven't verified this specific organization resp = self.client.get(path) assert resp.status_code == 401, (resp.status_code, resp.content) # superuser should still require SSO as they're a member of the org user.update(is_superuser=True) for path in paths: resp = self.client.get(path) assert resp.status_code == 401, (resp.status_code, resp.content) # XXX(dcramer): using internal API as exposing a request object is hard self.session[SSO_SESSION_KEY] = six.text_type(organization.id) self.save_session() # now that SSO is marked as complete, we should be able to access dash for path in paths: resp = self.client.get(path) assert resp.status_code == 200, (path, resp.status_code, resp.content) def test_sso_auth_required_signed_link(self): user = self.create_user('foo@example.com', is_superuser=False) organization = self.create_organization(name='foo') team = self.create_team(name='bar', organization=organization) project = self.create_project( name='baz', organization=organization, teams=[team]) member = self.create_member( user=user, organization=organization, teams=[team]) setattr(member.flags, 'sso:linked', True) member.save() group = self.create_group(project=project) self.create_event(group=group) auth_provider = AuthProvider.objects.create( organization=organization, provider='dummy', flags=0, ) AuthIdentity.objects.create( auth_provider=auth_provider, user=user, ) self.login_as(user) unsigned_link = reverse( 'sentry-api-0-project-fix-processing-issues', kwargs={ 'project_slug': project.slug, 'organization_slug': organization.slug, } ) resp = self.client.get(unsigned_link) assert resp.status_code == 401, (resp.status_code, resp.content) signed_link = generate_signed_link( user, 'sentry-api-0-project-fix-processing-issues', kwargs={ 'project_slug': project.slug, 'organization_slug': organization.slug, } ) resp = self.client.get(signed_link) assert resp.status_code == 200