diff --git a/r2/r2/controllers/promotecontroller.py b/r2/r2/controllers/promotecontroller.py index ea087f799..fbf7e19ae 100644 --- a/r2/r2/controllers/promotecontroller.py +++ b/r2/r2/controllers/promotecontroller.py @@ -416,6 +416,7 @@ class PromoteController(ListingController): def POST_update_pay(self, form, jquery, link, indx, customer_id, pay_id, edit, address, creditcard): address_modified = not pay_id or edit + form_has_errors = False if address_modified: if (form.has_errors(["firstName", "lastName", "company", "address", "city", "state", "zip", @@ -423,13 +424,13 @@ class PromoteController(ListingController): errors.BAD_ADDRESS) or form.has_errors(["cardNumber", "expirationDate", "cardCode"], errors.BAD_CARD)): - pass + form_has_errors = True elif g.authorizenetapi: pay_id = edit_profile(c.user, address, creditcard, pay_id) else: pay_id = 1 # if link is in use or finished, don't make a change - if pay_id: + if pay_id and not form_has_errors: # valid bid and created or existing bid id. # check if already a transaction if g.authorizenetapi: diff --git a/r2/r2/controllers/validator/validator.py b/r2/r2/controllers/validator/validator.py index 8e4049e2e..c94bf21e0 100644 --- a/r2/r2/controllers/validator/validator.py +++ b/r2/r2/controllers/validator/validator.py @@ -1638,15 +1638,34 @@ class ValidCard(Validator): dict(message=msg), field = field) def run(self, cardNumber, expirationDate, cardCode): + has_errors = False + if not self.valid_ccn.match(cardNumber or ""): self.set_error(_("credit card numbers should be 13 to 16 digits"), "cardNumber") - elif not self.valid_date.match(expirationDate or ""): + has_errors = True + + if not self.valid_date.match(expirationDate or ""): self.set_error(_("dates should be YYYY-MM"), "expirationDate") - elif not self.valid_ccv.match(cardCode or ""): + has_errors = True + else: + now = datetime.now() + yyyy, mm = expirationDate.split("-") + year = int(yyyy) + month = int(mm) + if month < 1 or month > 12: + self.set_error(_("month must be in the range 01..12"), "expirationDate") + has_errors = True + elif datetime(year, month, now.day) < now: + self.set_error(_("expiration date must be in the future"), "expirationDate") + has_errors = True + + if not self.valid_ccv.match(cardCode or ""): self.set_error(_("card verification codes should be 3 or 4 digits"), "cardCode") - else: + has_errors = True + + if not has_errors: return CreditCard(cardNumber = cardNumber, expirationDate = expirationDate, cardCode = cardCode)