We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
User invite accept screen leaks 'project names' of projects that the new user does not necessarily have access rights to
<!--

Do you want to ask a question? Are you looking for support? The Sentry message
board is the best place for getting support: https://forum.sentry.io
-->

## Important Details

How are you running Sentry?

* [ ] On-Premise docker [Version xyz]
* [x] Saas (sentry.io)
* [ ] Other [briefly describe your environment]

## Description

We are providing sentry as a service with our products to our customer, as a result we have internal teams but would also like to invite external users (customers) to specific projects. We are able to utilise the team construct for this and setup special customer teams with limited access.

When we however invite customers into our org to become member of this restricted team the customer received a generic org invite email and is redirected to a generic org invite screen:
https://sentry.io/accept/xyz/xyz

This invite accept screen provides a list of 'active' projects with full project name, however the user does not necessary have access to these projects. 

We would classify this as a security concern and leak of 'restricted' information. 

## Steps to Reproduce

1. open org
2. create 2 new teams
    - team A
    - team B
2. create 2 new projects
    - project A, assign access to team A
    - project B, assign access to team B
3. invite new user to org (as member level) and assign acces to team B only
4. user receives invite by email and opens the accept link
5. on the accept webpage notice that both project A and B are listed to be part of this org

### What you expected to happen

The recommendation is to hide the project names completely in this view, or restrict it to the projects the new user has access to based on his team assignment.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/sentry/web/frontend/accept_organization_invite.py`
Content:
```
1 from __future__ import absolute_import
2 
3 from django import forms
4 from django.contrib import messages
5 from django.core.urlresolvers import reverse
6 from django.utils.crypto import constant_time_compare
7 from django.utils.translation import ugettext_lazy as _
8 
9 from sentry.models import AuditLogEntryEvent, Authenticator, OrganizationMember, Project
10 from sentry.signals import member_joined
11 from sentry.utils import auth
12 from sentry.web.frontend.base import BaseView
13 
14 ERR_INVITE_INVALID = _('The invite link you followed is not valid, or has expired.')
15 PENDING_INVITE = 'pending-invite'
16 COOKIE_MAX_AGE = 60 * 60 * 24 * 7  # 7 days
17 
18 
19 class AcceptInviteForm(forms.Form):
20     pass
21 
22 
23 class AcceptOrganizationInviteView(BaseView):
24     auth_required = False
25 
26     def get_form(self, request):
27         if request.method == 'POST':
28             return AcceptInviteForm(request.POST)
29         return AcceptInviteForm()
30 
31     def redirect_with_err_message(self, request):
32         messages.add_message(
33             request,
34             messages.ERROR,
35             ERR_INVITE_INVALID,
36         )
37 
38         return self.redirect(reverse('sentry'))
39 
40     def handle(self, request, member_id, token):
41         assert request.method in ('POST', 'GET')
42 
43         try:
44             helper = WebInviteHelper(
45                 instance=self,
46                 request=request,
47                 member_id=member_id,
48                 token=token
49             )
50         except OrganizationMember.DoesNotExist:
51             return self.redirect_with_err_message(request)
52 
53         if not helper.member_pending or not helper.valid_token:
54             return self.redirect_with_err_message(request)
55 
56         om = helper.om
57         organization = om.organization
58 
59         qs = Project.objects.filter(
60             organization=organization,
61         )
62         project_list = list(qs[:25])
63         project_count = qs.count()
64 
65         context = {
66             'org_name': organization.name,
67             'project_list': project_list,
68             'project_count': project_count,
69             'needs_authentication': not helper.user_authenticated,
70             'needs_2fa': helper.needs_2fa,
71             'logout_url': u'{}?next={}'.format(
72                 reverse('sentry-logout'),
73                 request.path,
74             ),
75             'login_url': u'{}?next={}'.format(
76                 reverse('sentry-login'),
77                 request.path,
78             ),
79             'register_url': u'{}?next={}'.format(
80                 reverse('sentry-register'),
81                 request.path,
82             ),
83         }
84 
85         if not helper.user_authenticated:
86             # Show login or register form
87             auth.initiate_login(request, next_url=request.get_full_path())
88             request.session['can_register'] = True
89             request.session['invite_email'] = om.email
90 
91             return self.respond('sentry/accept-organization-invite.html', context)
92 
93         if helper.needs_2fa:
94             # redirect to setup 2fa
95             response = self.respond('sentry/accept-organization-invite.html', context)
96             response.set_cookie(PENDING_INVITE, request.path, max_age=COOKIE_MAX_AGE)
97             return response
98 
99         # if they're already a member of the organization its likely they're
100         # using a shared account and either previewing this invite or
101         # are incorrectly expecting this to create a new account for them
102         context['existing_member'] = helper.member_already_exists
103 
104         form = self.get_form(request)
105         if form.is_valid():
106             helper.accept_invite()
107 
108             request.session.pop('can_register', None)
109             response = self.redirect(reverse('sentry-organization-home', args=[organization.slug]))
110             return helper.remove_invite_cookie(response)
111 
112         context['form'] = form
113         return self.respond('sentry/accept-organization-invite.html', context)
114 
115 
116 class BaseInviteHelper(object):
117     def __init__(self, instance, request, member_id, token, logger=None):
118         self.request = request
119         self.instance = instance
120         self.member_id = member_id
121         self.token = token
122         self.logger = logger
123         self.om = self.get_organization_member()
124 
125     def handle_success(self):
126         pass
127 
128     def handle_member_already_exists(self):
129         pass
130 
131     def get_organization_member(self):
132         return OrganizationMember.objects.select_related('organization').get(pk=self.member_id)
133 
134     @property
135     def member_pending(self):
136         return self.om.is_pending
137 
138     @property
139     def valid_token(self):
140         if self.om.token_expired:
141             return False
142         return constant_time_compare(self.om.token or self.om.legacy_token, self.token)
143 
144     @property
145     def user_authenticated(self):
146         return self.request.user.is_authenticated()
147 
148     @property
149     def needs_2fa(self):
150         org_requires_2fa = self.om.organization.flags.require_2fa.is_set
151         user_has_2fa = Authenticator.objects.user_has_2fa(self.request.user.id)
152         return org_requires_2fa and not user_has_2fa
153 
154     @property
155     def member_already_exists(self):
156         return OrganizationMember.objects.filter(
157             organization=self.om.organization, user=self.request.user
158         ).exists()
159 
160     def accept_invite(self):
161         om = self.om
162 
163         if self.member_already_exists:
164             self.handle_member_already_exists()
165             om.delete()
166         else:
167             om.set_user(self.request.user)
168             om.save()
169 
170             self.instance.create_audit_entry(
171                 self.request,
172                 organization=om.organization,
173                 target_object=om.id,
174                 target_user=self.request.user,
175                 event=AuditLogEntryEvent.MEMBER_ACCEPT,
176                 data=om.get_audit_log_data(),
177             )
178 
179             self.handle_success()
180 
181     def remove_invite_cookie(self, response):
182         if PENDING_INVITE in self.request.COOKIES:
183             response.delete_cookie(PENDING_INVITE)
184         return response
185 
186 
187 class WebInviteHelper(BaseInviteHelper):
188     def handle_success(self):
189         messages.add_message(
190             self.request, messages.SUCCESS,
191             _('You have been added to the %r organization.') %
192             (self.om.organization.name.encode('utf-8'), )
193         )
194 
195         member_joined.send_robust(
196             member=self.om, organization=self.om.organization, sender=self.instance)
197 
198     def handle_member_already_exists(self):
199         messages.add_message(
200             self.request, messages.SUCCESS,
201             _('You are already a member of the %r organization.') %
202             (self.om.organization.name.encode('utf-8'), )
203         )
204 
205 
206 class ApiInviteHelper(BaseInviteHelper):
207     def handle_member_already_exists(self):
208         self.logger.info(
209             'Pending org invite not accepted - User already org member',
210             extra={
211                 'organization_id': self.om.organization.id,
212                 'user_id': self.request.user.id,
213             }
214         )
215 
216     def valid_request(self):
217         if (not self.member_pending or
218             not self.valid_token or
219             not self.user_authenticated or
220                 self.needs_2fa):
221             return False
222         return True
223
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/sentry/web/frontend/accept_organization_invite.py b/src/sentry/web/frontend/accept_organization_invite.py
--- a/src/sentry/web/frontend/accept_organization_invite.py
+++ b/src/sentry/web/frontend/accept_organization_invite.py
@@ -6,7 +6,7 @@
 from django.utils.crypto import constant_time_compare
 from django.utils.translation import ugettext_lazy as _
 
