Skip to content

Commit

Permalink
Prevent user from registering if registration has passed (#10765)
Browse files Browse the repository at this point in the history
* reject payment token request if registration has passed

* prevented payment panel from showing in ui

* diff and eslint changes

* linter

* rubocop re-enable

* simplified i18n call

* linter
  • Loading branch information
dunkOnIT authored Feb 3, 2025
1 parent 5375f50 commit b9cc989
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 6 deletions.
10 changes: 6 additions & 4 deletions app/controllers/api/v1/registrations/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class Api::V1::Registrations::RegistrationsController < Api::V1::ApiController
def validate_show_registration
@user_id, @competition_id = show_params
@competition = Competition.find(@competition_id)
render_error(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) unless @current_user.id == @user_id.to_i || @current_user.can_manage_competition?(@competition)
render_error(:unauthorized, Registrations::ErrorCodes::USER_INSUFFICIENT_PERMISSIONS) unless @current_user.id == @user_id.to_i || @current_user.can_manage_competition?(@competition)
end

def show
Expand Down Expand Up @@ -108,7 +108,7 @@ def validate_list_admin
# TODO: Do we set this as an instance variable here so we can use it below?
@competition = Competition.find(competition_id)
unless @current_user.can_manage_competition?(@competition)
render_error(:unauthorized, ErrorCodes::USER_INSUFFICIENT_PERMISSIONS)
render_error(:unauthorized, Registrations::ErrorCodes::USER_INSUFFICIENT_PERMISSIONS)
end
end

Expand All @@ -128,10 +128,12 @@ def list_admin
def validate_payment_ticket_request
competition_id = params[:competition_id]
@competition = Competition.find(competition_id)
render_error(:forbidden, ErrorCodes::PAYMENT_NOT_ENABLED) unless @competition.using_payment_integrations?
return render_error(:forbidden, Registrations::ErrorCodes::PAYMENT_NOT_ENABLED) unless @competition.using_payment_integrations?

return render_error(:forbidden, Registrations::ErrorCodes::REGISTRATION_CLOSED) if @competition.registration_past?

@registration = Registration.find_by(user: @current_user, competition: @competition)
render_error(:forbidden, ErrorCodes::PAYMENT_NOT_READY) if @registration.nil?
render_error(:forbidden, Registrations::ErrorCodes::PAYMENT_NOT_READY) if @registration.nil?
end

def payment_ticket
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
FormField,
Header,
Label,
Message,
Segment,
} from 'semantic-ui-react';
import { paymentFinishUrl } from '../../../lib/requests/routes.js.erb';
Expand Down Expand Up @@ -86,6 +87,12 @@ export default function PaymentStep({
setIsLoading(false);
};

if (!competitionInfo['registration_currently_open?']) {
return (
<Message color="red">{I18n.t('registrations.payment_form.errors.registration_closed')}</Message>
);
}

return (
<Segment>
<Form id="payment-form" onSubmit={handleSubmit}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const shouldBeDisabled = (hasPaid, key, activeIndex, index, competitionInfo, isR
}

if (key === paymentStepConfig.key) {
return !hasPaid && index > activeIndex;
return (!hasPaid && index > activeIndex) || !competitionInfo['registration_currently_open?'];
}
if (key === competingStepConfig.key) {
return index > activeIndex;
Expand All @@ -77,7 +77,7 @@ export default function StepPanel({
const isAccepted = isRegistered && registration.competing.registration_status === 'accepted';
const isRejected = isRegistered && registration.competing.registration_status === 'rejected';
const hasPaid = registration?.payment?.has_paid;
const registrationFinished = (isRegistered && hasPaid) || (isRegistered && !competitionInfo['using_payment_integrations?']);
const registrationFinished = (isRegistered && hasPaid) || (isRegistered && !competitionInfo['using_payment_integrations?']) || !competitionInfo['registration_currently_open?'];

const steps = useMemo(() => {
const stepList = [requirementsStepConfig, competingStepConfig];
Expand Down
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,7 @@ en:
amount_too_low: "The total amount must be at least the registration fees to be paid."
amount_rather_high: "You are about to pay at least double the required amount for your registration to proceed."
errors:
registration_closed: "Registration has closed - no further payments are allowed."
already_paid: "The charge was not placed because the registration fees are already paid."
not_allowed: "You can't pay for that registration."
cpi_disconnected: "Tried to confirm a payment but the payment integration was disabled. Please contact the organizers of the competition."
Expand Down
14 changes: 14 additions & 0 deletions spec/requests/api_registrations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -386,4 +386,18 @@
end
end
end

describe 'GET #payment_ticket' do
it 'refuses ticket create request if registration is closed' do
closed_comp = FactoryBot.create(:competition, :registration_closed, :with_organizer, :stripe_connected)
reg = FactoryBot.create(:registration, :pending, competition: closed_comp)

headers = { 'Authorization' => fetch_jwt_token(reg.user_id) }
get api_v1_registrations_payment_ticket_path(competition_id: closed_comp.id), headers: headers

body = JSON.parse(response.body)
expect(response.status).to eq(403)
expect(body).to eq({ error: Registrations::ErrorCodes::REGISTRATION_CLOSED }.with_indifferent_access)
end
end
end

0 comments on commit b9cc989

Please sign in to comment.