def test_domain_regenerate_from_csv_row(): filename = os.path.abspath( os.path.join(os.path.dirname(__file__), 'domains_sample.csv')) assert csv_import.load_from_csv(filename, dry_run=False) == 2 domain1 = zdomains.domain_find('test-import-1.ai') user1 = zusers.find_account('*****@*****.**') assert domain1 is not None assert user1 is not None assert domain1.registrant.epp_id == 'epp2025164ehqs' assert domain1.contact_admin.epp_id == 'epp2024611d4ru' assert domain1.list_nameservers() == [ 'facebook.com', 'google.com', '', '', ] domain2 = zdomains.domain_find('test-import-2.ai') user2 = zusers.find_account('*****@*****.**') assert user2 is not None assert domain2 is not None assert domain2.registrant.epp_id == 'epp583472wixr' assert domain2.contact_admin.epp_id == 'epp583456ht51' assert domain2.list_nameservers() == [ 'ns1.google.com', 'ns2.google.com', 'ns3.google.com', '' ]
def test_domain_regenerate_from_csv_row_dry_run(): filename = os.path.abspath( os.path.join(os.path.dirname(__file__), 'domains_sample.csv')) assert csv_import.load_from_csv(filename, dry_run=True) == 2 assert zdomains.domain_find('test-import-1.ai') is None assert zdomains.domain_find('test-import-2.ai') is None assert zusers.find_account('*****@*****.**') is None assert zusers.find_account('*****@*****.**') is None
def test_domain_is_in_another_users_basket(self, mock_user_profile_complete, mock_domain_find): """ Test when domain is someone's basket and if it's hold for an hour. So user can't register that domain. """ mock_user_profile_complete.return_value = True mock_domain_find.return_value = mock.MagicMock( epp_id=None, create_date=datetime.datetime.utcnow()) with mock.patch('zen.zmaster.contact_create_update' ) as mock_contact_create_update: mock_contact_create_update.return_value = True self.client.post('/contacts/create/', data=contact_person, follow=True) registrant_info = copy.deepcopy(contact_person) registrant_info['owner'] = zusers.find_account('*****@*****.**') Registrant.registrants.create(**registrant_info) response = self.client.post( '/domains/create/test.ai/', data=dict(nameserver1='ns1.google.com', contact_admin=Contact.contacts.all()[0].id)) assert response.status_code == 302 assert len(Domain.domains.all()) == 0
def test_domain_is_available_after_1_hour(self, mock_zone_is_supported, mock_user_profile_complete, mock_domain_find): """ Test after domain was someone's basket for an hour, user can still register it. """ mock_zone_is_supported.return_value = True mock_user_profile_complete.return_value = True mock_domain_find.return_value = mock.MagicMock( epp_id=None, create_date=datetime.datetime.utcnow() - datetime.timedelta(hours=1), id=1) with mock.patch('zen.zmaster.contact_create_update' ) as mock_contact_create_update: mock_contact_create_update.return_value = True self.client.post('/contacts/create/', data=contact_person, follow=True) registrant_info = copy.deepcopy(contact_person) registrant_info['owner'] = zusers.find_account('*****@*****.**') Registrant.registrants.create(**registrant_info) response = self.client.post( '/domains/create/test.ai/', data=dict(nameserver1='ns1.google.com', contact_admin=Contact.contacts.all()[0].id)) assert response.status_code == 302 assert len(Domain.domains.all()) == 1
def prepare_tester_account(email='*****@*****.**', account_password='******', is_staff=False, account_balance=None, automatic_renewal_enabled=True, email_notifications_enabled=True, join_date=None): tester = zusers.find_account(email) if not tester: tester = zusers.create_account( email, account_password=account_password, is_active=True, person_name='Tester Tester', organization_name='TestingCorp', address_street='TestStreet', address_city='TestCity', address_province='TestProvince', address_postal_code='TestPostalCode', address_country='AI', contact_voice='1234567890', contact_fax='1234567890', contact_email=email, automatic_renewal_enabled=automatic_renewal_enabled, email_notifications_enabled=email_notifications_enabled, ) if account_balance is not None: tester.balance = account_balance if is_staff: tester.is_staff = True if join_date: tester.date_joined = join_date tester.save() return tester
def list_domains(registrant_email): """ List all domains for given user identified by email where he have registrant role assigned. """ existing_account = zusers.find_account(registrant_email) if not existing_account: return [] return list(existing_account.domains.all())
def list_domains(registrant_email): """ List all domains for given user identified by email. """ existing_account = zusers.find_account(registrant_email) if not existing_account: return [] return list(existing_account.domains.all().order_by('expiry_date'))
def get_last_registered_domain(registrant_email): """ If user has any domain, return latest registered domain of the user by email else empty list. """ existing_account = zusers.find_account(registrant_email) if existing_account: domains = existing_account.domains.all() if domains: return domains.order_by('-create_date')[0] return []
def isUserAccountExists(self, *args, **kwargs): """ Condition method. """ if self.expected_owner: return self.expected_owner.registrants.first() existing_account = zusers.find_account( args[0]['epp']['response']['resData']['infData']['email']) if not existing_account: return False return existing_account.registrants.first()
def test_create_domain_successful_without_contacts( self, mock_zone_is_supported, mock_user_profile_complete): mock_zone_is_supported.return_value = True mock_user_profile_complete.return_value = True registrant_info = copy.deepcopy(contact_person) registrant_info['owner'] = zusers.find_account('*****@*****.**') Registrant.registrants.create(**registrant_info) response = self.client.post('/domains/create/test.ai/', data=dict(nameserver1='ns1.google.com', )) assert response.status_code == 302 assert response.url == '/billing/order/create/register/test.ai/' assert len(Domain.domains.all()) == 1
def doUseExistingRegistrant(self, *args, **kwargs): """ Action method. """ response = args[0] self.current_registrant_info = response['epp']['response']['resData'][ 'infData'] self.current_registrant_address_info = zcontacts.extract_address_info( response) existing_account = zusers.find_account( self.current_registrant_info['email']) self.new_registrant_epp_id = existing_account.registrants.first( ).epp_id
def isUserAccountExists(self, *args, **kwargs): """ Condition method. """ if self.expected_owner: return self.expected_owner.registrants.first() existing_account = zusers.find_account( args[0]['epp']['response']['resData']['infData']['email'].lower()) if not existing_account: return False # existing_registrant = existing_account.registrants.first() # if not existing_registrant: # return False # if existing_registrant.epp_id != self.received_registrant_epp_id: # return False return True
def test_zone_is_not_supported(self, mock_user_profile_complete, mock_messages_error): mock_user_profile_complete.return_value = True with mock.patch('zen.zmaster.contact_create_update' ) as mock_contact_create_update: mock_contact_create_update.return_value = True self.client.post('/contacts/create/', data=contact_person) registrant_info = copy.deepcopy(contact_person) registrant_info['owner'] = zusers.find_account('*****@*****.**') Registrant.registrants.create(**registrant_info) response = self.client.post( '/domains/create/test.ax/', data=dict(nameserver1='ns1.google.com', contact_admin=Contact.contacts.all()[0].id)) assert response.status_code == 302 assert response.url == '/domains/' mock_messages_error.assert_called_once()
def prepare_tester_account(email='*****@*****.**', account_password='******'): tester = zusers.find_account(email) if not tester: tester = zusers.create_account( email, account_password=account_password, is_active=True, person_name='Tester Tester', organization_name='TestingCorp', address_street='TestStreet', address_city='TestCity', address_province='TestProvince', address_postal_code='TestPostalCode', address_country='AI', contact_voice='1234567890', contact_fax='1234567890', contact_email='*****@*****.**', ) return tester
def test_domain_is_already_registered(self, mock_user_profile_complete, mock_domain_find): mock_user_profile_complete.return_value = True mock_domain_find.return_value = mock.MagicMock(epp_id='12345') with mock.patch('zen.zmaster.contact_create_update' ) as mock_contact_create_update: mock_contact_create_update.return_value = True self.client.post('/contacts/create/', data=contact_person, follow=True) registrant_info = copy.deepcopy(contact_person) registrant_info['owner'] = zusers.find_account('*****@*****.**') Registrant.registrants.create(**registrant_info) response = self.client.post( '/domains/create/test.ai/', data=dict(nameserver1='ns1.google.com', contact_admin=Contact.contacts.all()[0].id)) assert response.status_code == 302 assert response.url == '/domains/' assert len(Domain.domains.all()) == 0
def test_create_domain_successful(self, mock_zone_is_supported, mock_user_profile_complete): mock_zone_is_supported.return_value = True mock_user_profile_complete.return_value = True with mock.patch('zen.zmaster.contact_create_update' ) as mock_contact_create_update: mock_contact_create_update.return_value = True self.client.post('/contacts/create/', data=contact_person, follow=True) registrant_info = copy.deepcopy(contact_person) registrant_info['owner'] = zusers.find_account('*****@*****.**') Registrant.registrants.create(**registrant_info) response = self.client.post( '/domains/create/test.ai/', data=dict(nameserver1='ns1.google.com', contact_admin=Contact.contacts.all()[0].id)) assert response.status_code == 302 assert len(Domain.domains.all()) == 1
def domain_regenerate_from_csv_row(csv_row, headers, wanted_registrar='whois_ai', dry_run=True): """ """ errors = [] try: csv_record = split_csv_row(csv_row, headers) csv_info = get_csv_domain_info(csv_row, headers) domain = csv_info['name'] except Exception as exc: errors.append('failed processing csv record: ' + str(exc)) return errors if not zdomains.is_valid(domain): #--- invalid domain name errors.append('invalid domain name') return errors #--- lookup existing domain known_domain = zdomains.domain_find(domain) real_registrar_id = csv_record.get('registrar_id_9') if wanted_registrar and real_registrar_id != wanted_registrar: #--- belong to another registrar errors.append('%s: csv record belongs to another registrar %s' % (domain, real_registrar_id, )) return errors real_expiry_date = csv_info['expiry_date'] real_create_date = csv_info['create_date'] real_epp_id = csv_record.get('roid_0') real_auth_key = csv_record.get('auth_info_password_2') real_registrant_contact_id = csv_record.get('registrant_contact_id_24') real_admin_contact_id = csv_record.get('admin_contact_id_54') real_tech_contact_id = csv_record.get('tech_contact_id_69') real_billing_contact_id = csv_record.get('billing_contact_id_39') real_registrant_email = csv_info['registrant']['contact_email'] real_admin_email = csv_info['admin']['contact_email'] real_tech_email = csv_info['tech']['contact_email'] real_billing_email = csv_info['billing']['contact_email'] real_nameservers = csv_info['nameservers'] known_expiry_date = None known_create_date = None known_epp_id = None known_auth_key = None known_registrant_contact_id = None known_admin_contact_id = None known_tech_contact_id = None known_billing_contact_id = None known_nameservers = ['', ] * 4 new_domain = None new_registrant_contact = None new_admin_contact = None new_tech_contact = None new_billing_contact = None need_registrant = False need_admin_contact = False need_tech_contact = False need_billing_contact = False owner_account = zusers.find_account(real_registrant_email) if not owner_account: if dry_run: errors.append('account %s not exist' % real_registrant_email) return errors #--- account check/create new_password=zusers.generate_password(length=10) owner_account = zusers.create_account( email=real_registrant_email, account_password=new_password, is_active=True, ) logger.info('generated new account and password for %s : %s', real_registrant_email, new_password) if known_domain: known_expiry_date = known_domain.expiry_date known_create_date = known_domain.create_date known_epp_id = known_domain.epp_id known_auth_key = known_domain.auth_key known_registrant_contact_id = None if not known_domain.registrant else known_domain.registrant.epp_id known_admin_contact_id = None if not known_domain.contact_admin else known_domain.contact_admin.epp_id known_billing_contact_id = None if not known_domain.contact_billing else known_domain.contact_billing.epp_id known_tech_contact_id = None if not known_domain.contact_tech else known_domain.contact_tech.epp_id known_nameservers = known_domain.list_nameservers() if real_admin_contact_id or real_tech_contact_id or real_billing_contact_id: if known_domain: if not known_tech_contact_id and not known_admin_contact_id and not known_billing_contact_id: if dry_run: errors.append('%s: no contacts present for known domain' % domain) return errors else: errors.append('%s: no csv contacts provided for domain' % domain) return errors if real_registrant_contact_id: #--- registrant check _errs, need_registrant = check_contact_to_be_created( domain_name=domain, known_epp_contact_id=known_registrant_contact_id, real_epp_contact_id=real_registrant_contact_id, real_owner=owner_account, ) if dry_run: errors.extend(_errs) if real_admin_contact_id: #--- admin contact check _errs, need_admin_contact = check_contact_to_be_created( domain_name=domain, known_epp_contact_id=known_admin_contact_id, real_epp_contact_id=real_admin_contact_id, real_owner=owner_account, ) if dry_run: errors.extend(_errs) if real_tech_contact_id: #--- tech contact check _errs, need_tech_contact = check_contact_to_be_created( domain_name=domain, known_epp_contact_id=known_tech_contact_id, real_epp_contact_id=real_tech_contact_id, real_owner=owner_account, ) if dry_run: errors.extend(_errs) if real_billing_contact_id: #--- billing contact check _errs, need_billing_contact = check_contact_to_be_created( domain_name=domain, known_epp_contact_id=known_billing_contact_id, real_epp_contact_id=real_billing_contact_id, real_owner=owner_account, ) if dry_run: errors.extend(_errs) if not dry_run: if need_registrant: #--- registrant create new_registrant_contact = zcontacts.registrant_create( epp_id=real_registrant_contact_id, owner=owner_account, **csv_info['registrant'], ) # TODO: make sure contact was assigned to the domain else: zcontacts.registrant_update( epp_id=real_registrant_contact_id, **csv_info['registrant'], ) if need_admin_contact: #--- admin contact create new_admin_contact = zcontacts.contact_create( epp_id=real_admin_contact_id, owner=owner_account, **csv_info['admin'], ) # TODO: make sure contact was assigned to the domain else: if real_admin_contact_id and real_admin_email: zcontacts.contact_update( epp_id=real_admin_contact_id, **csv_info['admin'], ) if need_tech_contact: #--- tech contact create new_tech_contact = zcontacts.contact_create( epp_id=real_tech_contact_id, owner=owner_account, **csv_info['tech'], ) # TODO: make sure contact was assigned to the domain else: if real_tech_contact_id and real_tech_email: zcontacts.contact_update( epp_id=real_tech_contact_id, **csv_info['tech'], ) if need_billing_contact: #--- billing contact create new_billing_contact = zcontacts.contact_create( epp_id=real_billing_contact_id, owner=owner_account, **csv_info['billing'], ) # TODO: make sure contact was assigned to the domain else: if real_billing_contact_id and real_billing_email: zcontacts.contact_update( epp_id=real_billing_contact_id, **csv_info['billing'], ) if not known_domain: if dry_run: #--- domain not found errors.append('%s: domain not exist' % domain) return errors #--- create new domain new_domain = zdomains.domain_create( domain_name=domain, owner=owner_account, expiry_date=real_expiry_date, create_date=real_create_date, epp_id=real_epp_id, auth_key=real_auth_key, registrar=real_registrar_id, registrant=new_registrant_contact, contact_admin=new_admin_contact, contact_tech=new_tech_contact, contact_billing=new_billing_contact, nameservers=real_nameservers, ) if new_domain: #--- DONE, new domain created return [] if known_expiry_date: dt = real_expiry_date - known_expiry_date dt_hours = float(dt.total_seconds()) / (60.0 * 60.0) if dt_hours >= 24: #--- domain expiry date not in sync if dry_run: errors.append('expiry date not in sync for %s, known is %s, real is %s' % ( domain, known_expiry_date, real_expiry_date, )) return errors known_domain.expiry_date = real_expiry_date known_domain.save() logger.debug('known expiry date updated for %s : %s', known_domain, real_expiry_date) else: if known_domain: #--- expiry date was not set if real_expiry_date: if dry_run: errors.append('expiry date was not set for %s, real is %s' % ( domain, real_expiry_date, )) return errors known_domain.expiry_date = real_expiry_date known_domain.save() logger.debug('expiry date was not set, now updated for %s : %s', known_domain, real_expiry_date) if known_create_date: dt = real_create_date - known_create_date dt_hours = float(dt.total_seconds()) / (60.0 * 60.0) if dt_hours >= 24: #--- domain create date not in sync if dry_run: errors.append('create date not in sync for %s, known is %s, real is %s' % ( domain, known_create_date, real_create_date, )) return errors known_domain.create_date = real_create_date known_domain.save() logger.debug('known create date updated for %s : %s', known_domain, real_create_date) else: if known_domain: if real_create_date: #--- create date was not set if dry_run: errors.append('create date was not set for %s, real is %s' % ( domain, real_create_date, )) return errors known_domain.create_date = real_create_date known_domain.save() logger.debug('create date was not set, now updated for %s : %s', known_domain, real_create_date) #--- check known epp_id if known_epp_id: if known_epp_id != real_epp_id: if dry_run: errors.append('epp_id not in sync for %s, known is %s, real is %s' % ( domain, known_epp_id, real_epp_id, )) return errors known_domain.epp_id = real_epp_id known_domain.save() logger.debug('known epp_id for %s updated : %s', known_domain, real_epp_id) else: if real_epp_id: if known_domain: if dry_run: errors.append('epp_id was not set for %s, real is %s' % ( domain, real_epp_id, )) return errors known_domain.epp_id = real_epp_id known_domain.save() logger.debug('epp_id was not set for %s, now updated : %s', known_domain, real_epp_id) #--- check auth_key if known_auth_key: if known_auth_key != real_auth_key: if dry_run: errors.append('auth_key not in sync for %s, known is %s, real is %s' % ( domain, known_auth_key, real_auth_key, )) return errors known_domain.auth_key = real_auth_key known_domain.save() logger.debug('known auth_key for %s updated : %s', known_domain, real_auth_key) else: if real_auth_key: if known_domain: if dry_run: errors.append('auth_key was not set for %s, real is %s' % ( domain, real_auth_key, )) return errors known_domain.auth_key = real_auth_key known_domain.save() logger.debug('auth_key was not set for %s, now updated : %s', known_domain, real_auth_key) #--- check nameservers for i in range(4): if real_nameservers[i] != known_nameservers[i]: if dry_run: errors.append('nameserver at position %s not in sync for %s, known is %s, real is %s' % ( domain, known_nameservers[i], real_nameservers[i], )) return errors #--- update nameservers if not dry_run: zdomains.update_nameservers(known_domain, real_nameservers) if errors and dry_run: return errors #--- DONE, existing domain updated return errors
def doDBCheckChangeOwner(self, *args, **kwargs): """ Action method. """ if not self.target_domain: return # update registrant of the domain if it is known if self.target_domain.registrant and self.known_registrant and self.target_domain.registrant != self.known_registrant: if not self.change_owner_allowed: logger.error( 'domain registrant changed, but domain already have another owner in local DB' ) raise zerrors.RegistrantAuthFailed( 'domain registrant changed, but domain already have another owner in local DB' ) logger.info('domain %r going to switch registrant %r to %r', self.target_domain, self.target_domain.registrant, self.known_registrant) self.target_domain = zdomains.domain_change_registrant( self.target_domain, self.known_registrant) self.target_domain.refresh_from_db() first_contact = self.known_registrant.owner.contacts.first() self.target_domain = zdomains.domain_replace_contacts( self.target_domain, new_admin_contact=first_contact) self.target_domain.refresh_from_db() return # make sure owner of the domain is correct if self.known_registrant and self.target_domain.owner != self.known_registrant.owner: # just in case given user have multiple registrant contacts... if not self.change_owner_allowed: logger.error('domain already have another owner in local DB') raise zerrors.RegistrantAuthFailed( 'domain already have another owner in local DB') logger.info( 'domain %r going to switch owner %r to %r because of different registrant found', self.target_domain, self.target_domain.owner, self.known_registrant.owner) self.target_domain = zdomains.domain_change_owner( self.target_domain, self.known_registrant.owner) self.target_domain.refresh_from_db() first_contact = self.known_registrant.owner.contacts.first() self.target_domain = zdomains.domain_replace_contacts( self.target_domain, new_admin_contact=first_contact) self.target_domain.refresh_from_db() return # also check if registrant's email changed on back-end # in that situation new account needs to be created and all domains and contacts re-attached to the new account # this must be done separately, because that flow is only focused on single domain object try: received_registrant_email = args[0]['registrant']['response'][ 'epp']['response']['resData']['infData']['email'].lower() except: received_registrant_email = self.target_domain.registrant.contact_email.lower( ) if received_registrant_email != self.target_domain.registrant.contact_email.lower( ): existing_registrant = zcontacts.registrant_find( contact_email=received_registrant_email) if existing_registrant: logger.error( 'registrant %r contact email changed to %r, but another registrant with same email already exist in local DB: %r', self.target_domain.registrant, received_registrant_email, existing_registrant) raise zerrors.RegistrantAuthFailed( 'registrant contact email changed, but another registrant with same email already exist in local DB' ) existing_account = zusers.find_account( email=received_registrant_email) if existing_account: logger.error( 'registrant %r contact email changed to %r, but another account already exist in local DB with same email: %r', self.target_domain.registrant, received_registrant_email, existing_registrant) raise zerrors.RegistrantAuthFailed( 'registrant contact email changed, but another account already exist in local DB with same email' ) logger.error( 'registrant %r contact email changed to %s and needs to be synchronized', self.target_domain.registrant, received_registrant_email) raise zerrors.RegistrantAuthFailed( 'registrant contact email changed and needs to be synchronized' )
def doDBCheckCreateUserAccount(self, *args, **kwargs): """ Action method. """ if self.known_registrant: logger.info( 'registrant already known so skip creating user account') return known_owner = zusers.find_account( self.current_registrant_info['email']) if not known_owner: known_owner = zusers.create_account( email=self.current_registrant_info['email'], account_password=zusers.generate_password(length=10), also_profile=True, is_active=True, person_name=self.current_registrant_address_info.get( 'name', 'unknown'), organization_name=self.current_registrant_address_info.get( 'org', 'unknown'), address_street=self.current_registrant_address_info.get( 'street', 'unknown'), address_city=self.current_registrant_address_info.get( 'city', 'unknown'), address_province=self.current_registrant_address_info.get( 'sp', 'unknown'), address_postal_code=self.current_registrant_address_info.get( 'pc', 'unknown'), address_country=self.current_registrant_address_info.get( 'cc', 'AF'), contact_voice=zcontacts.extract_phone_number( self.current_registrant_info.get('voice', '')), contact_fax=zcontacts.extract_phone_number( self.current_registrant_info.get('fax', '')), contact_email=self.current_registrant_info['email'], ) if not hasattr(known_owner, 'profile'): zusers.create_profile( known_owner, person_name=self.current_registrant_address_info.get( 'name', 'unknown'), organization_name=self.current_registrant_address_info.get( 'org', 'unknown'), address_street=self.current_registrant_address_info.get( 'street', 'unknown'), address_city=self.current_registrant_address_info.get( 'city', 'unknown'), address_province=self.current_registrant_address_info.get( 'sp', 'unknown'), address_postal_code=self.current_registrant_address_info.get( 'pc', 'unknown'), address_country=self.current_registrant_address_info.get( 'cc', 'AF'), contact_voice=zcontacts.extract_phone_number( self.current_registrant_info.get('voice', '')), contact_fax=zcontacts.extract_phone_number( self.current_registrant_info.get('fax', '')), contact_email=self.current_registrant_info['email'], ) self.received_registrant_epp_id = self.new_registrant_epp_id self.known_registrant = zcontacts.registrant_find( epp_id=self.received_registrant_epp_id) if not self.known_registrant: logger.info('new registrant will be created for %r', known_owner) self.known_registrant = zcontacts.registrant_create_from_profile( owner=known_owner, profile_object=known_owner.profile, epp_id=self.received_registrant_epp_id, ) if self.target_domain: zdomains.domain_detach_contact(self.target_domain, 'admin') zdomains.domain_detach_contact(self.target_domain, 'billing') zdomains.domain_detach_contact(self.target_domain, 'tech') self.new_domain_contacts.pop('admin', None) self.new_domain_contacts.pop('billing', None) self.new_domain_contacts.pop('tech', None) if self.target_domain: self.target_domain.refresh_from_db()
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