def testHostname(self): valid_hostnames = [ u"i-123445", u"5dfsdfsdrrfsv", u"432498234234A" u"234234235235235235", # Couldn't find anything in the RFC saying it's not valid u"A45fsdff045-dsflk4dfsdc.ret43tjssfd", u"4354sfsdkfj4TEfdlv56gdgdfRET.dsf-dg", u"r" * 255, ] not_valid_hostnames = [u"abc" * 150, u"sdf4..sfsd", u"$42sdf", u".sfdsfds" u"s™£™£¢ª•ªdfésdfs"] for hostname in valid_hostnames: self.assertTrue(is_valid_hostname(hostname), hostname) for hostname in not_valid_hostnames: self.assertFalse(is_valid_hostname(hostname), hostname)
def simple_post(): # Get the domain/message and validate domain = request.forms.get('domain') subdomain = request.forms.get('subdomain') message = request.forms.get('message') if domain == None or domain == '' or not util.is_valid_hostname( domain ) or message == None or message == '' or not util.is_valid_message( message): return template('invalid_data.tpl') # See if the DNS Provider supports domain connect json_data, txt, error_message = util.get_domainconnect_json(domain) if json_data == None: return template('no_domain_connect.tpl', {'reason': str(error_message)}) width = 750 if 'width' in json_data: width = json_data['width'] height = 750 if 'height' in json_data: height = json_data['height'] # See if our template is supported check_url1 = json_data[ 'urlAPI'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template1 if not util.check_template(check_url1): return template('no_domain_connect.tpl', {'reason': 'Missing template support'}) dns_message_data = util.dns_message_data(message) # Generate the query string for synchronous calls qs = 'domain=' + urllib.parse.quote( domain, '') + '&RANDOMTEXT=' + urllib.parse.quote( dns_message_data) + '&IP=' + urllib.parse.quote(config.ip, '') if subdomain != '' and subdomain != None: qs = qs + '&host=' + urllib.parse.quote(subdomain, '') # Create the URL to configure template 1 synchronousUrl1 = json_data[ 'urlSyncUX'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template1 + '/apply?' + qs fqdn = domain if subdomain: fqdn = subdomain + '.' + fqdn return template( 'simple_post.tpl', { 'providerName': json_data['providerName'], 'width': width, 'height': height, 'synchronousUrl1': synchronousUrl1, 'fqdn': fqdn })
def testHostname(self): valid_hostnames = [ u'i-123445', u'5dfsdfsdrrfsv', u'432498234234A' u'234234235235235235', # Couldn't find anything in the RFC saying it's not valid u'A45fsdff045-dsflk4dfsdc.ret43tjssfd', u'4354sfsdkfj4TEfdlv56gdgdfRET.dsf-dg', u'r' * 255, ] not_valid_hostnames = [ u'abc' * 150, u'sdf4..sfsd', u'$42sdf', u'.sfdsfds' u's™£™£¢ª•ªdfésdfs' ] for hostname in valid_hostnames: self.assertTrue(is_valid_hostname(hostname), hostname) for hostname in not_valid_hostnames: self.assertFalse(is_valid_hostname(hostname), hostname)
def testHostname(self): valid_hostnames = [ u'i-123445', u'5dfsdfsdrrfsv', u'432498234234A' u'234234235235235235', # Couldn't find anything in the RFC saying it's not valid u'A45fsdff045-dsflk4dfsdc.ret43tjssfd', u'4354sfsdkfj4TEfdlv56gdgdfRET.dsf-dg', u'r'*255, ] not_valid_hostnames = [ u'abc' * 150, u'sdf4..sfsd', u'$42sdf', u'.sfdsfds' u's™£™£¢ª•ªdfésdfs' ] for hostname in valid_hostnames: self.assertTrue(is_valid_hostname(hostname), hostname) for hostname in not_valid_hostnames: self.assertFalse(is_valid_hostname(hostname), hostname)
def sync_post(): # This only works for the hosting website over the supported protocol if request.headers['Host'] != config.hosting_website or request.urlparts.scheme != config.protocol: return abort(404) # Get the domain/message and validate domain = request.forms.get('domain') subdomain = request.forms.get('subdomain') message = request.forms.get('message') if domain == None or domain == '' or not util.is_valid_hostname(domain) or message == None or message == '' or not util.is_valid_message(message): return template('invalid_data.tpl') # See if the DNS Provider supports domain connect json_data, txt = util.get_domainconnect_json(domain) if json_data == None: return template('no_domain_connect.tpl', {'reason' : 'Unable to read configuration'}) width = 750 if json_data.has_key('width'): width = json_data['width'] height = 750 if json_data.has_key('height'): height =json_data['height'] # See if our templates are supported check_url1 = json_data['urlAPI'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template1 check_url2 = json_data['urlAPI'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template2 if not util.check_template(check_url1) or not util.check_template(check_url2): return template('no_domain_connect.tpl', {'reason' : 'Missing template support'}) dns_message_data = util.dns_message_data(message) # Generate the query string for synchronous calls qs = 'domain=' + urllib.quote(domain, '') + '&RANDOMTEXT=' + urllib.quote(dns_message_data) + '&IP=' + urllib.quote(config.ip, '') if subdomain != '' and subdomain != None: qs = qs + '&host=' + urllib.quote(subdomain, '') # Create the URL to configure template 1 synchronousUrl1 = json_data['urlSyncUX'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template1 + '/apply?' + qs # Create the URL to configure template2. Template 2 needs a singature sig = sigutil.generate_sig(config.priv_key, qs) synchronousSignedUrl2 = json_data['urlSyncUX'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template2 + '/apply?' + qs + '&sig=' + urllib.quote(sig, '') + '&key=_dck1' # Generate the redirect uri redirect_uri = config.protocol + "://" + config.hosting_website + "/sync_confirm?domain=" + domain + "&subdomain=" + subdomain # Query string with the redirect qsRedirect = qs + "&redirect_uri=" + urllib.quote(redirect_uri, '') # Create the URL to configure template 1 with a redirect back synchronousRedirectUrl1 = json_data['urlSyncUX'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template1 + '/apply?' + qsRedirect # Create the URL to configure template 2 with a redirect back. Template 2 needs a signature sigRedirect = sigutil.generate_sig(config.priv_key, qsRedirect) synchronousSignedRedirectUrl2 = json_data['urlSyncUX'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template2 + '/apply?' + qsRedirect + '&sig=' + urllib.quote(sigRedirect, '') + '&key=_dck1' return template('sync_post.tpl', { 'txt': txt, 'json': json.dumps(json_data), 'check_url1' : check_url1, 'check_url2' : check_url2, 'domain': domain, 'providerName' : json_data['providerName'], 'width': width, 'height': height, 'synchronousUrl1' : synchronousUrl1, 'synchronousSignedUrl2' : synchronousSignedUrl2, 'qs': qs, 'sig': sig, 'synchronousRedirectUrl1' : synchronousRedirectUrl1, 'synchronousSignedRedirectUrl2' : synchronousSignedRedirectUrl2, 'qsRedirect' : qsRedirect, 'sigRedirect': sigRedirect })
def async_post(): # This only works for the hosting website over the supported protocol if request.headers[ 'Host'] != config.hosting_website or request.urlparts.scheme != config.protocol: return abort(404) # Get the domain and hosts domain = request.forms.get('domain') hosts = request.forms.get('hosts') if hosts is None: hosts = '' if domain == None or domain == '' or not util.is_valid_hostname(domain): return template('invalid_data.tpl') # See if the DNS Provider supports domain connect json_data, txt, error_message = util.get_domainconnect_json(domain) if json_data == None: return template('no_domain_connect.tpl', {'reason': str(error_message)}) # Get the provider name dns_provider = json_data['providerName'] # See if our templates are supported check_url1 = json_data[ 'urlAPI'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template1 check_url2 = json_data[ 'urlAPI'] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template2 if not util.check_template(check_url1) or not util.check_template( check_url2): return template('no_domain_connect.tpl', {'reason': 'Missing template support'}) # Verify that the provider supports async if not dns_provider in config.oAuthSecrets or not dns_provider in config.oAuthAPIURLs or config.oAuthAPIURLs[ dns_provider] != json_data['urlAPI']: return template('no_domain_connect.tpl', {'reason': 'Not onboarded as oAuth provider'}) # The redirect_url is part of oAuth and where the user will be sent after consent. Appended to this URL will be the OAuth code or an error redirect_url = config.protocol + "://" + config.hosting_website + "/async_oauth_response?domain=" + domain + "&hosts=" + hosts + "&dns_provider=" + dns_provider # Right now the call to get a permission requires the template in the path. Doesn't matter which one. Spec is updating to eliminate this asynchronousUrl = json_data['urlAsyncUX'] + '/v2/domainTemplates/providers/' + config.provider + '?' + \ "domain=" + domain + \ "&host=" + hosts + \ "&client_id=" + config.provider + \ "&scope=" + config.template1 + '+' + config.template2 + \ "&redirect_uri=" + urllib.parse.quote(redirect_url, '') return template( 'async_post.tpl', { 'txt': txt, 'json': json.dumps(json_data), 'check_url1': check_url1, 'check_url2': check_url2, 'domain': domain, 'hosts': hosts, 'providerName': json_data['providerName'], 'asynchronousUrl': asynchronousUrl })
def async_confirm(): # This only works for the hosting website over the supported protocol if request.headers[ 'Host'] != config.hosting_website or request.urlparts.scheme != config.protocol: return abort(404) # Get the domain name, message, acccess token domain = request.forms.get('domain') subdomain = request.forms.get('subdomain') hosts = request.forms.get('hosts') message = request.forms.get('message') access_token = request.forms.get('access_token') dns_provider = request.forms.get('dns_provider') force = request.forms.get('force') if force == None or force == '': force = 0 else: force = 1 # Validate the form settings if domain == None or domain == '' or not util.is_valid_hostname( domain ) or message == None or message == '' or not util.is_valid_message( message ) or access_token == None or access_token == '' or dns_provider == None or dns_provider == '': return template('invalid_data.tpl') dns_message_data = util.dns_message_data(message) # This is the URL to call the api to apply the template if 'template2' in request.forms.keys(): url = config.oAuthAPIURLs[ dns_provider] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template2 + '/apply?domain=' + domain + '&host=' + subdomain + '&force=' + str( force) + '&RANDOMTEXT=' + dns_message_data + '&IP=' + config.ip applied_template = 'Template 2' else: url = config.oAuthAPIURLs[ dns_provider] + '/v2/domainTemplates/providers/' + config.provider + '/services/' + config.template1 + '/apply?domain=' + domain + '&host=' + subdomain + '&force=' + str( force) + '&RANDOMTEXT=' + dns_message_data + '&IP=' + config.ip applied_template = 'Template 1' # Call the api with the oauth acces bearer token r = requests.post(url, headers={'Authorization': 'Bearer ' + access_token}, verify=True) # If this fails, and there is a re-auth token, we could add this code here # Return a page. Normally you would store the access and re-auth tokens and redirect the client browser return template( 'async_confirm.tpl', { "applied_template": applied_template, "url": url, "message": message, "access_token": access_token, "domain": domain, "subdomain": subdomain, "hosts": hosts, "dns_provider": dns_provider, "status_code": str(r.status_code) })