def test_domain_transfer_takeover_already_in_progress( self, mock_messages_warning, mock_domain_info, mock_user_profile_complete, mock_list_contacts): started_order = billing_orders.order_single_item( owner=self.account, item_type="domain_transfer", item_price=100.0, item_name="bitdust.ai") started_order_item = started_order.items.all()[0] billing_orders.update_order_item(order_item=started_order_item, new_status='pending') mock_domain_info.return_value = { "epp": { "response": { "resData": { "infData": { "clID": "12345", "status": { "@s": "Good" }, "authInfo": { "pw": "Authinfo Correct" } } } } } } mock_user_profile_complete.return_value = True mock_list_contacts.return_value = [mock.MagicMock(), mock.MagicMock()] response = self.client.post('/domains/transfer/', data=dict(domain_name='bitdust.ai', transfer_code='12345')) assert response.status_code == 200 mock_messages_warning.assert_called_once()
def test_pending_renew_order_already_exist(self): tester = testsupport.prepare_tester_account(account_balance=200.0) testsupport.prepare_tester_domain( domain_name='abcd.ai', tester=tester, domain_epp_id='aaa123', domain_status='active', expiry_date=timezone.now() + datetime.timedelta(days=89), # will expire in 89 days auto_renew_enabled=True, ) orders.order_single_item( owner=tester, item_type='domain_renew', item_price=100.0, item_name='abcd.ai', item_details={'some': 'details', }, ) report = tasks.auto_renew_expiring_domains(dry_run=True) assert len(report) == 0
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) restore_order = billing_orders.order_single_item( owner=self.request.user, item_type='domain_restore', item_price=200.0, item_name=kwargs.get('domain_name'), ) context.update({'order': restore_order}) return context
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) restore_order = billing_orders.order_single_item( owner=self.request.user, item_type='domain_restore', item_price=settings.ZENAIDA_DOMAIN_RESTORE_PRICE, item_name=kwargs.get('domain_name'), ) context.update({'order': restore_order}) context['domain_expiry_date'] = timezone.now() + relativedelta(years=2) return context
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) new_order = billing_orders.order_single_item( owner=self.request.user, item_type='domain_register', item_price=settings.ZENAIDA_DOMAIN_PRICE, item_name=kwargs.get('domain_name'), ) context.update({'order': new_order}) context['domain_expiry_date'] = '' domain = zdomains.domain_find(domain_name=kwargs.get('domain_name')) if domain: context['domain_expiry_date'] = domain.expiry_date return context
def form_valid(self, form): domain_name = form.cleaned_data.get('domain_name').strip() transfer_code = form.cleaned_data.get('transfer_code').strip() info = zmaster.domain_read_info( domain=domain_name, auth_info=transfer_code, ) if not info: messages.warning(self.request, 'Domain name is not registered') return super().form_invalid(form) current_registrar = info['epp']['response']['resData']['infData'][ 'clID'] if current_registrar == settings.ZENAIDA_REGISTRAR_ID: messages.warning(self.request, 'Domain transfer is not possible') return super().form_invalid(form) current_statuses = info['epp']['response']['resData']['infData'][ 'status'] current_statuses = [ current_statuses, ] if not isinstance(current_statuses, list) else current_statuses current_statuses = [s['@s'] for s in current_statuses] if 'clientTransferProhibited' in current_statuses or 'serverTransferProhibited' in current_statuses: messages.error(self.request, 'Domain transfer is not possible at the moment. ' \ 'Please contact site administrator') return super().form_invalid(form) if len(orders.find_pending_domain_transfer_order_items(domain_name)): messages.warning(self.request, 'Domain transfer is already in progress') return super().form_invalid(form) current_registrar = info['epp']['response']['resData']['infData'][ 'clID'] if current_registrar == settings.ZENAIDA_AUCTION_REGISTRAR_ID: price = 0.0 else: price = settings.ZENAIDA_DOMAIN_PRICE transfer_order = orders.order_single_item( owner=self.request.user, item_type='domain_transfer', item_price=price, item_name=domain_name, item_details={ 'transfer_code': transfer_code, 'rewrite_contacts': form.cleaned_data.get('rewrite_contacts'), }, ) messages.success(self.request, self.success_message) return shortcuts.redirect('billing_order_details', order_id=transfer_order.id)
def _do_renew_on_behalf_of_customer(self, queryset): report = [] for domain_object in queryset: renewal_order = billing_orders.order_single_item( owner=domain_object.owner, item_type='domain_renew', item_price=settings.ZENAIDA_DOMAIN_PRICE, item_name=domain_object.name, ) if renewal_order.total_price > renewal_order.owner.balance: report.append('"%s": %s' % (domain_object.name, 'not enough funds')) continue new_status = billing_orders.execute_order(renewal_order) report.append('"%s": %s' % (domain_object.name, new_status)) return report
def test_refresh_order_domain_transfer_pending_to_processed( self, mock_domain_transfer_request): tester_domain = testsupport.prepare_tester_domain( domain_name='testdomain.%s' % settings.ZENAIDA_SUPPORTED_ZONES[0], add_contacts=[ 'registrant', 'admin', ], epp_id_dict={ 'registrant': 'ThisIDNotExist1', 'admin': 'ThisIDNotExist2', }, nameservers=[ 'notexist1.com', 'notexist2.com', ], ) tester_domain.owner.balance = 1000.0 tester_domain.owner.save() mock_domain_transfer_request.return_value = True order_object = orders.order_single_item( owner=tester_domain.owner, item_type='domain_transfer', item_price=100.0, item_name='testdomain.ai', item_details={ 'transfer_code': 'abcd1234', }, ) assert len(order_object.items.all()) == 1 order_item = order_object.items.first() assert order_item.status == 'started' assert order_object.status == 'started' orders.execute_order(order_object) order_item.refresh_from_db() assert order_item.status == 'pending' assert order_object.status == 'processing' assert tester_domain.owner.balance == 1000.0 orders.update_order_item(order_item, new_status='processed', charge_user=True) order_item.refresh_from_db() assert order_item.status == 'processed' orders.refresh_order(order_object) assert order_object.status == 'processed' tester_domain.owner.refresh_from_db() assert tester_domain.owner.balance == 900.0
def test_order_domain_renew_processed( self, mock_domain_check_create_update_renew, mock_domain_synchronize_from_backend): tester_domain = testsupport.prepare_tester_domain( domain_name='testdomain.%s' % settings.ZENAIDA_SUPPORTED_ZONES[0], add_contacts=[ 'registrant', 'admin', ], epp_id_dict={ 'registrant': 'ThisIDNotExist1', 'admin': 'ThisIDNotExist2', }, nameservers=[ 'notexist1.com', 'notexist2.com', ], ) tester_domain.owner.balance = 1000.0 tester_domain.owner.save() mock_domain_synchronize_from_backend.return_value = True mock_domain_check_create_update_renew.return_value = True order_object = orders.order_single_item( owner=tester_domain.owner, item_type='domain_renew', item_price=100.0, item_name='testdomain.ai', item_details={ 'some': 'details', }, ) assert len(order_object.items.all()) == 1 order_item = order_object.items.first() assert order_item.status == 'started' assert order_object.status == 'started' orders.execute_order(order_object) order_item.refresh_from_db() assert order_item.status == 'processed' assert order_object.status == 'processed' tester_domain.owner.refresh_from_db() assert tester_domain.owner.balance == 900.0
def wrapper(self, **kwargs): domain_name = kwargs.get('domain_name') order = None started_orders = billing_orders.list_orders( owner=self.request.user, exclude_cancelled=True, include_statuses=['started']) if started_orders: order = started_orders[0] kwargs['has_existing_order'] = True messages.warning( self.request, 'There is an order you did not complete yet. ' 'Please confirm or cancel this order to create a new one') if not order: order = billing_orders.order_single_item( owner=self.request.user, item_type=item_type, item_price=item_price, item_name=domain_name, ) kwargs['order'] = order return func(self, **kwargs)
def test_list_orders(self): tester_domain = testsupport.prepare_tester_domain( domain_name='testdomain.ai', add_contacts=[ 'registrant', 'admin', ], epp_id_dict={ 'registrant': 'ThisIDNotExist1', 'admin': 'ThisIDNotExist2', }, nameservers=[ 'notexist1.com', 'notexist2.com', ], ) order_object_1 = orders.order_single_item( owner=tester_domain.owner, item_type='domain_register', item_price=100.0, item_name='testdomain.ai', item_details={ 'some': 'details', }, ) order_object_1.finished_at = timezone.now() + datetime.timedelta( seconds=1) order_object_1.save() order_object_2 = orders.order_single_item( owner=tester_domain.owner, item_type='domain_renew', item_price=100.0, item_name='testdomain.ai', item_details={ 'some': 'details', }, ) order_object_2.finished_at = timezone.now() + datetime.timedelta( seconds=2) order_object_2.save() order_object_3 = orders.order_single_item( owner=tester_domain.owner, item_type='domain_renew', item_price=100.0, item_name='testdomain.ai', item_details={ 'some': 'details', }, ) order_object_3.finished_at = timezone.now() + datetime.timedelta( seconds=3) order_object_3.save() l = orders.list_orders(tester_domain.owner, exclude_cancelled=True, include_statuses=[ 'started', ]) assert len(l) == 3 assert l[0].id == order_object_3.id assert l[1].id == order_object_2.id assert l[2].id == order_object_1.id
def auto_renew_expiring_domains(dry_run=True, min_days_before_expire=60, max_days_before_expire=90): """ When customer enables "domain auto-renew" feature on "My Profile" page and possess enough account balance Zenaida must take care of his expiring domains and automatically renew them 3 months before the expiration date. The task is checking all expiring domains and for those which has enabled `auto_renew_enabled` flag performs such actions: 1. create a renew order on behalf of customer 2. execute the order right away if customer possess enough account balance 3. send a email notification to customer 4. if user do not have enough account balance, will send a "low_balance" notification 5. checks notifications history to keep only one "low_balance" email per 30 days if `dry_run` is True will only return a list of domains to be automatically renewed. """ moment_now = timezone.now() moment_min_days_before_expire = timezone.now() + datetime.timedelta( days=min_days_before_expire) moment_max_days_before_expire = timezone.now() + datetime.timedelta( days=max_days_before_expire) expiring_active_domains = Domain.domains.filter( expiry_date__gte=moment_min_days_before_expire, expiry_date__lte=moment_max_days_before_expire, status='active', ).exclude(epp_id=None, ) report = [] users_on_low_balance = {} for expiring_domain in expiring_active_domains: if not expiring_domain.auto_renew_enabled: continue if not expiring_domain.owner.profile.automatic_renewal_enabled: continue logger.debug('domain %r is expiring, going to start auto-renew now', expiring_domain.name) current_expiry_date = expiring_domain.expiry_date if expiring_domain.owner.balance < settings.ZENAIDA_DOMAIN_PRICE: # step 4: user is on low balance report.append(( expiring_domain.name, expiring_domain.owner.email, Exception('not enough funds'), )) if expiring_domain.owner.email not in users_on_low_balance: users_on_low_balance[expiring_domain.owner.email] = [] users_on_low_balance[expiring_domain.owner.email].append( expiring_domain.name) logger.debug('not enough funds to auto-renew domain %r', expiring_domain.name) continue if billing_orders.find_pending_domain_renew_order_items( expiring_domain.name): logger.debug('domain renew order already started for %r', expiring_domain.name) continue if dry_run: report.append(( expiring_domain.name, expiring_domain.owner.email, current_expiry_date, )) continue # step 1: create domain renew order renewal_order = billing_orders.order_single_item( owner=expiring_domain.owner, item_type='domain_renew', item_price=settings.ZENAIDA_DOMAIN_PRICE, item_name=expiring_domain.name, item_details={ 'created_automatically': moment_now.isoformat(), }, ) # step 2: execute the order new_status = billing_orders.execute_order(renewal_order) expiring_domain.refresh_from_db() if new_status != 'processed': report.append(( expiring_domain.name, expiring_domain.owner.email, Exception('renew order status is %s' % new_status, ), )) logger.info('for account %r renew order status is %r', expiring_domain.owner, new_status) continue if not expiring_domain.owner.profile.email_notifications_enabled: report.append(( expiring_domain.name, expiring_domain.owner.email, Exception('email notifications are disabled', ), )) logger.info( 'skip "domain_renewed" notification, email notifications are disabled for account %r', expiring_domain.owner) continue # step 3: send a notification to the customer notifications.start_email_notification_domain_renewed( user=expiring_domain.owner, domain_name=expiring_domain.name, expiry_date=expiring_domain.expiry_date, old_expiry_date=current_expiry_date, ) report.append(( expiring_domain.name, expiring_domain.owner.email, expiring_domain.expiry_date, )) for one_user_email, user_domain_names in users_on_low_balance.items(): one_user = zusers.find_account(one_user_email) if not one_user.profile.email_notifications_enabled: report.append(( expiring_domain.name, expiring_domain.owner.email, Exception('email notifications are disabled', ), )) logger.debug( 'skip "low_balance" notification, email notifications are disabled for account %r', expiring_domain.owner) continue recent_low_balance_notification = one_user.notifications.filter( subject='low_balance', created_at__gte=(moment_now - datetime.timedelta(days=30)), ).first() if recent_low_balance_notification: # step 5: found recent notification, skip report.append(( None, one_user.email, Exception('notification already sent recently'), )) logger.debug( 'skip "low_balance" notification, notification already sent recently for account %r', expiring_domain.owner) continue if dry_run: report.append(( None, one_user.email, True, )) continue notifications.start_email_notification_low_balance( one_user, expiring_domains_list=user_domain_names) return report
def form_valid(self, form): if self.request.temporarily_blocked: messages.error(self.request, 'Too many attempts made, please try again later') return self.render_to_response(self.get_context_data(form=form)) domain_name = form.cleaned_data.get('domain_name').strip().lower() transfer_code = form.cleaned_data.get('transfer_code').strip() internal = False # detects if transfer is going to happen within same registrar info = zmaster.domain_read_info( domain=domain_name, auth_info=transfer_code, ) if not info: messages.warning( self.request, 'Domain name is not registered or transfer is not possible at the moment' ) return super().form_invalid(form) current_registrar = info['epp']['response']['resData']['infData'][ 'clID'] if current_registrar == settings.ZENAIDA_REGISTRAR_ID: internal = True current_statuses = info['epp']['response']['resData']['infData'][ 'status'] current_statuses = [ current_statuses, ] if not isinstance(current_statuses, list) else current_statuses current_statuses = [s['@s'] for s in current_statuses] if info['epp']['response']['resData']['infData']['authInfo'][ 'pw'] != 'Authinfo Correct': messages.error(self.request, 'Given transfer code is not correct') return super().form_invalid(form) if 'clientTransferProhibited' in current_statuses or 'serverTransferProhibited' in current_statuses: messages.error( self.request, 'Transfer failed. Probably the domain is locked or the Auth Code was wrong' ) return super().form_invalid(form) if len(orders.find_pending_domain_transfer_order_items(domain_name)): messages.warning(self.request, 'Domain transfer is already in progress') return super().form_invalid(form) if current_registrar in [ settings.ZENAIDA_AUCTION_REGISTRAR_ID, settings.ZENAIDA_REGISTRAR_ID ]: price = 0.0 else: price = settings.ZENAIDA_DOMAIN_PRICE transfer_order = orders.order_single_item( owner=self.request.user, item_type='domain_transfer', item_price=price, item_name=domain_name, item_details={ 'transfer_code': transfer_code, 'rewrite_contacts': True, 'internal': internal, }, ) messages.success(self.request, self.success_message) return shortcuts.redirect('billing_order_details', order_id=transfer_order.id)