Skip to content
This repository has been archived by the owner on Nov 22, 2023. It is now read-only.

Commit

Permalink
(PC-10838) Remove easy-removal of spectree on contremarque api
Browse files Browse the repository at this point in the history
The bug fix cd43b26 is efficient, there is no need for an environment variable ready rollback
  • Loading branch information
viconnex committed Sep 30, 2021
1 parent 637ccb7 commit 5839fbe
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 252 deletions.
284 changes: 101 additions & 183 deletions src/pcapi/routes/pro/bookings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from flask_login import current_user
from flask_login import login_required

from pcapi import settings
import pcapi.core.bookings.api as bookings_api
from pcapi.core.bookings.models import Booking
import pcapi.core.bookings.repository as booking_repository
Expand All @@ -18,7 +17,6 @@
from pcapi.routes.serialization.bookings_recap_serialize import _serialize_booking_recap
from pcapi.routes.serialization.bookings_serialize import GetBookingResponse
from pcapi.routes.serialization.bookings_serialize import get_booking_response
from pcapi.routes.serialization.bookings_serialize import serialize_booking
from pcapi.serialization.decorator import spectree_serialize
from pcapi.utils.human_ids import dehumanize
from pcapi.utils.human_ids import humanize
Expand Down Expand Up @@ -112,204 +110,124 @@ def get_all_bookings(query: ListBookingsQueryModel) -> ListBookingsResponseModel
)


