def determine_registrant_id_based_on_domain(self, domain: Domain) -> str: """ Method used to determine the contact/registrant id of a domain :param domain: the registrant related domain :return: returns the rotld ID of the registrant """ try: domain_info = self.get_domain_info(domain_name=domain.name) except RegistrarConnectorException as e: LOG.debug(e) raise RegistrarConnectorException(e) registrant_id = domain_info.get('registrant_id', None) if not registrant_id: raise RegistrarConnectorException( _('Domain information does not contain registrant id')) return registrant_id
def _raise_if_errors(json_response): if isinstance(json_response, dict): error = json_response.get('error', 0) if error > 0: msg = json_response.get('result_message', None) if msg is not None: raise RegistrarConnectorException(msg)
def _get_rotld_username_and_password(self) -> Tuple[str, str]: """Gets the RoTLD api authentication credentials and checks if they were provided""" username = self.registrar_settings.get('username', None) password = self.registrar_settings.get('password', None) if not username or not password: raise RegistrarConnectorException( _('The RoTLD connector is missing authentication credentials.') ) return username, password
def update_prices(self, tld_name: str): if tld_name != '.ro': raise RegistrarConnectorException( _('RoTLD supports only .ro TLDs')) else: new_prices = dict() extension_prices = getattr(settings, 'ROTLD_PRICES', None) for key, value in extension_prices.items(): if not value: raise RegistrarConnectorException( _('RoTLD prices {} setting was not set').format(key)) new_prices[key] = value RegistrarPrices.objects.update_or_create( defaults=new_prices, tld_name=tld_name, connector=self.get_db_connector(), years=1, currency='RON')
def create_customer(self, customer_details): """ Creare a customer account. :type customer_details: dict :returns str """ result = self.api_request('POST', self.CUSTOMER_SIGNUP_URL, customer_details) try: int_value = int(str(result)) except ValueError: raise RegistrarConnectorException(_('Cannot create the customer account at the registrar.')) return str(int_value)
def api_request(self, request_method, params, raise_on_error=True): api_url = self.TEST_API_URL if self.registrar_settings.get( 'test', False) else self.LIVE_API_URL params['lang'] = self.registrar_settings.get('language', 'en') if params['lang'] not in ('en', 'ro'): LOG.warning(_('RoTLD language must be either "ro" or "en"')) params['lang'] = 'en' params['format'] = 'json' params['command'] = request_method username, password = self._get_rotld_username_and_password() response = requests.post(url=api_url, data=params, verify=False, auth=HTTPDigestAuth( username=username, password=password, ), headers={ "Accept-Charset": "utf-8;q=0.7,*;q=0.7", "Keep-Alive": "30" }) if response.status_code == 401: raise RegistrarConnectorException( _('Authentication Failure. Invalid credentials.')) if response.status_code == 500: raise RegistrarConnectorException( _('Service not available. Server side error.')) if response.status_code != 200: raise RegistrarConnectorException(_('Service not available.')) try: json_response = response.json() except ValueError as e: LOG.exception(e) raise RegistrarConnectorException(e) if raise_on_error: self._raise_if_errors(json_response) return json_response
def api_request(self, request_method, sub_url, params, raise_on_error=True, domain_check=False): test_mode = self.registrar_settings.get('test', False) if not domain_check: api_url = self.TEST_API_URL if test_mode else self.LIVE_API_URL else: api_url = self.DOMAINCHECK_URL url = api_url + sub_url log_params = copy.deepcopy(params) try: log_params.pop('passwd', None) except (KeyError, ValueError): pass LOG.debug('Resellerclub: POST {} with data {}'.format(url, log_params)) params['auth-userid'] = self.registrar_settings.get('auth_userid') params['api-key'] = self.registrar_settings.get('api_key') if not params.get('auth-userid') or not params.get('api-key'): raise RegistrarConnectorException('Registrar connector {} not configured'.format(self.__class__.__name__)) req_method = self._unsafe_testing_request if test_mode else requests.request try: if request_method.upper() in ['POST', 'PUT', 'PATCH']: obj_response = req_method(request_method, url, data=params) else: obj_response = req_method(request_method, url, params=params) except Exception as e: LOG.exception(e) raise RegistrarConnectorException(e) try: json_response = obj_response.json() except ValueError as e: LOG.exception(e) raise RegistrarConnectorException(e) if raise_on_error: self._raise_if_errors(json_response) return json_response
def _raise_if_errors(json_response): # TODO(tomo): Better handling of errors. If msg is None after error status, set default for .get() if isinstance(json_response, dict): status = json_response.get('status') if status is not None: if status.lower() == 'success': return msg = None if status == 'error': msg = json_response.get('error') if status == 'ERROR': msg = json_response.get('message') if status == 'Failed': msg = json_response.get('actionstatusdesc') if msg is not None: raise RegistrarConnectorException(msg)
def create_contact(self, contact_details, customer_id, tld=None): """ Create a logicboxes contact associated with a customer ID. If tld is specified, set the appropriate contact type. :type contact_details: dict :type customer_id: str or int :type tld: str or None """ contact_type = 'Contact' if tld in ['ca', 'cn', 'co', 'coop', 'de', 'es', 'eu', 'nl', 'ru', 'uk']: contact_type = tld.title() + contact_type contact_details['customer-id'] = customer_id contact_details['type'] = contact_type result = self.api_request('POST', self.CONTACTS_ADD_URL, contact_details) try: int_value = int(str(result)) except ValueError: # TODO(tomo): Log the exception/ raise RegistrarConnectorException(_('Cannot create the customer account at the registrar.')) return str(int_value)
def generate_customer_password(length=9): """Generate a password and make sure it contains all required characters by Resellerclub""" limit = 0 password = DomainUtils.generate_password(length) while limit < 20: lowecase_found = False uppercase_found = False number_found = False punctuation_found = False for char in password: if char in string.ascii_lowercase: lowecase_found = True elif char in string.ascii_uppercase: uppercase_found = True elif char in string.digits: number_found = True elif char in string.punctuation: punctuation_found = True if lowecase_found and uppercase_found and number_found and punctuation_found: return password else: password = DomainUtils.generate_password(length) limit += 1 raise RegistrarConnectorException('Unable to generate a Customer password')
def get_actionstatusdesc(api_response) -> str: """ Return 'actionstatusdesc' if present. Raise otherwise.""" try: return api_response['actionstatusdesc'] except KeyError: raise RegistrarConnectorException(_('Invalid response from registrar'))
def restore(self, domain: Domain) -> str: raise RegistrarConnectorException(_('Restore domain not implemented'))
def create_contact(self, domain: Domain): """ Method that creates a registrant :param domain: the domain related to the registrant :return: returns the registrant id """ cnp = None vat_id = None person_type = None registration_number = None reg_no_result = None if domain.contact: contact = domain.contact custom_fields = ContactCustomField.objects.filter(contact=contact) else: contact = domain.service.client custom_fields = ClientCustomField.objects.filter( client=domain.service.client) # get custom fields for .ro domain for custom_field in custom_fields: if custom_field.name == 'rocnp': cnp = custom_field.value if custom_field.name == 'roregistranttype': person_type = custom_field.value if custom_field.name == 'roregistrationnumber': registration_number = custom_field.value # VALIDATIONS if not person_type: raise RegistrarConnectorException( _('Contact must have the person type specified')) if person_type == 'p': # validate cnp for persons if registration_number: raise RegistrarConnectorException( _('Romanian private person must not have registration number' )) cnp_check = CNP(cnp=cnp) if not cnp_check.is_valid(): raise RegistrarConnectorException(_('CNP is not valid')) if not cnp_check.check_if_at_least_eighteen_years_old(): raise RegistrarConnectorException( _('Person must have at least 18 years old')) else: # validate fiscal code for commercial entities and registry of commerce number vat_id = contact.vat_id if not RotldValidators.is_valid_fiscal_code(code=vat_id): raise RegistrarConnectorException( _('Fiscal code (VAT ID) is not valid.')) if (person_type == 'c' or person_type == 'ap') and contact.country == 'RO': # registry of commerce number validation if not registration_number: raise RegistrarConnectorException( _('Company Registry of Commerce number is mandatory for Commercial Romanian entities' )) is_valid, reg_no_result = RotldValidators.is_valid_com_reg_no( registration_number) if not is_valid: raise RegistrarConnectorException(reg_no_result) # validate and format phone number phone, phone_cc = RotldConnector.get_phone_and_phone_cc( contact.phone, contact.country) client_phone = RotldConnector._get_rotld_phone(national_number=phone, phone_cc=phone_cc) params = { 'name': contact.name, 'address1': contact.address1, 'address2': contact.address2, # 'address3'(optional): NOTE(manu) we don't have this field yet, 'city': contact.city, 'state_province': contact.state, 'postal_code': contact.zip_code, 'country_code': contact.country, 'phone': client_phone, # 'fax'(optional): NOTE(manu) we don't have this field yet, 'email': contact.email, 'person_type': person_type, 'cnp_fiscal_code': cnp if person_type == 'p' else vat_id, } if reg_no_result: params['registration_number'] = reg_no_result json_response = self.api_request( request_method=RotldActions.CREATE_CONTACT, params=params) response_data = json_response.get('data', {}) return response_data.get('cid', None)