def setUp(self): self.owner = self.create_user() self.org = self.create_organization(owner=self.owner) self.member = self.create_user() self.member_om = self.create_member( organization=self.org, user=self.member, role="member", teams=[] ) self.login_as(self.member) totp = TotpInterface() totp.enroll(self.member) self.interface_id = totp.authenticator.id assert Authenticator.objects.filter(user=self.member).exists()
def test_get_authenticator_details(self): interface = TotpInterface() interface.enroll(self.user) auth = interface.authenticator resp = self.get_success_response(self.user.id, auth.id) assert resp.data["isEnrolled"] assert resp.data["id"] == "totp" assert resp.data["authId"] == str(auth.id) # should not have these because enrollment assert "totp_secret" not in resp.data assert "form" not in resp.data assert "qrcode" not in resp.data
def test_require_2fa__cannot_delete_last_auth(self): self._require_2fa_for_organization() # enroll in one auth method interface = TotpInterface() interface.enroll(self.user) auth = interface.authenticator with self.tasks(): resp = self.get_error_response(self.user.id, auth.id, method="delete", status_code=403) assert b"requires 2FA" in resp.content assert Authenticator.objects.filter(id=auth.id).exists() assert len(mail.outbox) == 0
def test_require_2fa__can_delete_last_auth_superuser(self): self._require_2fa_for_organization() superuser = self.create_user(email="*****@*****.**", is_superuser=True) self.login_as(user=superuser, superuser=True) # enroll in one auth method interface = TotpInterface() interface.enroll(self.user) auth = interface.authenticator with self.tasks(): self.get_success_response(self.user.id, auth.id, method="delete", status_code=204) assert_security_email_sent("mfa-removed") assert not Authenticator.objects.filter(id=auth.id).exists()
def test_get_authenticator_details(self): interface = TotpInterface() interface.enroll(self.user) auth = interface.authenticator url = reverse( "sentry-api-0-user-authenticator-details", kwargs={"user_id": self.user.id, "auth_id": auth.id}, ) resp = self.client.get(url) assert resp.status_code == 200 assert resp.data["isEnrolled"] assert resp.data["id"] == "totp" assert resp.data["authId"] == six.text_type(auth.id) # should not have these because enrollment assert "totp_secret" not in resp.data assert "form" not in resp.data assert "qrcode" not in resp.data
def test_require_2fa__cannot_delete_last_auth(self, email_log): self._require_2fa_for_organization() # enroll in one auth method interface = TotpInterface() interface.enroll(self.user) auth = interface.authenticator url = reverse( "sentry-api-0-user-authenticator-details", kwargs={"user_id": self.user.id, "auth_id": auth.id}, ) resp = self.client.delete(url, format="json") assert resp.status_code == 403, (resp.status_code, resp.content) assert b"requires 2FA" in resp.content assert Authenticator.objects.filter(id=auth.id).exists() assert email_log.info.call_count == 0
def test_various_options(self): initial = self.organization.get_audit_log_data() AuditLogEntry.objects.filter(organization=self.organization).delete() data = { "openMembership": False, "isEarlyAdopter": True, "allowSharedIssues": False, "enhancedPrivacy": True, "dataScrubber": True, "dataScrubberDefaults": True, "sensitiveFields": ["password"], "eventsMemberAdmin": False, "alertsMemberWrite": False, "safeFields": ["email"], "storeCrashReports": 10, "scrubIPAddresses": True, "scrapeJavaScript": False, "defaultRole": "owner", "require2FA": True, "allowJoinRequests": False, "apdexThreshold": 450, } # needed to set require2FA interface = TotpInterface() interface.enroll(self.user) assert Authenticator.objects.user_has_2fa(self.user) self.get_success_response(self.organization.slug, **data) org = Organization.objects.get(id=self.organization.id) assert initial != org.get_audit_log_data() assert org.flags.early_adopter assert not org.flags.allow_joinleave assert org.flags.disable_shared_issues assert org.flags.enhanced_privacy assert org.flags.require_2fa assert org.default_role == "owner" options = { o.key: o.value for o in OrganizationOption.objects.filter(organization=org) } assert options.get("sentry:require_scrub_defaults") assert options.get("sentry:require_scrub_data") assert options.get("sentry:require_scrub_ip_address") assert options.get("sentry:sensitive_fields") == ["password"] assert options.get("sentry:safe_fields") == ["email"] assert options.get("sentry:store_crash_reports") == 10 assert options.get("sentry:scrape_javascript") is False assert options.get("sentry:join_requests") is False assert options.get("sentry:events_member_admin") is False assert options.get("sentry:apdex_threshold") == 450 # log created log = AuditLogEntry.objects.get(organization=org) assert log.get_event_display() == "org.edit" # org fields & flags assert "to {}".format(data["defaultRole"]) in log.data["default_role"] assert "to {}".format( data["openMembership"]) in log.data["allow_joinleave"] assert "to {}".format( data["isEarlyAdopter"]) in log.data["early_adopter"] assert "to {}".format( data["enhancedPrivacy"]) in log.data["enhanced_privacy"] assert "to {}".format( not data["allowSharedIssues"]) in log.data["disable_shared_issues"] assert "to {}".format(data["require2FA"]) in log.data["require_2fa"] # org options assert "to {}".format(data["dataScrubber"]) in log.data["dataScrubber"] assert "to {}".format( data["dataScrubberDefaults"]) in log.data["dataScrubberDefaults"] assert "to {}".format( data["sensitiveFields"]) in log.data["sensitiveFields"] assert "to {}".format(data["safeFields"]) in log.data["safeFields"] assert "to {}".format( data["storeCrashReports"]) in log.data["storeCrashReports"] assert "to {}".format( data["scrubIPAddresses"]) in log.data["scrubIPAddresses"] assert "to {}".format( data["scrapeJavaScript"]) in log.data["scrapeJavaScript"] assert "to {}".format( data["allowJoinRequests"]) in log.data["allowJoinRequests"] assert "to {}".format( data["eventsMemberAdmin"]) in log.data["eventsMemberAdmin"] assert "to {}".format( data["alertsMemberWrite"]) in log.data["alertsMemberWrite"] assert "to {}".format( data["apdexThreshold"]) in log.data["apdexThreshold"]
def _enroll_user_in_2fa(self): interface = TotpInterface() interface.enroll(self.user) assert Authenticator.objects.user_has_2fa(self.user)