if settings.ENABLE_SPECTREE_ON_CONTREMARQUE_API:
@pro_api_v2.route("/bookings/token/<token>", methods=["GET"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@spectree_serialize(
api=api,
response_model=GetBookingResponse,
tags=["API Contremarque"],
code_descriptions=BASE_CODE_DESCRIPTIONS | {"HTTP_200": "La contremarque existe et n’est pas validée"},
)
@login_or_api_key_required
def get_booking_by_token_v2(token: str) -> GetBookingResponse:
# in French, to be used by Swagger for the API documentation
"""Consultation d'une réservation.
Le code “contremarque” ou "token" est une chaîne de caractères permettant d’identifier la réservation et qui sert de preuve de réservation.
Ce code unique est généré pour chaque réservation d'un utilisateur sur l'application et lui est transmis à cette occasion.
"""
booking = booking_repository.find_by(token=token)

@pro_api_v2.route("/bookings/token/<token>", methods=["GET"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@spectree_serialize(
api=api,
response_model=GetBookingResponse,
tags=["API Contremarque"],
code_descriptions=BASE_CODE_DESCRIPTIONS | {"HTTP_200": "La contremarque existe et n’est pas validée"},
)
@login_or_api_key_required
def get_booking_by_token_v2(token: str) -> GetBookingResponse:
# in French, to be used by Swagger for the API documentation
"""Consultation d'une réservation.
Le code “contremarque” ou "token" est une chaîne de caractères permettant d’identifier la réservation et qui sert de preuve de réservation.
Ce code unique est généré pour chaque réservation d'un utilisateur sur l'application et lui est transmis à cette occasion.
"""
booking = booking_repository.find_by(token=token)

if current_user.is_authenticated:
# warning : current user is not none when user is not logged in
check_user_can_validate_bookings_v2(current_user, booking.offererId)

if current_api_key:
check_api_key_allows_to_validate_booking(current_api_key, booking.offererId)

bookings_validation.check_is_usable(booking)

return get_booking_response(booking)

@pro_api_v2.route("/bookings/use/token/<token>", methods=["PATCH"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@spectree_serialize(
api=api,
tags=["API Contremarque"],
on_success_status=204,
code_descriptions=BASE_CODE_DESCRIPTIONS | {"HTTP_204": "La contremarque a bien été validée"},
)
@login_or_api_key_required
def patch_booking_use_by_token(token: str):
# in French, to be used by Swagger for the API documentation
"""Validation d'une réservation.
Pour confirmer que la réservation a bien été utilisée par le jeune.
"""
booking = booking_repository.find_by(token=token)

if current_user.is_authenticated:
check_user_can_validate_bookings_v2(current_user, booking.offererId)

if current_api_key:
check_api_key_allows_to_validate_booking(current_api_key, booking.offererId)

bookings_api.mark_as_used(booking)

@pro_api_v2.route("/bookings/cancel/token/<token>", methods=["PATCH"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@login_or_api_key_required
@spectree_serialize(
api=api,
tags=["API Contremarque"],
on_success_status=204,
code_descriptions=BASE_CODE_DESCRIPTIONS
| {
"HTTP_204": "La contremarque a été annulée avec succès",
"HTTP_403": "Vous n'avez pas les droits nécessaires pour annuler cette contremarque ou la réservation a déjà été validée",
"HTTP_410": "La contremarque a déjà été annulée",
},
)
def patch_cancel_booking_by_token(token: str):
# in French, to be used by Swagger for the API documentation
"""Annulation d'une réservation.
Bien que, dans le cas d’un événement, l’utilisateur ne peut plus annuler sa réservation 72h avant le début de ce dernier,
cette API permet d’annuler la réservation d’un utilisateur si elle n’a pas encore été validé.
"""
token = token.upper()
booking = booking_repository.find_by(token=token)

if current_user.is_authenticated:
check_user_has_access_to_offerer(current_user, booking.offererId)

if current_api_key:
check_api_key_allows_to_cancel_booking(current_api_key, booking.offererId)

bookings_api.cancel_booking_by_offerer(booking)

@pro_api_v2.route("/bookings/keep/token/<token>", methods=["PATCH"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@login_or_api_key_required
@spectree_serialize(
api=api,
tags=["API Contremarque"],
on_success_status=204,
code_descriptions=BASE_CODE_DESCRIPTIONS
| {
"HTTP_204": "L'annulation de la validation de la contremarque a bien été effectuée",
"HTTP_410": "La contremarque n’est plus valide car elle a déjà été validée, annulée ou bien le remboursement a été initié",
},
)
def patch_booking_keep_by_token(token: str):
# in French, to be used by Swagger for the API documentation
"""Annulation de la validation d'une réservation."""
booking = booking_repository.find_by(token=token)

if current_user.is_authenticated:
check_user_can_validate_bookings_v2(current_user, booking.offererId)

if current_api_key:
check_api_key_allows_to_validate_booking(current_api_key, booking.offererId)

bookings_api.mark_as_unused(booking)


else:
# @debt api-migration
@public_api.route("/v2/bookings/token/<token>", methods=["GET"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@login_or_api_key_required
def get_booking_by_token_v2(token: str):
booking = booking_repository.find_by(token=token)

if current_user.is_authenticated:
# warning : current user is not none when user is not logged in
check_user_can_validate_bookings_v2(current_user, booking.offererId)

if current_api_key:
check_api_key_allows_to_validate_booking(current_api_key, booking.offererId)

bookings_validation.check_is_usable(booking)
if current_user.is_authenticated:
# warning : current user is not none when user is not logged in
check_user_can_validate_bookings_v2(current_user, booking.offererId)

response = serialize_booking(booking)
if current_api_key:
check_api_key_allows_to_validate_booking(current_api_key, booking.offererId)

return jsonify(response), 200

# @debt api-migration
@public_api.route("/v2/bookings/use/token/<token>", methods=["PATCH"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@login_or_api_key_required
def patch_booking_use_by_token(token: str):
"""Let a pro user mark a booking as used."""
booking = booking_repository.find_by(token=token)
bookings_validation.check_is_usable(booking)

if current_user.is_authenticated:
check_user_can_validate_bookings_v2(current_user, booking.offererId)
return get_booking_response(booking)

if current_api_key:
check_api_key_allows_to_validate_booking(current_api_key, booking.offererId)

bookings_api.mark_as_used(booking)
@pro_api_v2.route("/bookings/use/token/<token>", methods=["PATCH"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@spectree_serialize(
api=api,
tags=["API Contremarque"],
on_success_status=204,
code_descriptions=BASE_CODE_DESCRIPTIONS | {"HTTP_204": "La contremarque a bien été validée"},
)
@login_or_api_key_required
def patch_booking_use_by_token(token: str):
# in French, to be used by Swagger for the API documentation
"""Validation d'une réservation.
return "", 204
Pour confirmer que la réservation a bien été utilisée par le jeune.
"""
booking = booking_repository.find_by(token=token)

# @debt api-migration
@private_api.route("/v2/bookings/cancel/token/<token>", methods=["PATCH"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@login_or_api_key_required
def patch_cancel_booking_by_token(token: str):
"""Let a pro user cancel a booking."""
token = token.upper()
booking = booking_repository.find_by(token=token)
if current_user.is_authenticated:
check_user_can_validate_bookings_v2(current_user, booking.offererId)

if current_user.is_authenticated:
check_user_has_access_to_offerer(current_user, booking.offererId)
if current_api_key:
check_api_key_allows_to_validate_booking(current_api_key, booking.offererId)

if current_api_key:
check_api_key_allows_to_cancel_booking(current_api_key, booking.offererId)
bookings_api.mark_as_used(booking)

bookings_api.cancel_booking_by_offerer(booking)

return "", 204
@pro_api_v2.route("/bookings/cancel/token/<token>", methods=["PATCH"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@login_or_api_key_required
@spectree_serialize(
api=api,
tags=["API Contremarque"],
on_success_status=204,
code_descriptions=BASE_CODE_DESCRIPTIONS
| {
"HTTP_204": "La contremarque a été annulée avec succès",
"HTTP_403": "Vous n'avez pas les droits nécessaires pour annuler cette contremarque ou la réservation a déjà été validée",
"HTTP_410": "La contremarque a déjà été annulée",
},
)
def patch_cancel_booking_by_token(token: str):
# in French, to be used by Swagger for the API documentation
"""Annulation d'une réservation.
Bien que, dans le cas d’un événement, l’utilisateur ne peut plus annuler sa réservation 72h avant le début de ce dernier,
cette API permet d’annuler la réservation d’un utilisateur si elle n’a pas encore été validé.
"""
token = token.upper()
booking = booking_repository.find_by(token=token)

# @debt api-migration
@public_api.route("/v2/bookings/keep/token/<token>", methods=["PATCH"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@login_or_api_key_required
def patch_booking_keep_by_token(token: str):
"""Let a pro user mark a booking as _not_ used."""
booking = booking_repository.find_by(token=token)
if current_user.is_authenticated:
check_user_has_access_to_offerer(current_user, booking.offererId)

if current_user.is_authenticated:
check_user_can_validate_bookings_v2(current_user, booking.offererId)
if current_api_key:
check_api_key_allows_to_cancel_booking(current_api_key, booking.offererId)

bookings_api.cancel_booking_by_offerer(booking)


@pro_api_v2.route("/bookings/keep/token/<token>", methods=["PATCH"])
@ip_rate_limiter(deduct_when=lambda response: response.status_code == 401)
@basic_auth_rate_limiter()
@login_or_api_key_required
@spectree_serialize(
api=api,
tags=["API Contremarque"],
on_success_status=204,
code_descriptions=BASE_CODE_DESCRIPTIONS
| {
"HTTP_204": "L'annulation de la validation de la contremarque a bien été effectuée",
"HTTP_410": "La contremarque n’est plus valide car elle a déjà été validée, annulée ou bien le remboursement a été initié",
},
)
def patch_booking_keep_by_token(token: str):
# in French, to be used by Swagger for the API documentation
"""Annulation de la validation d'une réservation."""
booking = booking_repository.find_by(token=token)

if current_api_key:
check_api_key_allows_to_validate_booking(current_api_key, booking.offererId)
if current_user.is_authenticated:
check_user_can_validate_bookings_v2(current_user, booking.offererId)

bookings_api.mark_as_unused(booking)
if current_api_key:
check_api_key_allows_to_validate_booking(current_api_key, booking.offererId)

return "", 204
bookings_api.mark_as_unused(booking)


def _create_response_to_get_booking_by_token(booking: Booking) -> dict:
Expand Down
66 changes: 0 additions & 66 deletions src/pcapi/routes/serialization/bookings_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from pcapi.models import Booking
from pcapi.models import EventType
from pcapi.models import ThingType
from pcapi.routes.serialization import serialize
from pcapi.serialization.utils import to_camel
from pcapi.utils.date import format_into_utc_date
from pcapi.utils.human_ids import humanize
Expand Down Expand Up @@ -142,68 +141,3 @@ class PostBookingResponseModel(BaseModel):
class Config:
allow_population_by_field_name = True
arbitrary_types_allowed = True


def serialize_booking(booking: Booking) -> dict:
booking_id = humanize(booking.id)
is_educational_booking = booking.educationalBookingId is not None
if is_educational_booking:
user_email = booking.educationalBooking.educationalRedactor.email
else:
user_email = booking.user.email
is_used = booking.isUsed
offer_name = booking.stock.offer.product.name
if is_educational_booking:
redactor = booking.educationalBooking.educationalRedactor
user_name = f"{redactor.firstName} {redactor.lastName}"
else:
user_name = booking.user.publicName
venue_departement_code = booking.stock.offer.venue.departementCode
offer_id = booking.stock.offer.id
venue_name = booking.stock.offer.venue.name
venue_address = booking.stock.offer.venue.address
offer_type = "EVENEMENT" if booking.stock.offer.isEvent else "BIEN"
offer_formula = ""
if booking.stock.offer.type == str(EventType.CINEMA):
offer_formula = "PLACE"
elif booking.stock.offer.type == str(ThingType.CINEMA_ABO):
offer_formula = "ABO"
offer_date_time = serialize(booking.stock.beginningDatetime) if booking.stock.beginningDatetime else ""
price = booking.stock.price
quantity = booking.quantity
offer_extra_data = booking.stock.offer.extraData
product_isbn = ""
theater = {}
if offer_extra_data:
if "isbn" in offer_extra_data:
product_isbn = offer_extra_data["isbn"]
if "theater" in offer_extra_data:
theater = offer_extra_data["theater"]

date_of_birth = ""
phone_number = ""
if booking.educationalBookingId is None and booking.stock.offer.product.type == str(EventType.ACTIVATION):
date_of_birth = serialize(booking.user.dateOfBirth)
phone_number = booking.user.phoneNumber

return {
"bookingId": booking_id,
"dateOfBirth": date_of_birth,
"datetime": offer_date_time,
"ean13": product_isbn,
"email": user_email,
"formula": offer_formula,
"isUsed": is_used,
"offerId": offer_id,
"publicOfferId": humanize(offer_id),
"offerName": offer_name,
"offerType": offer_type,
"phoneNumber": phone_number,
"price": price,
"quantity": quantity,
"theater": theater,
"userName": user_name,
"venueAddress": venue_address,
"venueDepartementCode": venue_departement_code,
"venueName": venue_name,
}
Loading

0 comments on commit 5839fbe

Please sign in to comment.