def get(self, request, *args, **kwargs): transaction_id = kwargs.get('transaction_id', '') payment_object = payments.by_transaction_id(transaction_id=transaction_id) if not payment_object: logging.critical(f'payment not found, transaction_id is {transaction_id}') raise exceptions.SuspiciousOperation() if not payment_object.owner == request.user: logging.critical('invalid request, payment process raises SuspiciousOperation: ' 'payment owner is not matching to request') raise exceptions.SuspiciousOperation() if payment_object.finished_at: logging.critical('invalid request, payment process raises SuspiciousOperation: ' 'payment transaction is already finished') raise exceptions.SuspiciousOperation() payment_amount = round(payment_object.amount * ( 100.0 + settings.ZENAIDA_BILLING_4CSONLINE_BANK_COMMISSION_RATE) / 100.0, 2) return shortcuts.render(request, 'billing/4csonline/merchant_form.html', { 'company_name': 'DATAHAVEN NET', 'price': '%.2f' % payment_amount, 'merch_id': settings.ZENAIDA_BILLING_4CSONLINE_MERCHANT_ID, 'merch_link': settings.ZENAIDA_BILLING_4CSONLINE_MERCHANT_LINK, 'invoice': payment_object.transaction_id, 'tran_id': payment_object.transaction_id, 'url_approved': '{}{}'.format(settings.SITE_BASE_URL, urls.reverse('billing_4csonline_verify_payment')), 'url_other': '{}{}'.format(settings.SITE_BASE_URL, urls.reverse('billing_4csonline_verify_payment')), })
def get(self, request, signed_prequal_request_id): # Validate signed ID signer = signing.Signer() try: prequal_request_id = signer.unsign(signed_prequal_request_id) except signing.BadSignature: raise exceptions.SuspiciousOperation("Invalid Signature") # Get and validate redirect URL redirect_url = self.request.GET.get("next", "/") redirect_url_is_safe = is_safe_url( url=redirect_url, allowed_hosts=set((request.get_host(), )), require_https=request.is_secure(), ) if not redirect_url_is_safe: redirect_url = "/" # Make sure request ID is valid try: prequal_request = PreQualificationRequest.objects.get( pk=prequal_request_id) except PreQualificationRequest.DoesNotExist: raise exceptions.SuspiciousOperation( "PreQualificationRequest does not exist") # Put ID into session and redirect to next view request.session[PREQUAL_SESSION_KEY] = prequal_request.pk return redirect(redirect_url)
def get_order_by_id_and_owner(order_id, owner, log_action=None): order = by_id(order_id) if not order: logging.critical( f'User {owner} tried to {log_action} non-existing order') raise exceptions.SuspiciousOperation() if order.owner != owner: logging.critical( f'User {owner} tried to {log_action} an order for another user') raise exceptions.SuspiciousOperation() return order
def _check_rc_ok_is_incomplete(self, result, rc, fc, transaction_id, reference): if result != 'pass' or rc != 'OK' or fc != 'APPROVED': if fc == 'INCOMPLETE': self.message = 'Transaction was cancelled' if not payments.finish_payment(transaction_id=transaction_id, status='cancelled'): logging.critical(f'payment not found, transaction_id is {transaction_id}') raise exceptions.SuspiciousOperation() else: self.message = 'Transaction was declined' if not payments.finish_payment(transaction_id=transaction_id, status='declined', merchant_reference=reference): logging.critical(f'payment not found, transaction_id is {transaction_id}') raise exceptions.SuspiciousOperation() return True return False
def execute_one_item(order_item): target_domain = zdomains.domain_find(order_item.name) if not target_domain: logging.critical('Domain not exist', order_item.name) update_order_item(order_item, new_status='failed', charge_user=False, save=True) return False if target_domain.owner != order_item.order.owner: logging.critical( 'User %s tried to execute an order with domain from another owner' % order_item.order.owner) raise exceptions.SuspiciousOperation() if order_item.type == 'domain_register': return execute_domain_register(order_item, target_domain) if order_item.type == 'domain_renew': return execute_domain_renew(order_item, target_domain) if order_item.type == 'domain_restore': return execute_domain_restore(order_item, target_domain) logging.critical('Order item %s have a wrong type' % order_item) return False
def mutate(self, info: ResolveInfo, admin_id: str, board_id: str): success = False user = get_user_by_context(info.context) if BoardModel.objects.filter(id=map_id(board_id)).exists(): board = BoardModel.objects.get(id=map_id(board_id)) if not UserModel.objects.filter(id=map_id(admin_id)).exists(): raise exceptions.ObjectDoesNotExist( 'Cannot entitle user to become admin, that does not exist') would_be_admin = UserModel.objects.get(id=map_id(admin_id)) if (user not in board.admins): raise exceptions.PermissionDenied( 'User has no permissions to give somebody administrative privileges' ) if (would_be_admin in board.admins or would_be_admin is board.maker): raise exceptions.SuspiciousOperation( 'User is already board admin, it\'s kinda sus') board.admins.add(would_be_admin) board.save() success = True return AddAdmin(board=board, success=success) else: raise exceptions.ObjectDoesNotExist( 'Cannot add admin to board that does not exist')
def post(self, request, *args, **kwargs): order_items = request.POST.getlist('order_items') to_be_ordered = [] for domain_name in order_items: domain_object = zdomains.domain_find(domain_name=domain_name) if not domain_object: raise Http404 if domain_object.owner != request.user: logging.critical( 'User %s tried to make an order with domain from another owner' % request.user) raise exceptions.SuspiciousOperation() try: item_type, item_price, item_name = billing_orders.prepare_register_renew_restore_item( domain_object) except billing_errors.DomainBlockedError as err: messages.error(request, str(err)) return shortcuts.redirect('account_domains') to_be_ordered.append( dict( item_type=item_type, item_price=item_price, item_name=item_name, )) if not to_be_ordered: messages.error(request, self.error_message) return shortcuts.redirect('account_domains') new_order = billing_orders.order_multiple_items( owner=request.user, order_items=to_be_ordered, ) return shortcuts.render(request, 'billing/order_details.html', {'order': new_order})
def _check_rc_usercan_is_incomplete(self, result, rc, fc, transaction_id): if result != 'pass' and rc == 'USERCAN' and fc == 'INCOMPLETE': self.message = 'Transaction was cancelled' if not payments.finish_payment(transaction_id=transaction_id, status='cancelled'): logging.critical(f'payment not found, transaction_id is {transaction_id}') raise exceptions.SuspiciousOperation() return True return False
def _check_payment(payment_obj, transaction_id, amount): if not payment_obj: logging.critical( f'Payment not found, transaction_id is {transaction_id}') raise exceptions.SuspiciousOperation() if payment_obj.finished_at: logging.critical( 'Invalid request, payment process raises SuspiciousOperation: ' 'payment transaction is already finished') raise exceptions.SuspiciousOperation() if payment_obj.amount != float(amount.replace(',', '')): logging.critical( 'Invalid request, payment processing will raise SuspiciousOperation: ' 'transaction amount is not matching with existing record') raise exceptions.SuspiciousOperation()
def get(self, request, *args, **kwargs): request_data = request.GET result = request_data.get('result') rc = request_data.get('rc') fc = request_data.get('fc') reference = request_data.get('ref') transaction_id = request_data.get('tid') amount = request_data.get('amt', '').replace(',', '') logging.info('verifying payment request: %r', request_data) if self._check_rc_usercan_is_incomplete(result, rc, fc, transaction_id): return shortcuts.render(request, 'billing/4csonline/failed_payment.html', { 'message': self.message, # TODO Use Django messages }) payment_object = payments.by_transaction_id(transaction_id=transaction_id) self._check_payment(payment_object, transaction_id, amount) if not settings.ZENAIDA_BILLING_4CSONLINE_BYPASS_PAYMENT_VERIFICATION: if self._check_rc_ok_is_incomplete(result, rc, fc, transaction_id, reference): return shortcuts.render(request, 'billing/4csonline/failed_payment.html', { 'message': self.message, }) payments.update_payment(payment_object, status='paid', merchant_reference=reference) if not settings.ZENAIDA_BILLING_4CSONLINE_BYPASS_PAYMENT_CONFIRMATION: result = self._is_payment_verified(transaction_id) if result == 'pending': return shortcuts.render(request, 'billing/4csonline/pending_payment.html', { 'message': self.message, }) if result == 'failed': return shortcuts.render(request, 'billing/4csonline/failed_payment.html', { 'message': self.message, }) if not payments.finish_payment(transaction_id=transaction_id, status='processed'): logging.critical(f'payment not found, transaction_id is {transaction_id}') # TODO Use Django messages raise exceptions.SuspiciousOperation() redirect_url = '/billing/payments/' if not request.user.is_anonymous: started_orders = billing_orders.list_orders( owner=self.request.user, exclude_cancelled=True, include_statuses=['started'] ) if started_orders: messages.warning(self.request, 'You have an ongoing order. Please click the "Confirm" button ' 'to complete the order.') redirect_url = '/billing/order/' + str(started_orders[0].id) return shortcuts.render(request, 'billing/4csonline/success_payment.html', {'redirect_url': redirect_url})
def mutate(self, info: ResolveInfo, forget_token: str, new_password: str): if(info.context.user.is_authenticated): raise exceptions.SuspiciousOperation("User is already logged in, it's kinda sus") payload = jwt_utils.decode_token(forget_token, info.context) email = payload["email"] if not (UserModel.objects.filter(email=email).exists()): raise exceptions.ObjectDoesNotExist('User does not exist') user = UserModel.objects.filter(email=email).get() if not user.hashed_pwd.startswith(crypto.UNUSABLE_PASSWORD_PREFIX): raise exceptions.SuspiciousOperation("User's password is not marked as unusable, it's kinda sus") if not (user.jtis.filter(value=payload["jti"]).exists()): raise jwt.InvalidTokenError("Token expired by user-logout request") return SetNewPasswordAfterReset(**_register_password(user, new_password))
def _check_payment(payment_obj, transaction_id, amount): if not payment_obj: logging.critical(f'payment not found, transaction_id is {transaction_id}') raise exceptions.SuspiciousOperation() if payment_obj.finished_at: logging.critical('invalid request, payment process raises SuspiciousOperation: ' 'payment transaction was already finished') raise exceptions.SuspiciousOperation() expected_payment_amount = round(payment_obj.amount * ( 100.0 + settings.ZENAIDA_BILLING_4CSONLINE_BANK_COMMISSION_RATE) / 100.0, 2) if float(amount) < expected_payment_amount: logging.critical('invalid request, payment processing will raise SuspiciousOperation: ' 'transaction amount is not matching with existing record') raise exceptions.SuspiciousOperation() if float(amount) > expected_payment_amount: logging.warn('payment %r is overpaid: %r', payment_obj, amount) else: logging.info('payment %r is valid', payment_obj)
def get(self, request, *args, **kwargs): request_data = request.GET result = request_data.get('result') rc = request_data.get('rc') fc = request_data.get('fc') reference = request_data.get('ref') transaction_id = request_data.get('tid') amount = request_data.get('amt') if self._check_rc_usercan_is_incomplete(result, rc, fc, transaction_id): return shortcuts.render( request, 'billing/4csonline/failed_payment.html', { 'message': self.message, # TODO Use Django messages }) payment_object = payments.by_transaction_id( transaction_id=transaction_id) self._check_payment(payment_object, transaction_id, amount) if not settings.ZENAIDA_BILLING_4CSONLINE_BYPASS_PAYMENT_VERIFICATION: if self._check_rc_ok_is_incomplete(result, rc, fc, transaction_id, reference): return shortcuts.render( request, 'billing/4csonline/failed_payment.html', { 'message': self.message, }) payments.update_payment(payment_object, status='paid', merchant_reference=reference) if not settings.ZENAIDA_BILLING_4CSONLINE_BYPASS_PAYMENT_CONFIRMATION: if not self._is_payment_verified(transaction_id): return shortcuts.render( request, 'billing/4csonline/failed_payment.html', { 'message': self.message, }) if not payments.finish_payment(transaction_id=transaction_id, status='processed'): logging.critical( f'Payment not found, transaction_id is {transaction_id}' ) # TODO Use Django messages raise exceptions.SuspiciousOperation() return shortcuts.render(request, 'billing/4csonline/success_payment.html')
def _is_payment_verified(self, transaction_id): try: verified = requests.get(f'{settings.ZENAIDA_BILLING_4CSONLINE_MERCHANT_VERIFY_LINK}?m=' f'{settings.ZENAIDA_BILLING_4CSONLINE_MERCHANT_ID}&t={transaction_id}') except Exception as exc: self.message = 'Payment verification is pending, your balance will be updated within few minutes.' logging.critical(f'payment confirmation failed, transaction_id is {transaction_id} : {exc}') return 'pending' if verified.text != 'YES': if not payments.finish_payment(transaction_id=transaction_id, status='unconfirmed'): logging.critical(f'payment not found, transaction_id is {transaction_id}') raise exceptions.SuspiciousOperation() self.message = 'Transaction verification failed' logging.critical(f'payment confirmation failed, transaction_id is {transaction_id}') return 'failed' return 'verified'
def _is_payment_verified(self, transaction_id): verified = requests.get( f'{settings.ZENAIDA_BILLING_4CSONLINE_MERCHANT_VERIFY_LINK}?m=' f'{settings.ZENAIDA_BILLING_4CSONLINE_MERCHANT_ID}&t={transaction_id}' ) if verified.text != 'YES': if not payments.finish_payment(transaction_id=transaction_id, status='unconfirmed'): logging.critical( f'Payment not found, transaction_id is {transaction_id}') raise exceptions.SuspiciousOperation() self.message = 'Transaction verification failed, please contact site administrator' logging.critical( f'Payment confirmation failed, transaction_id is {transaction_id}' ) return False return True
def mutate(self, info: ResolveInfo, email: str): if(info.context.user.is_authenticated): raise exceptions.SuspiciousOperation("User is already logged in, it's kinda sus") if not (UserModel.objects.filter(email=email).exists()): raise exceptions.ObjectDoesNotExist('User does not exist') user = UserModel.objects.filter(email=email).get() user.set_unusable_password() jti = user.jtis.create(value=crypto.create_jwt_id()) user.jwt_salt = jti.value user.save() token = shortcuts.get_token(user, info.context) return ForgetPasswordRequest(forget_token=token)
def mutate(self, info: ResolveInfo, refresh_token: str): user = get_user_by_context(info.context) tkn = shortcuts.get_refresh_token(refresh_token, info.context) tkn.revoke() if(user is None): raise exceptions.ObjectDoesNotExist("User doesn't exist for computed payload") if user.hashed_pwd.startswith(crypto.UNUSABLE_PASSWORD_PREFIX): raise exceptions.SuspiciousOperation("User's password is marked as unusable, it's kinda sus") payload = jwt_utils.decode_token( info.context.headers['Authorization'].replace('Bearer ','') ) user.jtis.filter(value=payload['jti']).delete() user.jwt_salt = crypto.create_jwt_id() user.save(update_fields=["jwt_salt"]) return LogoutUser(success=True)