internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: fossasia/open-event-server

Issue:
Multiple role invitations to the same email are allowed and are stored multiple times
**Describe the bug**
Currently, multiple role invitations can be sent to the same email id and even invitations with the same email and same role can be sent more than once and it is being stored multiple times in the list of roles. 

**Expected behavior**
There can be an option to resend a pending invitation and that should not be stored as a duplicate entry.


Discussion:
On it.

Resolving patch:
diff --git a/app/models/role_invite.py b/app/models/role_invite.py
--- a/app/models/role_invite.py
+++ b/app/models/role_invite.py
@@ -1,5 +1,6 @@
 import random
 from datetime import datetime, timedelta
+from sqlalchemy.schema import UniqueConstraint
 
 import pytz
 
@@ -14,6 +15,7 @@ def generate_hash():
 
 class RoleInvite(SoftDeletionModel):
     __tablename__ = 'role_invites'
+    __table_args__ = (UniqueConstraint('email', 'role_id', 'event_id', name='email_role_event_uc'),)
 
     id = db.Column(db.Integer, primary_key=True)
 
diff --git a/migrations/versions/89a5b836b406_.py b/migrations/versions/89a5b836b406_.py
new file mode 100644
--- /dev/null
+++ b/migrations/versions/89a5b836b406_.py
@@ -0,0 +1,37 @@
+"""empty message
+
+Revision ID: 89a5b836b406
+Revises: c517c6be040d
+Create Date: 2019-06-06 13:08:53.755940
+
+"""
+
+from alembic import op
+import sqlalchemy as sa
+import sqlalchemy_utils
+
+
+# revision identifiers, used by Alembic.
+revision = '89a5b836b406'
+down_revision = 'c517c6be040d'
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.execute(
+        """DELETE FROM role_invites R1
+        USING role_invites R2
+        WHERE R1.id > R2.id
+        AND R1.email = R2.email
+        AND R1.role_id = R2.role_id
+        AND R1.event_id = R2.event_id
+        """
+    )
+    op.create_unique_constraint('email_role_event_uc', 'role_invites', ['email', 'role_id', 'event_id'])
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_constraint('email_role_event_uc', 'role_invites', type_='unique')
+    # ### end Alembic commands ###


Test patch:
Repository: fossasia/open-event-server

Issue:
minor typo in settings schema and add omise payment to order schema
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->

change `is_omise_activate` to `is_omise_activated`
The typo is messing up frontend settings model so this is required


Discussion:

Resolving patch:
diff --git a/app/api/schema/orders.py b/app/api/schema/orders.py
--- a/app/api/schema/orders.py
+++ b/app/api/schema/orders.py
@@ -60,7 +60,8 @@ def initial_values(self, data):
     transaction_id = fields.Str(dump_only=True)
     payment_mode = fields.Str(
                             default="free",
-                            validate=validate.OneOf(choices=["free", "stripe", "paypal", "bank", "cheque", "onsite"]),
+                            validate=validate.OneOf(choices=["free", "stripe", "paypal", "bank",
+                                                             "cheque", "onsite", "omise", "alipay"]),
                             allow_none=True)
     paid_via = fields.Str(dump_only=True)
     is_billing_enabled = fields.Boolean(default=False)
diff --git a/app/api/schema/settings.py b/app/api/schema/settings.py
--- a/app/api/schema/settings.py
+++ b/app/api/schema/settings.py
@@ -57,7 +57,7 @@ class Meta:
     #
     is_paypal_activated = fields.Bool(dump_only=True)
     is_stripe_activated = fields.Bool(dump_only=True)
-    is_omise_activate = fields.Bool(dump_only=True)
+    is_omise_activated = fields.Bool(dump_only=True)
     is_alipay_activated = fields.Bool(dump_only=True)
 
 


Test patch:
Repository: fossasia/open-event-server

