def get_orders_list(module, account, orders_url): ''' Retrieves orders list (handles pagination). ''' orders = [] while orders_url: # Get part of orders list res, info = account.get_request(orders_url, parse_json_result=True, fail_on_error=True) if not res.get('orders'): if orders: module.warn( 'When retrieving orders list part {0}, got empty result list' .format(orders_url)) break # Add order URLs to result list orders.extend(res['orders']) # Extract URL of next part of results list new_orders_url = [] def f(link, relation): if relation == 'next': new_orders_url.append(link) process_links(info, f) new_orders_url.append(None) previous_orders_url, orders_url = orders_url, new_orders_url.pop(0) if orders_url == previous_orders_url: # Prevent infinite loop orders_url = None return orders
def _new_cert_v1(self): ''' Create a new certificate based on the CSR (ACME v1 protocol). Return the certificate object as dict https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-6.5 ''' csr = pem_to_der(self.csr) new_cert = { "resource": "new-cert", "csr": nopad_b64(csr), } result, info = self.account.send_signed_request(self.directory['new-cert'], new_cert) chain = [] def f(link, relation): if relation == 'up': chain_result, chain_info = self.account.get_request(link, parse_json_result=False) if chain_info['status'] in [200, 201]: chain.clear() chain.append(self._der_to_pem(chain_result)) process_links(info, f) if info['status'] not in [200, 201]: raise ModuleFailException("Error new cert: CODE: {0} RESULT: {1}".format(info['status'], result)) else: return {'cert': self._der_to_pem(result), 'uri': info['location'], 'chain': chain}
def _download_cert(self, url): ''' Download and parse the certificate chain. https://tools.ietf.org/html/rfc8555#section-7.4.2 ''' content, info = self.account.get_request( url, parse_json_result=False, headers={'Accept': 'application/pem-certificate-chain'}) if not content or not info['content-type'].startswith( 'application/pem-certificate-chain'): raise ModuleFailException( "Cannot download certificate chain from {0}: {1} (headers: {2})" .format(url, content, info)) cert = None chain = [] # Parse data lines = content.decode('utf-8').splitlines(True) current = [] for line in lines: if line.strip(): current.append(line) if line.startswith('-----END CERTIFICATE-----'): if cert is None: cert = ''.join(current) else: chain.append(''.join(current)) current = [] alternates = [] def f(link, relation): if relation == 'up': # Process link-up headers if there was no chain in reply if not chain: chain_result, chain_info = self.account.get_request( link, parse_json_result=False) if chain_info['status'] in [200, 201]: chain.append(self._der_to_pem(chain_result)) elif relation == 'alternate': alternates.append(link) process_links(info, f) if cert is None or current: raise ModuleFailException( "Failed to parse certificate chain download from {0}: {1} (headers: {2})" .format(url, content, info)) return {'cert': cert, 'chain': chain, 'alternates': alternates}