-from sentry.models import AuditLogEntryEvent, Authenticator, OrganizationMember, Project
+from sentry.models import AuditLogEntryEvent, Authenticator, OrganizationMember
 from sentry.signals import member_joined
 from sentry.utils import auth
 from sentry.web.frontend.base import BaseView
@@ -56,16 +56,8 @@
         om = helper.om
         organization = om.organization
 
-        qs = Project.objects.filter(
-            organization=organization,
-        )
-        project_list = list(qs[:25])
-        project_count = qs.count()
-
         context = {
             'org_name': organization.name,
-            'project_list': project_list,
-            'project_count': project_count,
             'needs_authentication': not helper.user_authenticated,
             'needs_2fa': helper.needs_2fa,
             'logout_url': u'{}?next={}'.format(

{"golden_diff": "diff --git a/src/sentry/web/frontend/accept_organization_invite.py b/src/sentry/web/frontend/accept_organization_invite.py\n--- a/src/sentry/web/frontend/accept_organization_invite.py\n+++ b/src/sentry/web/frontend/accept_organization_invite.py\n@@ -6,7 +6,7 @@\n from django.utils.crypto import constant_time_compare\n from django.utils.translation import ugettext_lazy as _\n \n-from sentry.models import AuditLogEntryEvent, Authenticator, OrganizationMember, Project\n+from sentry.models import AuditLogEntryEvent, Authenticator, OrganizationMember\n from sentry.signals import member_joined\n from sentry.utils import auth\n from sentry.web.frontend.base import BaseView\n@@ -56,16 +56,8 @@\n         om = helper.om\n         organization = om.organization\n \n-        qs = Project.objects.filter(\n-            organization=organization,\n-        )\n-        project_list = list(qs[:25])\n-        project_count = qs.count()\n-\n         context = {\n             'org_name': organization.name,\n-            'project_list': project_list,\n-            'project_count': project_count,\n             'needs_authentication': not helper.user_authenticated,\n             'needs_2fa': helper.needs_2fa,\n             'logout_url': u'{}?next={}'.format(\n", "issue": "User invite accept screen leaks 'project names' of projects that the new user does not necessarily have access rights to\n<!--\r\n\r\nDo you want to ask a question? Are you looking for support? The Sentry message\r\nboard is the best place for getting support: https://forum.sentry.io\r\n-->\r\n\r\n## Important Details\r\n\r\nHow are you running Sentry?\r\n\r\n* [ ] On-Premise docker [Version xyz]\r\n* [x] Saas (sentry.io)\r\n* [ ] Other [briefly describe your environment]\r\n\r\n## Description\r\n\r\nWe are providing sentry as a service with our products to our customer, as a result we have internal teams but would also like to invite external users (customers) to specific projects. We are able to utilise the team construct for this and setup special customer teams with limited access.\r\n\r\nWhen we however invite customers into our org to become member of this restricted team the customer received a generic org invite email and is redirected to a generic org invite screen:\r\nhttps://sentry.io/accept/xyz/xyz\r\n\r\nThis invite accept screen provides a list of 'active' projects with full project name, however the user does not necessary have access to these projects. \r\n\r\nWe would classify this as a security concern and leak of 'restricted' information. \r\n\r\n## Steps to Reproduce\r\n\r\n1. open org\r\n2. create 2 new teams\r\n    - team A\r\n    - team B\r\n2. create 2 new projects\r\n    - project A, assign access to team A\r\n    - project B, assign access to team B\r\n3. invite new user to org (as member level) and assign acces to team B only\r\n4. user receives invite by email and opens the accept link\r\n5. on the accept webpage notice that both project A and B are listed to be part of this org\r\n\r\n### What you expected to happen\r\n\r\nThe recommendation is to hide the project names completely in this view, or restrict it to the projects the new user has access to based on his team assignment.\r\n\n", "before_files": [{"content": "from __future__ import absolute_import\n\nfrom django import forms\nfrom django.contrib import messages\nfrom django.core.urlresolvers import reverse\nfrom django.utils.crypto import constant_time_compare\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom sentry.models import AuditLogEntryEvent, Authenticator, OrganizationMember, Project\nfrom sentry.signals import member_joined\nfrom sentry.utils import auth\nfrom sentry.web.frontend.base import BaseView\n\nERR_INVITE_INVALID = _('The invite link you followed is not valid, or has expired.')\nPENDING_INVITE = 'pending-invite'\nCOOKIE_MAX_AGE = 60 * 60 * 24 * 7  # 7 days\n\n\nclass AcceptInviteForm(forms.Form):\n    pass\n\n\nclass AcceptOrganizationInviteView(BaseView):\n    auth_required = False\n\n    def get_form(self, request):\n        if request.method == 'POST':\n            return AcceptInviteForm(request.POST)\n        return AcceptInviteForm()\n\n    def redirect_with_err_message(self, request):\n        messages.add_message(\n            request,\n            messages.ERROR,\n            ERR_INVITE_INVALID,\n        )\n\n        return self.redirect(reverse('sentry'))\n\n    def handle(self, request, member_id, token):\n        assert request.method in ('POST', 'GET')\n\n        try:\n            helper = WebInviteHelper(\n                instance=self,\n                request=request,\n                member_id=member_id,\n                token=token\n            )\n        except OrganizationMember.DoesNotExist:\n            return self.redirect_with_err_message(request)\n\n        if not helper.member_pending or not helper.valid_token:\n            return self.redirect_with_err_message(request)\n\n        om = helper.om\n        organization = om.organization\n\n        qs = Project.objects.filter(\n            organization=organization,\n        )\n        project_list = list(qs[:25])\n        project_count = qs.count()\n\n        context = {\n            'org_name': organization.name,\n            'project_list': project_list,\n            'project_count': project_count,\n            'needs_authentication': not helper.user_authenticated,\n            'needs_2fa': helper.needs_2fa,\n            'logout_url': u'{}?next={}'.format(\n                reverse('sentry-logout'),\n                request.path,\n            ),\n            'login_url': u'{}?next={}'.format(\n                reverse('sentry-login'),\n                request.path,\n            ),\n            'register_url': u'{}?next={}'.format(\n                reverse('sentry-register'),\n                request.path,\n            ),\n        }\n\n        if not helper.user_authenticated:\n            # Show login or register form\n            auth.initiate_login(request, next_url=request.get_full_path())\n            request.session['can_register'] = True\n            request.session['invite_email'] = om.email\n\n            return self.respond('sentry/accept-organization-invite.html', context)\n\n        if helper.needs_2fa:\n            # redirect to setup 2fa\n            response = self.respond('sentry/accept-organization-invite.html', context)\n            response.set_cookie(PENDING_INVITE, request.path, max_age=COOKIE_MAX_AGE)\n            return response\n\n        # if they're already a member of the organization its likely they're\n        # using a shared account and either previewing this invite or\n        # are incorrectly expecting this to create a new account for them\n        context['existing_member'] = helper.member_already_exists\n\n        form = self.get_form(request)\n        if form.is_valid():\n            helper.accept_invite()\n\n            request.session.pop('can_register', None)\n            response = self.redirect(reverse('sentry-organization-home', args=[organization.slug]))\n            return helper.remove_invite_cookie(response)\n\n        context['form'] = form\n        return self.respond('sentry/accept-organization-invite.html', context)\n\n\nclass BaseInviteHelper(object):\n    def __init__(self, instance, request, member_id, token, logger=None):\n        self.request = request\n        self.instance = instance\n        self.member_id = member_id\n        self.token = token\n        self.logger = logger\n        self.om = self.get_organization_member()\n\n    def handle_success(self):\n        pass\n\n    def handle_member_already_exists(self):\n        pass\n\n    def get_organization_member(self):\n        return OrganizationMember.objects.select_related('organization').get(pk=self.member_id)\n\n    @property\n    def member_pending(self):\n        return self.om.is_pending\n\n    @property\n    def valid_token(self):\n        if self.om.token_expired:\n            return False\n        return constant_time_compare(self.om.token or self.om.legacy_token, self.token)\n\n    @property\n    def user_authenticated(self):\n        return self.request.user.is_authenticated()\n\n    @property\n    def needs_2fa(self):\n        org_requires_2fa = self.om.organization.flags.require_2fa.is_set\n        user_has_2fa = Authenticator.objects.user_has_2fa(self.request.user.id)\n        return org_requires_2fa and not user_has_2fa\n\n    @property\n    def member_already_exists(self):\n        return OrganizationMember.objects.filter(\n            organization=self.om.organization, user=self.request.user\n        ).exists()\n\n    def accept_invite(self):\n        om = self.om\n\n        if self.member_already_exists:\n            self.handle_member_already_exists()\n            om.delete()\n        else:\n            om.set_user(self.request.user)\n            om.save()\n\n            self.instance.create_audit_entry(\n                self.request,\n                organization=om.organization,\n                target_object=om.id,\n                target_user=self.request.user,\n                event=AuditLogEntryEvent.MEMBER_ACCEPT,\n                data=om.get_audit_log_data(),\n            )\n\n            self.handle_success()\n\n    def remove_invite_cookie(self, response):\n        if PENDING_INVITE in self.request.COOKIES:\n            response.delete_cookie(PENDING_INVITE)\n        return response\n\n\nclass WebInviteHelper(BaseInviteHelper):\n    def handle_success(self):\n        messages.add_message(\n            self.request, messages.SUCCESS,\n            _('You have been added to the %r organization.') %\n            (self.om.organization.name.encode('utf-8'), )\n        )\n\n        member_joined.send_robust(\n            member=self.om, organization=self.om.organization, sender=self.instance)\n\n    def handle_member_already_exists(self):\n        messages.add_message(\n            self.request, messages.SUCCESS,\n            _('You are already a member of the %r organization.') %\n            (self.om.organization.name.encode('utf-8'), )\n        )\n\n\nclass ApiInviteHelper(BaseInviteHelper):\n    def handle_member_already_exists(self):\n        self.logger.info(\n            'Pending org invite not accepted - User already org member',\n            extra={\n                'organization_id': self.om.organization.id,\n                'user_id': self.request.user.id,\n            }\n        )\n\n    def valid_request(self):\n        if (not self.member_pending or\n            not self.valid_token or\n            not self.user_authenticated or\n                self.needs_2fa):\n            return False\n        return True\n", "path": "src/sentry/web/frontend/accept_organization_invite.py"}], "after_files": [{"content": "from __future__ import absolute_import\n\nfrom django import forms\nfrom django.contrib import messages\nfrom django.core.urlresolvers import reverse\nfrom django.utils.crypto import constant_time_compare\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom sentry.models import AuditLogEntryEvent, Authenticator, OrganizationMember\nfrom sentry.signals import member_joined\nfrom sentry.utils import auth\nfrom sentry.web.frontend.base import BaseView\n\nERR_INVITE_INVALID = _('The invite link you followed is not valid, or has expired.')\nPENDING_INVITE = 'pending-invite'\nCOOKIE_MAX_AGE = 60 * 60 * 24 * 7  # 7 days\n\n\nclass AcceptInviteForm(forms.Form):\n    pass\n\n\nclass AcceptOrganizationInviteView(BaseView):\n    auth_required = False\n\n    def get_form(self, request):\n        if request.method == 'POST':\n            return AcceptInviteForm(request.POST)\n        return AcceptInviteForm()\n\n    def redirect_with_err_message(self, request):\n        messages.add_message(\n            request,\n            messages.ERROR,\n            ERR_INVITE_INVALID,\n        )\n\n        return self.redirect(reverse('sentry'))\n\n    def handle(self, request, member_id, token):\n        assert request.method in ('POST', 'GET')\n\n        try:\n            helper = WebInviteHelper(\n                instance=self,\n                request=request,\n                member_id=member_id,\n                token=token\n            )\n        except OrganizationMember.DoesNotExist:\n            return self.redirect_with_err_message(request)\n\n        if not helper.member_pending or not helper.valid_token:\n            return self.redirect_with_err_message(request)\n\n        om = helper.om\n        organization = om.organization\n\n        context = {\n            'org_name': organization.name,\n            'needs_authentication': not helper.user_authenticated,\n            'needs_2fa': helper.needs_2fa,\n            'logout_url': u'{}?next={}'.format(\n                reverse('sentry-logout'),\n                request.path,\n            ),\n            'login_url': u'{}?next={}'.format(\n                reverse('sentry-login'),\n                request.path,\n            ),\n            'register_url': u'{}?next={}'.format(\n                reverse('sentry-register'),\n                request.path,\n            ),\n        }\n\n        if not helper.user_authenticated:\n            # Show login or register form\n            auth.initiate_login(request, next_url=request.get_full_path())\n            request.session['can_register'] = True\n            request.session['invite_email'] = om.email\n\n            return self.respond('sentry/accept-organization-invite.html', context)\n\n        if helper.needs_2fa:\n            # redirect to setup 2fa\n            response = self.respond('sentry/accept-organization-invite.html', context)\n            response.set_cookie(PENDING_INVITE, request.path, max_age=COOKIE_MAX_AGE)\n            return response\n\n        # if they're already a member of the organization its likely they're\n        # using a shared account and either previewing this invite or\n        # are incorrectly expecting this to create a new account for them\n        context['existing_member'] = helper.member_already_exists\n\n        form = self.get_form(request)\n        if form.is_valid():\n            helper.accept_invite()\n\n            request.session.pop('can_register', None)\n            response = self.redirect(reverse('sentry-organization-home', args=[organization.slug]))\n            return helper.remove_invite_cookie(response)\n\n        context['form'] = form\n        return self.respond('sentry/accept-organization-invite.html', context)\n\n\nclass BaseInviteHelper(object):\n    def __init__(self, instance, request, member_id, token, logger=None):\n        self.request = request\n        self.instance = instance\n        self.member_id = member_id\n        self.token = token\n        self.logger = logger\n        self.om = self.get_organization_member()\n\n    def handle_success(self):\n        pass\n\n    def handle_member_already_exists(self):\n        pass\n\n    def get_organization_member(self):\n        return OrganizationMember.objects.select_related('organization').get(pk=self.member_id)\n\n    @property\n    def member_pending(self):\n        return self.om.is_pending\n\n    @property\n    def valid_token(self):\n        if self.om.token_expired:\n            return False\n        return constant_time_compare(self.om.token or self.om.legacy_token, self.token)\n\n    @property\n    def user_authenticated(self):\n        return self.request.user.is_authenticated()\n\n    @property\n    def needs_2fa(self):\n        org_requires_2fa = self.om.organization.flags.require_2fa.is_set\n        user_has_2fa = Authenticator.objects.user_has_2fa(self.request.user.id)\n        return org_requires_2fa and not user_has_2fa\n\n    @property\n    def member_already_exists(self):\n        return OrganizationMember.objects.filter(\n            organization=self.om.organization, user=self.request.user\n        ).exists()\n\n    def accept_invite(self):\n        om = self.om\n\n        if self.member_already_exists:\n            self.handle_member_already_exists()\n            om.delete()\n        else:\n            om.set_user(self.request.user)\n            om.save()\n\n            self.instance.create_audit_entry(\n                self.request,\n                organization=om.organization,\n                target_object=om.id,\n                target_user=self.request.user,\n                event=AuditLogEntryEvent.MEMBER_ACCEPT,\n                data=om.get_audit_log_data(),\n            )\n\n            self.handle_success()\n\n    def remove_invite_cookie(self, response):\n        if PENDING_INVITE in self.request.COOKIES:\n            response.delete_cookie(PENDING_INVITE)\n        return response\n\n\nclass WebInviteHelper(BaseInviteHelper):\n    def handle_success(self):\n        messages.add_message(\n            self.request, messages.SUCCESS,\n            _('You have been added to the %r organization.') %\n            (self.om.organization.name.encode('utf-8'), )\n        )\n\n        member_joined.send_robust(\n            member=self.om, organization=self.om.organization, sender=self.instance)\n\n    def handle_member_already_exists(self):\n        messages.add_message(\n            self.request, messages.SUCCESS,\n            _('You are already a member of the %r organization.') %\n            (self.om.organization.name.encode('utf-8'), )\n        )\n\n\nclass ApiInviteHelper(BaseInviteHelper):\n    def handle_member_already_exists(self):\n        self.logger.info(\n            'Pending org invite not accepted - User already org member',\n            extra={\n                'organization_id': self.om.organization.id,\n                'user_id': self.request.user.id,\n            }\n        )\n\n    def valid_request(self):\n        if (not self.member_pending or\n            not self.valid_token or\n            not self.user_authenticated or\n                self.needs_2fa):\n            return False\n        return True\n", "path": "src/sentry/web/frontend/accept_organization_invite.py"}]}