Issue:
Error in link provided in new session proposal email
**Describe the bug**
The link contains an extra `/` after `https://fossasia.github.io/open-event-frontend/`

![New session proposal wrong link](https://user-images.githubusercontent.com/35566748/58651381-c8ac9a80-832e-11e9-98ba-6fe533ee5950.png)



Discussion:
@iamareebjamal What is the exact frontend url in production?


Resolving patch:
diff --git a/app/api/sessions.py b/app/api/sessions.py
--- a/app/api/sessions.py
+++ b/app/api/sessions.py
@@ -20,6 +20,7 @@
 from app.models.user import User
 from app.models.session_speaker_link import SessionsSpeakersLink
 from app.settings import get_settings
+from app.api.helpers.files import make_frontend_url
 
 
 class SessionListPost(ResourceList):
@@ -54,8 +55,8 @@ def after_create_object(self, session, data, view_kwargs):
             organizer_email = organizer.email
             frontend_url = get_settings()['frontend_url']
             event = session.event
-            link = "{}/events/{}/sessions/{}"\
-                .format(frontend_url, event.identifier, session.id)
+            link = make_frontend_url("/events/{}/sessions/{}"
+                                     .format(event.identifier, session.id))
             send_email_new_session(organizer_email, event_name, link)
             send_notif_new_session_organizer(organizer, event_name, link, session.id)
 


Test patch:
Repository: fossasia/open-event-server

Issue:
Add role name in role-invite 
Add role name attribute in the json response on acceptance of a role.


Discussion:

Resolving patch:
diff --git a/app/api/role_invites.py b/app/api/role_invites.py
--- a/app/api/role_invites.py
+++ b/app/api/role_invites.py
@@ -168,7 +168,8 @@ def accept_invite():
     return jsonify({
         "email": user.email,
         "event": role_invite.event_id,
-        "name": user.fullname if user.fullname else None
+        "name": user.fullname if user.fullname else None,
+        "role": uer.role.name
     })
 
 


Test patch:
Repository: fossasia/open-event-server

Issue:
Limit the number of emails an account can sent out in a given timeframe
One account yesterday tried a password reset requesting a reset 1000 times.

Please implement a threshhold for account resets and propose a threshhold for other emails in a certain time frame. Open relevant issues for this.

A threshhold for an account reset email should be 3 times per hour. After that the user should receive a message: "You have reached the threshhold for this action. Please try again in one hour."


Discussion:
I'll be working on this
Thank you. It is related to this frontend issue: https://github.com/fossasia/open-event-frontend/issues/3128 and https://github.com/fossasia/open-event-frontend/issues/3129.
@shreyanshdwivedi https://github.com/fossasia/open-event-server/issues/6034

Resolving patch:
diff --git a/app/__init__.py b/app/__init__.py
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -11,6 +11,7 @@
 from flask_script import Manager
 from flask_login import current_user
 from flask_jwt import JWT
+from flask_limiter import Limiter
 from datetime import timedelta
 from flask_cors import CORS
 from flask_rest_jsonapi.errors import jsonapi_errors
@@ -50,6 +51,7 @@
 static_dir = os.path.dirname(os.path.dirname(__file__)) + "/static"
 template_dir = os.path.dirname(__file__) + "/templates"
 app = Flask(__name__, static_folder=static_dir, template_folder=template_dir)
+limiter = Limiter(app)
 env.read_envfile()
 
 
diff --git a/app/api/auth.py b/app/api/auth.py
--- a/app/api/auth.py
+++ b/app/api/auth.py
@@ -8,11 +8,13 @@
 from functools import wraps
 from flask import request, jsonify, make_response, Blueprint, send_file, url_for, redirect
 from flask_jwt import current_identity as current_user, jwt_required
+from flask_limiter.util import get_remote_address
 from sqlalchemy.orm.exc import NoResultFound
 from app.api.helpers.order import create_pdf_tickets_for_holder
 from app.api.helpers.storage import generate_hash
 
 from app import get_settings
+from app import limiter
 from app.api.helpers.db import save_to_db, get_count
 from app.api.helpers.errors import ForbiddenError, UnprocessableEntityError, NotFoundError, BadRequestError
 from app.api.helpers.files import make_frontend_url
@@ -29,7 +31,6 @@
 from app.models.user import User
 from app.api.helpers.storage import UPLOAD_PATHS
 
-
 authorised_blueprint = Blueprint('authorised_blueprint', __name__, url_prefix='/')
 ticket_blueprint = Blueprint('ticket_blueprint', __name__, url_prefix='/v1')
 auth_routes = Blueprint('auth', __name__, url_prefix='/v1/auth')
@@ -207,6 +208,12 @@ def resend_verification_email():
 
 
 @auth_routes.route('/reset-password', methods=['POST'])
+@limiter.limit(
+    '3/hour', key_func=lambda: request.json['data']['email'], error_message='Limit for this action exceeded'
+)
+@limiter.limit(
+    '1/minute', key_func=get_remote_address, error_message='Limit for this action exceeded'
+)
 def reset_password_post():
     try:
         email = request.json['data']['email']


Test patch:
Repository: fossasia/open-event-server

Issue:
Error logs generated in Celery while sending Mails
```
Traceback (most recent call last):
  File "/Users/abhinav/Documents/OpenSource/fossassia/open-event-server/venv/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 551, in on_task_received
    payload = message.decode()
  File "/Users/abhinav/Documents/OpenSource/fossassia/open-event-server/venv/lib/python3.6/site-packages/kombu/message.py", line 193, in decode
    self._decoded_cache = self._decode()
  File "/Users/abhinav/Documents/OpenSource/fossassia/open-event-server/venv/lib/python3.6/site-packages/kombu/message.py", line 198, in _decode
    self.content_encoding, accept=self.accept)
  File "/Users/abhinav/Documents/OpenSource/fossassia/open-event-server/venv/lib/python3.6/site-packages/kombu/serialization.py", line 253, in loads
    raise self._for_untrusted_content(content_type, 'untrusted')
kombu.exceptions.ContentDisallowed: Refusing to deserialize untrusted content of type pickle (application/x-python-serialize)
```

Similar logs are there for JSON format of mail objects.


Discussion:

Resolving patch:
diff --git a/app/__init__.py b/app/__init__.py
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -108,6 +108,7 @@ def create_app():
     # setup celery
     app.config['CELERY_BROKER_URL'] = app.config['REDIS_URL']
     app.config['CELERY_RESULT_BACKEND'] = app.config['CELERY_BROKER_URL']
+    app.config['CELERY_ACCEPT_CONTENT'] = ['json', 'application/text']
 
     CORS(app, resources={r"/*": {"origins": "*"}})
     AuthManager.init_login(app)


Test patch:
Repository: fossasia/open-event-server

Issue:
Only event organizers should be able to create discount codes for an event.
**Describe the bug**
User who is not the event organizer should not be able to create a discount code for the event.

**Expected behavior**
Only event organizers should be allowed to create a discount code for the event.

**Additional context**
Working on it.


Discussion:

Resolving patch:
diff --git a/app/api/discount_codes.py b/app/api/discount_codes.py
--- a/app/api/discount_codes.py
+++ b/app/api/discount_codes.py
@@ -1,3 +1,5 @@
+from datetime import datetime
+
 from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
 from flask_rest_jsonapi.exceptions import ObjectNotFound
 from sqlalchemy.orm.exc import NoResultFound
@@ -15,7 +17,6 @@
 from app.models.ticket import Ticket
 from app.models.user import User
 
-from datetime import datetime
 
 class DiscountCodeListPost(ResourceList):
     """
@@ -48,7 +49,7 @@ def before_post(self, args, kwargs, data):
             require_relationship(['event'], data)
             if not has_access('is_coorganizer', event_id=data['event']):
                 raise ForbiddenException({'source': ''}, 'You are not authorized')
-        elif not data['used_for'] == 'event' and has_access('is_admin') and 'events' in data:
+        elif data['used_for'] == 'event' and not has_access('is_admin') and 'events' in data:
             raise UnprocessableEntity({'source': ''}, "Please verify your permission or check your relationship")
 
         data['user_id'] = current_identity.id


Test patch:
Repository: fossasia/open-event-server

Issue:
Populate event locations with most frequent locations routinely
Parent issue https://github.com/fossasia/open-event-frontend/issues/2970

Event locations endpoint should return the most popular locations for events, and be updated regularly.


Discussion:
@CosmicCoder96 I will take this one. Closed the old one  (https://github.com/fossasia/open-event-server/pull/5982). Will open a new one by tonight.
Also, this is a duplicate of https://github.com/fossasia/open-event-server/issues/5945

Resolving patch:
diff --git a/app/api/event_locations.py b/app/api/event_locations.py
--- a/app/api/event_locations.py
+++ b/app/api/event_locations.py
@@ -1,9 +1,14 @@
 from flask_rest_jsonapi import ResourceList
+from flask_rest_jsonapi.querystring import QueryStringManager as QSManager
+from flask_rest_jsonapi.pagination import add_pagination_links
 
+from flask import request, url_for
 from app.api.bootstrap import api
 from app.api.schema.event_locations import EventLocationSchema
 from app.models import db
+from app.models.event import Event
 from app.models.event_location import EventLocation
+from sqlalchemy import func, desc
 
 
 class EventLocationList(ResourceList):
@@ -11,7 +16,30 @@ class EventLocationList(ResourceList):
     """
     List event locations
     """
+    def get(self, *args, **kwargs):
+        qs = QSManager(request.args, self.schema)
+        popular_locations = db.session.query(Event.searchable_location_name, func.count(Event.id).label('counts')) \
+            .group_by(Event.searchable_location_name) \
+            .order_by(desc('counts')) \
+            .limit(6)
+        locations = []
+        for location, _ in popular_locations:
+            if location is not None:
+                new_location = EventLocation(location)
+                new_location.id = len(locations)
+                locations.append(new_location)
+        schema = EventLocationSchema()
+        result = schema.dump(locations, many=True).data
+        view_kwargs = request.view_args if getattr(self, 'view_kwargs', None) is True else dict()
+        add_pagination_links(result,
+                             len(locations),
+                             qs,
+                             url_for(self.view, **view_kwargs))
+        result.update({'meta': {'count': len(locations)}})
+        return result
+
     decorators = (api.has_permission('is_admin', methods="POST"),)
     schema = EventLocationSchema
     data_layer = {'session': db.session,
-                  'model': EventLocation}
+                  'model': EventLocation
+                  }


Test patch:
Repository: fossasia/open-event-server

Issue:
Error raised on reset password if user is not registered
Raising an error on password reset if the user is not registered is like gifting hackers a list of users present in the database.

Instead, regardless of user being present in the system, it should return 

"If your email was registered with us, you'll get an email with reset link shortly"


Discussion:
Will work on it
@shreyanshdwivedi Can I take this as you will be handling order workflow?
@kushthedude order workflow is being handled by @uds5501 and @mrsaicharan1 as he had a similar PR few days ago. I'll open a PR in few hours
Cool

On Thu, 20 Jun 2019 at 10:32 AM, Shreyansh Dwivedi <notifications@github.com>
wrote:

> @kushthedude <https://github.com/kushthedude> order workflow is being
> handled by @uds5501 <https://github.com/uds5501> and @mrsaicharan1
> <https://github.com/mrsaicharan1> as he had a similar PR few days ago.
> I'll open a PR in few hours
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/fossasia/open-event-server/issues/6069?email_source=notifications&email_token=AKQMTLU4VIVWHALF67A6DETP3MFORA5CNFSM4HZGGY2KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYEIM5A#issuecomment-503875188>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AKQMTLXMWNO44UJWN333HTTP3MFORANCNFSM4HZGGY2A>
> .
>


Resolving patch:
diff --git a/app/api/auth.py b/app/api/auth.py
--- a/app/api/auth.py
+++ b/app/api/auth.py
@@ -1,5 +1,6 @@
 import os
 import base64
+import logging
 import random
 import string
 
@@ -32,6 +33,7 @@
 from app.api.helpers.storage import UPLOAD_PATHS
 from app.api.helpers.auth import AuthManager
 
+logger = logging.getLogger(__name__)
 authorised_blueprint = Blueprint('authorised_blueprint', __name__, url_prefix='/')
 ticket_blueprint = Blueprint('ticket_blueprint', __name__, url_prefix='/v1')
 auth_routes = Blueprint('auth', __name__, url_prefix='/v1/auth')
@@ -224,7 +226,7 @@ def reset_password_post():
     try:
         user = User.query.filter_by(email=email).one()
     except NoResultFound:
-        return NotFoundError({'source': ''}, 'User not found').respond()
+        logger.info('Tried to reset password not existing email %s', email)
     else:
         link = make_frontend_url('/reset-password', {'token': user.reset_password})
         if user.was_registered_with_order:
@@ -232,7 +234,8 @@ def reset_password_post():
         else:
             send_email_with_action(user, PASSWORD_RESET, app_name=get_settings()['app_name'], link=link)
 
-    return make_response(jsonify(message="Email Sent"), 200)
+    return make_response(jsonify(message="If your email was registered with us, you'll get an \
+                         email with reset link shortly", email=email), 200)
 
 
 @auth_routes.route('/reset-password', methods=['PATCH'])


Test patch:
Repository: fossasia/open-event-server

Issue:
After event mail cron job fails
```
2019-06-22T05:30:05.422615216Z ERROR:apscheduler.executors.default:Job "send_after_event_mail (trigger: cron[hour='5', minute='30'], next run at: 2019-06-23 05:30:00 UTC)" raised an exception
2019-06-22T05:30:05.422679235Z Traceback (most recent call last):
2019-06-22T05:30:05.422686046Z   File "/usr/local/lib/python3.6/site-packages/apscheduler/executors/base.py", line 125, in run_job
2019-06-22T05:30:05.422691849Z     retval = job.func(*job.args, **job.kwargs)
2019-06-22T05:30:05.422696907Z   File "/data/app/app/api/helpers/scheduled_jobs.py", line 47, in send_after_event_mail
2019-06-22T05:30:05.422702403Z     send_notif_after_event(organizer.user.email, event.name)
2019-06-22T05:30:05.422707205Z   File "/data/app/app/api/helpers/notification.py", line 221, in send_notif_after_event
2019-06-22T05:30:05.422712346Z     send_notification(user, title, message)
2019-06-22T05:30:05.422717388Z   File "/data/app/app/api/helpers/notification.py", line 27, in send_notification
2019-06-22T05:30:05.422722453Z     notification = Notification(user_id=user.id,
2019-06-22T05:30:05.422727394Z AttributeError: 'str' object has no attribute 'id'
2019-06-22T06:15:52.785255345Z ERROR:flask_jwt:Bad Request. Invalid credentials

```


Discussion:

Resolving patch:
diff --git a/app/api/helpers/scheduled_jobs.py b/app/api/helpers/scheduled_jobs.py
--- a/app/api/helpers/scheduled_jobs.py
+++ b/app/api/helpers/scheduled_jobs.py
@@ -44,7 +44,7 @@ def send_after_event_mail():
                     send_notif_after_event(speaker.user, event.name)
                 for organizer in organizers:
                     send_email_after_event(organizer.user.email, event.name, upcoming_event_links)
-                    send_notif_after_event(organizer.user.email, event.name)
+                    send_notif_after_event(organizer.user, event.name)
 
 
 def change_session_state_on_event_completion():


Test patch:
Repository: fossasia/open-event-server

Issue:
Speakers are queried by role in after event mail cron job but no such role exists
Currently, speakers are being queried under the assumption that there is a role called speaker, no such role exists.


Discussion:

Resolving patch:
diff --git a/app/api/helpers/scheduled_jobs.py b/app/api/helpers/scheduled_jobs.py
--- a/app/api/helpers/scheduled_jobs.py
+++ b/app/api/helpers/scheduled_jobs.py
@@ -14,6 +14,7 @@
 from app.models.event import Event
 from app.models.event_invoice import EventInvoice
 from app.models.order import Order
+from app.models.speaker import Speaker
 from app.models.session import Session
 from app.models.ticket import Ticket
 from app.models.ticket_fee import get_fee
@@ -33,7 +34,7 @@ def send_after_event_mail():
         upcoming_event_links += "</ul>"
         for event in events:
             organizers = get_user_event_roles_by_role_name(event.id, 'organizer')
-            speakers = get_user_event_roles_by_role_name(event.id, 'speaker')
+            speakers = Speaker.query.filter_by(event_id=event.id, deleted_at=None).all()
             current_time = datetime.datetime.now(pytz.timezone(event.timezone))
             time_difference = current_time - event.ends_at
             time_difference_minutes = (time_difference.days * 24 * 60) + \


Test patch:
Repository: fossasia/open-event-server

Issue:
Multi-attendee invoice download fails 
403 Forbidden error, corrupt PDF file.


Discussion:

Resolving patch:
diff --git a/app/api/auth.py b/app/api/auth.py
--- a/app/api/auth.py
+++ b/app/api/auth.py
@@ -295,9 +295,9 @@ def change_password():
     })
 
 
-def return_tickets(file_path, order_identifier):
+def return_file(file_name_prefix, file_path, order_identifier):
     response = make_response(send_file(file_path))
-    response.headers['Content-Disposition'] = 'attachment; filename=ticket-%s.pdf' % order_identifier
+    response.headers['Content-Disposition'] = 'attachment; filename=%s-%s.pdf' % (file_name_prefix, order_identifier)
     return response
 
 
@@ -313,10 +313,10 @@ def ticket_attendee_authorized(order_identifier):
             key = UPLOAD_PATHS['pdf']['tickets_all'].format(identifier=order_identifier)
             file_path = '../generated/tickets/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'
             try:
-                return return_tickets(file_path, order_identifier)
+                return return_file('ticket', file_path, order_identifier)
             except FileNotFoundError:
                 create_pdf_tickets_for_holder(order)
-                return return_tickets(file_path, order_identifier)
+                return return_file('ticket', file_path, order_identifier)
         else:
             return ForbiddenError({'source': ''}, 'Unauthorized Access').respond()
     else:
@@ -329,15 +329,16 @@ def order_invoices(order_identifier):
     if current_user:
         try:
             order = Order.query.filter_by(identifier=order_identifier).first()
-            user_id = order.user.id
         except NoResultFound:
             return NotFoundError({'source': ''}, 'Order Invoice not found').respond()
-        if current_user.id == user_id:
+        if current_user.can_download_tickets(order):
             key = UPLOAD_PATHS['pdf']['order'].format(identifier=order_identifier)
             file_path = '../generated/invoices/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'
-            response = make_response(send_file(file_path))
-            response.headers['Content-Disposition'] = 'attachment; filename=invoice-%s.zip' % order_identifier
-            return response
+            try:
+                return return_file('invoice', file_path, order_identifier)
+            except FileNotFoundError:
+                create_pdf_tickets_for_holder(order)
+                return return_file('invoice', file_path, order_identifier)
         else:
             return ForbiddenError({'source': ''}, 'Unauthorized Access').respond()
     else:


Test patch: