Skip to content

Commit cc5752d

Browse files
iamareebjamalcodedsundependabot-preview[bot]prateekj117AmitAronovitch
authored
chore : Release v1.11 (#6768)
chore : Release v1.11 Co-authored-by: Areeb Jamal <[email protected]> Co-authored-by: Suneet Srivastava <[email protected]> Co-authored-by: null <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Prateek Jain <[email protected]> Co-authored-by: Amit Aronovitch <[email protected]> Co-authored-by: D.Rohit <[email protected]> Co-authored-by: Ritik Jain <[email protected]> Co-authored-by: Nitin Kumar <[email protected]> Co-authored-by: Sai Charan <[email protected]>
2 parents e2341cc + f83ef03 commit cc5752d

File tree

122 files changed

+1417
-1182
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+1417
-1182
lines changed

.env.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ DATABASE_URL=postgresql://open_event_user:[email protected]:5432/oevent
22
INTEGRATE_SOCKETIO=false
33
TEST_DATABASE_URL=postgresql://open_event_user:[email protected]:5432/opev_test
44
APP_CONFIG=config.DevelopmentConfig
5-
ENABLE_ELASTICSEARCH=false
6-
ELASTICSEARCH_HOST=localhost:9200
75

86
POSTGRES_USER=open_event_user
97
POSTGRES_PASSWORD=opev_pass
108
POSTGRES_DB=open_event
9+
10+
FLASK_APP=app.instance

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Fixes #
1818

1919
- [ ] I have read the [Contribution & Best practices Guide](https://blog.fossasia.org/open-source-developer-guide-and-best-practices-at-fossasia) and my PR follows them.
2020
- [ ] My branch is up-to-date with the Upstream `development` branch.
21-
- [ ] The unit tests pass locally with my changes <!-- use `nosetests tests/all` to run all the tests -->
21+
- [ ] The unit tests pass locally with my changes <!-- use `nosetests tests/` to run all the tests -->
2222
- [ ] I have added tests that prove my fix is effective or that my feature works
2323
- [ ] I have added necessary documentation (if appropriate)
2424
<!-- If an existing function does not have a docstring, please add one -->

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ install:
2121
- pip3 install -r requirements/tests.txt
2222

2323
env:
24-
- APP_CONFIG="config.TestingConfig" PATH=$PATH:${HOME}/google-cloud-sdk/bin
24+
- APP_CONFIG="config.TestingConfig" SECRET_KEY="super secret key" PATH=$PATH:${HOME}/google-cloud-sdk/bin
2525

2626
before_script:
2727
- psql -c 'create database test;' -U postgres
@@ -30,7 +30,7 @@ before_script:
3030
- bash scripts/test_multiple_heads.sh
3131

3232
script:
33-
- nosetests tests/all -v --with-coverage
33+
- nosetests tests/ -v --with-coverage
3434

3535
after_success:
3636
- 'bash <(curl -s https://codecov.io/bash)'

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
## Changelog
22

3+
#### v1.11.0 (2020-01-23):
4+
5+
- **BREAKING:** Fix security issues related to secret key. You **MUST** add the current secret key set in DB as `SECRET_KEY` environment variable before upgrading. After upgrading, the column will be removed from DB
6+
- Fix count query of tickets used to reserve tickets
7+
- Support event statistics in include query
8+
- Restrict deletion of orders except by admin
9+
- Fix missing fields and incorrect column value in session csv export
10+
- Addition of field for Promoted Events, Instagram Speaker URL, Age Groups for Attendee
11+
- Replaced jobs running with APS to celery-beat
12+
- Fix sessions can be edited after CFS has ended
13+
- Removed elasticsearch initialisation and redundant APIs
14+
- Change country field type to select in forms
15+
- Other minor fixes
16+
317
##### v1.10.0 (2019-12-22):
418

519
- Fix event and speaker image resizing, and add management command to resize event and speaker images which remained to be resized.

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ WORKDIR /data/app
2626
ADD . .
2727

2828
EXPOSE 8080
29-
CMD ["sh", "scripts/container_start.sh"]
29+
ENTRYPOINT ["sh", "scripts/container_start.sh"]

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,13 @@ export APP_CONFIG=config.TestingConfig
234234

235235
* Then go to the project directory and run the following command:
236236
```
237-
python3 -m unittest discover tests/all/
237+
python3 -m unittest discover tests/
238238
```
239239
* It will run each test one by one.
240240

241241
* You can also use the following command to run tests using nosetests:
242242
```
243-
nosetests tests/all/
243+
nosetests tests/
244244
```
245245

246246
#### Running robot framework tests

app.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
"APP_SECRET_TOKEN": {
1313
"generator": "secret"
1414
},
15+
"SECRET_KEY": {
16+
"generator": "secret"
17+
},
1518
"ON_HEROKU": "true",
1619
"FORCE_SSL": "true",
1720
"INVITATION_CODE": {

app/api/attendees.py

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
from datetime import datetime
1+
import datetime
22

3-
from flask import Blueprint, request, jsonify, abort, make_response
43
from flask_jwt_extended import current_user
54
from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
6-
from flask_rest_jsonapi.exceptions import ObjectNotFound
7-
from sqlalchemy.orm.exc import NoResultFound
5+
from sqlalchemy import or_, and_
86

97
from app.api.bootstrap import api
108
from app.api.helpers.db import safe_query, get_count
@@ -13,7 +11,6 @@
1311
ForbiddenException,
1412
UnprocessableEntity,
1513
)
16-
from app.api.helpers.mail import send_email_to_attendees
1714
from app.api.helpers.permission_manager import has_access
1815
from app.api.helpers.permissions import jwt_required
1916
from app.api.helpers.query import event_query
@@ -25,7 +22,23 @@
2522
from app.models.ticket_holder import TicketHolder
2623
from app.models.user import User
2724

28-
attendee_misc_routes = Blueprint('attendee_misc', __name__, url_prefix='/v1')
25+
from app.settings import get_settings
26+
27+
28+
def get_sold_and_reserved_tickets_count(event_id):
29+
order_expiry_time = get_settings()['order_expiry_time']
30+
return db.session.query(TicketHolder.id).join(Order).filter(TicketHolder.order_id == Order.id) \
31+
.filter(Order.event_id == int(event_id),
32+
Order.deleted_at.is_(None),
33+
or_(Order.status == 'placed',
34+
Order.status == 'completed',
35+
and_(Order.status == 'initializing',
36+
Order.created_at + datetime.timedelta(
37+
minutes=order_expiry_time) > datetime.datetime.utcnow()),
38+
and_(Order.status == 'pending',
39+
Order.created_at + datetime.timedelta(
40+
minutes=30 + order_expiry_time) > (datetime.datetime.utcnow()))
41+
)).count()
2942

3043

3144
class AttendeeListPost(ResourceList):
@@ -56,8 +69,7 @@ def before_post(self, args, kwargs, data):
5669
"Ticket belongs to a different Event"
5770
)
5871
# Check if the ticket is already sold out or not.
59-
if get_count(db.session.query(TicketHolder.id).
60-
filter_by(ticket_id=int(data['ticket']), deleted_at=None)) >= ticket.quantity:
72+
if get_sold_and_reserved_tickets_count(ticket.event_id) >= ticket.quantity:
6173
raise ConflictException(
6274
{'pointer': '/data/attributes/ticket_id'},
6375
"Ticket already sold out"
@@ -257,34 +269,3 @@ class AttendeeRelationshipOptional(ResourceRelationship):
257269
schema = AttendeeSchema
258270
data_layer = {'session': db.session,
259271
'model': TicketHolder}
260-
261-
262-
@attendee_misc_routes.route('/attendees/send-receipt', methods=['POST'])
263-
@jwt_required
264-
def send_receipt():
265-
"""
266-
Send receipts to attendees related to the provided order.
267-
:return:
268-
"""
269-
order_identifier = request.json.get('order-identifier')
270-
if order_identifier:
271-
try:
272-
order = db.session.query(Order).filter_by(identifier=order_identifier).one()
273-
except NoResultFound:
274-
raise ObjectNotFound({'parameter': '{identifier}'}, "Order not found")
275-
276-
if (order.user_id != current_user.id) and (not has_access('is_registrar', event_id=order.event_id)):
277-
abort(
278-
make_response(jsonify(error="You need to be the event organizer or order buyer to send receipts."), 403)
279-
)
280-
elif order.status != 'completed':
281-
abort(
282-
make_response(jsonify(error="Cannot send receipt for an incomplete order"), 409)
283-
)
284-
else:
285-
send_email_to_attendees(order, current_user.id)
286-
return jsonify(message="receipt sent to attendees")
287-
else:
288-
abort(
289-
make_response(jsonify(error="Order identifier missing"), 422)
290-
)

app/api/auth.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
from healthcheck import EnvironmentDump
1717
from sqlalchemy.orm.exc import NoResultFound
1818

19-
from app import get_settings
20-
from app import limiter
2119
from app.api.helpers.db import save_to_db, get_count
2220
from app.api.helpers.auth import AuthManager, blacklist_token
2321
from app.api.helpers.jwt import jwt_authenticate
@@ -28,11 +26,13 @@
2826
from app.api.helpers.notification import send_notification_with_action
2927
from app.api.helpers.third_party_auth import GoogleOAuth, FbOAuth, TwitterOAuth, InstagramOAuth
3028
from app.api.helpers.utilities import get_serializer, str_generator
29+
from app.extensions.limiter import limiter
3130
from app.models import db
3231
from app.models.mail import PASSWORD_RESET, PASSWORD_CHANGE, \
3332
PASSWORD_RESET_AND_VERIFY
3433
from app.models.notification import PASSWORD_CHANGE as PASSWORD_CHANGE_NOTIF
3534
from app.models.user import User
35+
from app.settings import get_settings
3636

3737

3838
logger = logging.getLogger(__name__)

app/api/custom/attendees.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from flask import Blueprint, request, jsonify, abort, make_response
2+
from flask_jwt_extended import current_user
3+
from sqlalchemy.orm.exc import NoResultFound
4+
5+
from app.api.helpers.mail import send_email_to_attendees
6+
from app.api.helpers.permissions import jwt_required
7+
from app.api.helpers.errors import (
8+
UnprocessableEntityError,
9+
NotFoundError,
10+
ForbiddenError,
11+
)
12+
from app.api.helpers.permission_manager import has_access
13+
14+
from app.models.order import Order
15+
from app.models import db
16+
17+
attendee_blueprint = Blueprint('attendee_blueprint', __name__, url_prefix='/v1')
18+
19+
20+
@attendee_blueprint.route('/attendees/send-receipt', methods=['POST'])
21+
@jwt_required
22+
def send_receipt():
23+
"""
24+
Send receipts to attendees related to the provided order.
25+
:return:
26+
"""
27+
order_identifier = request.json.get('order-identifier')
28+
if order_identifier:
29+
try:
30+
order = db.session.query(Order).filter_by(identifier=order_identifier).one()
31+
except NoResultFound:
32+
return NotFoundError({'parameter': '{order_identifier}'}, "Order not found").respond()
33+
34+
if (order.user_id != current_user.id) and (not has_access('is_registrar', event_id=order.event_id)):
35+
return ForbiddenError({'source': ''},
36+
'You need to be the event organizer or order buyer to send receipts.').respond()
37+
elif order.status != 'completed':
38+
abort(
39+
make_response(jsonify(error="Cannot send receipt for an incomplete order"), 409)
40+
)
41+
else:
42+
send_email_to_attendees(order, current_user.id)
43+
return jsonify(message="receipt sent to attendees")
44+
else:
45+
return UnprocessableEntityError({'source': ''}, 'Order identifier missing').respond()

0 commit comments

Comments
 (0)