def delete(self):
        """
        Call delete() to remove the Partner from Netki systems.

        :return: AttrDict for valid, non-error responses. Empty dict for 204 responses. Exception for error responses.
        """
        process_request(self.netki_client, '/v1/admin/partner/' + self.name, 'DELETE')
示例#2
0
    def delete(self):
        """
        Call delete() to remove the Partner from Netki systems.

        :return: AttrDict for valid, non-error responses. Empty dict for 204 responses. Exception for error responses.
        """
        process_request(self.netki_client, '/v1/admin/partner/' + self.name,
                        'DELETE')
示例#3
0
    def revoke(self, reason):
        """
        Call revoke() to add the certificate to the revocation list, effectively invalidating it.

        :param reason: Provide a reason for revocation, such as private key lost.

        :return Exception for error responses or required missing data.
        """

        if not self.id:
            raise ValueError('Missing ID - Order Not Yet Submitted')

        process_request(self.netki_client, '/v1/certificate/%s' % self.id, 'DELETE', {'revocation_reason': reason})
示例#4
0
    def submit_csr(self, pkey_obj):
        """
        Call submit_csr() to generate and send a CSR to the API for use when creating the customer's certificate.

        :param pkey_obj: OpenSSL.crypto.PKEY object used to sign the CSR and be bound to the issued certificate.

        :return Exception for error responses or required missing data.
        """

        if not self.id:
            raise ValueError('Missing ID - Order Not Yet Submitted')

        csr_pem = Certificate.generate_csr(self.customer_data, pkey_obj)

        process_request(self.netki_client, '/v1/certificate/%s/csr' % self.id, 'POST', {'signed_csr': csr_pem})
    def test_certificate_auth_post_method_go_right(self):

        # Setup Test Case
        self.netki_client._auth_type = 'certificate'
        self.netki_client.user_key = self.user_key.to_der().encode('hex')

        ret_val = process_request(self.netki_client, 'uri', 'POST', self.request_data)

        # Validate submit_request data
        self.assertEqual(1, self.mockRequests.request.call_count)

        call_args = self.mockRequests.request.call_args[1]
        self.assertEqual(json.dumps(self.request_data), call_args.get('data'))

        self.assertTrue(  # Validate that the Appropriate PK Was Used to Sign the Data
            self.user_key.get_verifying_key().verify(
                call_args['headers']['X-Signature'].decode('hex'),
                self.netki_client.api_url + 'uri' + json.dumps(self.request_data),
                hashfunc=hashlib.sha256, sigdecode=sigdecode_der
            )
        )

        del call_args['headers']['X-Signature']  # Delete sig and Validate Remaining Headers
        self.assertDictEqual(self.certificate_auth_headers, call_args.get('headers'))
        self.assertEqual('POST', call_args.get('method'))
        self.assertEqual('uri', call_args.get('url'))

        # Validate response
        self.assertDictEqual(ret_val, self.response_data)
示例#6
0
    def test_certificate_auth_post_method_go_right(self):

        # Setup Test Case
        self.netki_client._auth_type = 'certificate'
        self.netki_client.user_key = self.user_key.to_der().encode('hex')

        ret_val = process_request(self.netki_client, 'uri', 'POST',
                                  self.request_data)

        # Validate submit_request data
        self.assertEqual(1, self.mockRequests.request.call_count)

        call_args = self.mockRequests.request.call_args[1]
        self.assertEqual(json.dumps(self.request_data), call_args.get('data'))

        self.assertTrue(  # Validate that the Appropriate PK Was Used to Sign the Data
            self.user_key.get_verifying_key().verify(
                call_args['headers']['X-Signature'].decode('hex'),
                self.netki_client.api_url + 'uri' +
                json.dumps(self.request_data),
                hashfunc=hashlib.sha256,
                sigdecode=sigdecode_der))

        del call_args['headers'][
            'X-Signature']  # Delete sig and Validate Remaining Headers
        self.assertDictEqual(self.certificate_auth_headers,
                             call_args.get('headers'))
        self.assertEqual('POST', call_args.get('method'))
        self.assertEqual('uri', call_args.get('url'))

        # Validate response
        self.assertDictEqual(ret_val, self.response_data)
示例#7
0
    def submit_customer_data(self):
        """
        Call submit_customer_data() to submit customer information to the API for validation. A token representing the
        customer data is stored in the certificate object and used when submitting a certificate order.

        :return: Exception for error responses including data validation failures.
        """

        if not self.customer_data:
            raise ValueError('customer_data must be set on Certificate object')

        post_data = dict()
        for key, value in self.customer_data.iteritems():
            if key == 'partner_name':
                continue

            if isinstance(value, datetime):
                value = value.strftime('%Y-%m-%d')

            post_data[key] = value

        post_data['product'] = self.product_id

        response = process_request(self.netki_client, '/v1/certificate/token', 'POST', post_data)

        self.data_token = response.get('token')
示例#8
0
    def submit_certificate_order(self, stripe_token=None):
        """
        Call submit_customer_data() to submit customer information to the API for validation. A token representing the
        customer data is stored in the certificate object and used when submitting a certificate order.

        :param stripe_token: If a user is being billed by Netki, submit the stripe_token returned from the Netki widget.

        :return Exception for error responses or required missing data.
        """

        if self.id:
            raise Exception('Certificate Order Has Already Been Submitted')

        if not self.data_token:
            raise ValueError('Customer Data Submission Not Complete')

        if not self.customer_data.get('email'):
            raise ValueError('Email Required in customer_data For Order Submission')

        if not self.product_id:
            raise ValueError('Product ID required for Order Submission')

        post_data = {
            'certdata_token': self.data_token,
            'email': self.customer_data.get('email'),
            'product': self.product_id,
            'stripe_token': stripe_token
        }

        response = process_request(self.netki_client, '/v1/certificate', 'POST', post_data)

        self.id = response.get('order_id')
    def save(self):
        """
        Commit changes to a WalletName object by submitting them to the API. For new Wallet Names, an id will
        automatically be generated by the server. Run Netki.create_wallet_name() to create a new WalletName object,
        then run save() on your WalletName object to submit it to the API. To update a Wallet Name, run
        Netki.get_wallet_names() to retrieve the Wallet Name object, make your updates, then run save() on the
        WalletName object to commit changes to the API.
        """

        wallet_data = []

        for k in self.wallets.keys():
            wallet_data.append({
                'currency': k,
                'wallet_address': self.wallets[k]
            })

        wallet_name_data = {
            'domain_name': self.domain_name,
            'name': self.name,
            'wallets': wallet_data,
            'external_id': self.external_id
        }

        wn_api_data = {'wallet_names': [wallet_name_data]}

        # If an ID is present it exists in Netki's systems, therefore submit an update
        if self.id:
            wallet_name_data['id'] = self.id
            response = process_request(
                self.netki_client,
                '/v1/partner/walletname',
                'PUT',
                wn_api_data
            )
        else:
            response = process_request(
                self.netki_client,
                '/v1/partner/walletname',
                'POST',
                wn_api_data
            )

        for wn in response.wallet_names:
            if wn.domain_name == self.domain_name and wn.name == self.name:
                self.id = wn.id
    def get_available_products(self):
        """
        Certificate Operation

        Get all available certificate products associated with your account including tier and pricing information.

        :return: Dictionary containing product details.
        """

        return process_request(self, '/v1/certificate/products', 'GET').get('products')
    def get_account_balance(self):
        """
        Certificate Operation

        Get available balance for certificate purchases when using Deposit/Retainer billing.

        :return: Dictionary containing available balance.
        """

        return process_request(self, '/v1/certificate/balance', 'GET').get('available_balance')
    def get_ca_bundle(self):
        """
        Certificate Operation

        Download the root bundle used to validate the certificate chain for Netki issued certificates.

        :return: Dictionary containing certificate bundle.
        """

        return process_request(self, '/v1/certificate/cacert', 'GET').get('cacerts')
示例#13
0
    def delete(self):
        """
        To delete a WalletName object, first run Netki.get_wallet_names() to retrieve the Wallet Name from the API,
        then run delete() on the WalletName object to delete it from Netki systems.
        """

        if not self.id:
            raise Exception(
                'Unable to Delete Object that Does Not Exist Remotely')

        wn_api_data = {
            'wallet_names': [{
                'domain_name': self.domain_name,
                'id': self.id
            }]
        }

        process_request(self.netki_client, '/v1/partner/walletname', 'DELETE',
                        wn_api_data)
    def get_wallet_names(self, domain_name=None, external_id=None):
        """
        Wallet Name Operation

        Retrieve Wallet Names from the Netki API. Four options are available for retrieval:

        * Retrieve all Wallet Names associated with your partner_id by not specifying a domain_name or external_id.
        * Retrieve all Wallet Names associated with a particular partner domain_name by specifying a domain_name.
        * Retrieve all Wallet Names associated with a particular external_id by specifying an external_id.
        * Retrieve all Wallet Names associated with a domain_name and external_id by specifying both domain_name
        and external_id.

        :param domain_name: Domain name to which the requested Wallet Names belong. ``partnerdomain.com``
        :param external_id: Your unique customer identifier specified when creating a Wallet Name.
        :return: List of WalletName objects.
        """

        args = []
        if domain_name:
            args.append('domain_name=%s' % domain_name)

        if external_id:
            args.append('external_id=%s' % external_id)

        uri = '/v1/partner/walletname'

        if args:
            uri = uri + '?' + '&'.join(args)

        response = process_request(self, uri, 'GET')

        if not response.wallet_name_count:
            return []

        # Assemble and return a list of Wallet Name objects from the response data
        all_wallet_names = []

        for wn in response.wallet_names:
            wallet_name = WalletName(
                domain_name=wn.domain_name,
                name=wn.name,
                external_id=wn.external_id,
                id=wn.id
            )

            for wallet in wn.wallets:
                wallet_name.set_currency_address(wallet.currency, wallet.wallet_address)

            wallet_name.set_netki_client(self)

            all_wallet_names.append(wallet_name)

        return all_wallet_names
示例#15
0
    def save(self):
        """
        Commit changes to a WalletName object by submitting them to the API. For new Wallet Names, an id will
        automatically be generated by the server. Run Netki.create_wallet_name() to create a new WalletName object,
        then run save() on your WalletName object to submit it to the API. To update a Wallet Name, run
        Netki.get_wallet_names() to retrieve the Wallet Name object, make your updates, then run save() on the
        WalletName object to commit changes to the API.
        """

        wallet_data = []

        for k in self.wallets.keys():
            wallet_data.append({
                'currency': k,
                'wallet_address': self.wallets[k]
            })

        wallet_name_data = {
            'domain_name': self.domain_name,
            'name': self.name,
            'wallets': wallet_data,
            'external_id': self.external_id
        }

        wn_api_data = {'wallet_names': [wallet_name_data]}

        # If an ID is present it exists in Netki's systems, therefore submit an update
        if self.id:
            wallet_name_data['id'] = self.id
            response = process_request(self.netki_client,
                                       '/v1/partner/walletname', 'PUT',
                                       wn_api_data)
        else:
            response = process_request(self.netki_client,
                                       '/v1/partner/walletname', 'POST',
                                       wn_api_data)

        for wn in response.wallet_names:
            if wn.domain_name == self.domain_name and wn.name == self.name:
                self.id = wn.id
    def load_status(self):
        """
        Call load_status() to retrieve meta data about the domain.

        :return: AttrDict for valid, non-error responses. Empty dict for 204 responses. Exception for error responses.
        """

        response = process_request(self.netki_client, '/v1/partner/domain/' + self.name, 'GET')

        self.status = response.get('status')
        self.delegation_status = response.get('delegation_status')
        self.delegation_message = response.get('delegation_message')
        self.wallet_name_count = response.get('wallet_name_count')
    def load_dnssec_details(self):
        """
        Call load_dnssec_details() to retrieve DNSSEC information required for secure DNS setup.

        :return: AttrDict for valid, non-error responses. Empty dict for 204 responses. Exception for error responses.
        """

        response = process_request(self.netki_client, '/v1/partner/domain/dnssec/' + self.name, 'GET')

        self.public_key_signing_key = response.get('public_key_signing_key')
        self.ds_records = response.get('ds_records')
        self.nameservers = response.get('nameservers')
        self.next_roll = response.get('next_roll')
    def load_status(self):
        """
        Call load_status() to retrieve meta data about the domain.

        :return: AttrDict for valid, non-error responses. Empty dict for 204 responses. Exception for error responses.
        """

        response = process_request(self.netki_client,
                                   '/v1/partner/domain/' + self.name, 'GET')

        self.status = response.get('status')
        self.delegation_status = response.get('delegation_status')
        self.delegation_message = response.get('delegation_message')
        self.wallet_name_count = response.get('wallet_name_count')
    def load_dnssec_details(self):
        """
        Call load_dnssec_details() to retrieve DNSSEC information required for secure DNS setup.

        :return: AttrDict for valid, non-error responses. Empty dict for 204 responses. Exception for error responses.
        """

        response = process_request(self.netki_client,
                                   '/v1/partner/domain/dnssec/' + self.name,
                                   'GET')

        self.public_key_signing_key = response.get('public_key_signing_key')
        self.ds_records = response.get('ds_records')
        self.nameservers = response.get('nameservers')
        self.next_roll = response.get('next_roll')
    def delete(self):
        """
        To delete a WalletName object, first run Netki.get_wallet_names() to retrieve the Wallet Name from the API,
        then run delete() on the WalletName object to delete it from Netki systems.
        """

        if not self.id:
            raise Exception('Unable to Delete Object that Does Not Exist Remotely')

        wn_api_data = {
            'wallet_names': [
                {
                    'domain_name': self.domain_name,
                    'id': self.id
                }
            ]
        }

        process_request(
            self.netki_client,
            '/v1/partner/walletname',
            'DELETE',
            wn_api_data
        )
    def test_api_key_auth_put_method_go_right(self):

        ret_val = process_request(self.netki_client, 'uri', 'PUT', self.request_data)

        # Validate submit_request data
        self.assertEqual(1, self.mockRequests.request.call_count)

        call_args = self.mockRequests.request.call_args[1]
        self.assertEqual(json.dumps(self.request_data), call_args.get('data'))
        self.assertDictEqual(self.api_key_auth_headers, call_args.get('headers'))
        self.assertEqual('PUT', call_args.get('method'))
        self.assertEqual('uri', call_args.get('url'))

        # Validate response
        self.assertDictEqual(ret_val, self.response_data)
    def create_partner(self, partner_name):
        """
        Sub-partner Operation

        Create a sub-partner.

        :param partner_name: Partner Name
        :return: Partner object
        """

        response = process_request(self, '/v1/admin/partner/' + partner_name, 'POST')

        partner = Partner(id=response.partner.id, name=response.partner.name)
        partner.set_netki_client(self)

        return partner
    def test_api_key_auth_get_method_go_right(self):

        del self.api_key_auth_headers['Content-Type']

        ret_val = process_request(self.netki_client, 'uri', 'GET')

        # Validate submit_request data
        self.assertEqual(1, self.mockRequests.request.call_count)

        call_args = self.mockRequests.request.call_args[1]
        self.assertIsNone(call_args.get('data'))
        self.assertDictEqual(self.api_key_auth_headers, call_args.get('headers'))
        self.assertEqual('GET', call_args.get('method'))
        self.assertEqual('uri', call_args.get('url'))

        # Validate response
        self.assertDictEqual(ret_val, self.response_data)
示例#24
0
    def test_api_key_auth_put_method_go_right(self):

        ret_val = process_request(self.netki_client, 'uri', 'PUT',
                                  self.request_data)

        # Validate submit_request data
        self.assertEqual(1, self.mockRequests.request.call_count)

        call_args = self.mockRequests.request.call_args[1]
        self.assertEqual(json.dumps(self.request_data), call_args.get('data'))
        self.assertDictEqual(self.api_key_auth_headers,
                             call_args.get('headers'))
        self.assertEqual('PUT', call_args.get('method'))
        self.assertEqual('uri', call_args.get('url'))

        # Validate response
        self.assertDictEqual(ret_val, self.response_data)
示例#25
0
    def test_api_key_auth_get_method_go_right(self):

        del self.api_key_auth_headers['Content-Type']

        ret_val = process_request(self.netki_client, 'uri', 'GET')

        # Validate submit_request data
        self.assertEqual(1, self.mockRequests.request.call_count)

        call_args = self.mockRequests.request.call_args[1]
        self.assertIsNone(call_args.get('data'))
        self.assertDictEqual(self.api_key_auth_headers,
                             call_args.get('headers'))
        self.assertEqual('GET', call_args.get('method'))
        self.assertEqual('uri', call_args.get('url'))

        # Validate response
        self.assertDictEqual(ret_val, self.response_data)
    def test_delete_non_204_response(self):

        # Setup Test case
        self.mockRequests.request.return_value.status_code = 200
        del self.api_key_auth_headers['Content-Type']

        ret_val = process_request(self.netki_client, 'uri', 'DELETE')

        # Validate submit_request data
        self.assertEqual(1, self.mockRequests.request.call_count)

        call_args = self.mockRequests.request.call_args[1]
        self.assertIsNone(call_args.get('data'))
        self.assertDictEqual(self.api_key_auth_headers, call_args.get('headers'))
        self.assertEqual('DELETE', call_args.get('method'))
        self.assertEqual('uri', call_args.get('url'))

        # Validate response
        self.assertDictEqual(ret_val, self.response_data)
示例#27
0
    def get_status(self):
        """
        Call get_status() to retrieve the order status. If an order is complete, the certificate bundle will be returned.

        :return Exception for error responses or required missing data.
        """

        if not self.id:
            raise ValueError('Missing ID - Order Not Yet Submitted')

        response = process_request(self.netki_client, '/v1/certificate/%s' % self.id, 'GET')

        self.order_status = response.get('order_status')
        self.order_error = response.get('order_error')

        if response.get('certificate_bundle'):
            self.bundle['root'] = response['certificate_bundle'].get('root')
            self.bundle['intermediate'] = response['certificate_bundle'].get('intermediate')
            self.bundle['certificate'] = response['certificate_bundle'].get('certificate')
    def get_partners(self):
        """
        Sub-partner Operation

        Get all partners (partner and sub-partners) associated with your account.

        :return: List containing Partner objects
        """

        response = process_request(self, '/v1/admin/partner', 'GET')

        partner_objects = list()
        for p in response.partners:
            partner = Partner(id=p.id, name=p.name)
            partner_objects.append(partner)

            partner.set_netki_client(self)

        return partner_objects
示例#29
0
    def test_delete_non_204_response(self):

        # Setup Test case
        self.mockRequests.request.return_value.status_code = 200
        del self.api_key_auth_headers['Content-Type']

        ret_val = process_request(self.netki_client, 'uri', 'DELETE')

        # Validate submit_request data
        self.assertEqual(1, self.mockRequests.request.call_count)

        call_args = self.mockRequests.request.call_args[1]
        self.assertIsNone(call_args.get('data'))
        self.assertDictEqual(self.api_key_auth_headers,
                             call_args.get('headers'))
        self.assertEqual('DELETE', call_args.get('method'))
        self.assertEqual('uri', call_args.get('url'))

        # Validate response
        self.assertDictEqual(ret_val, self.response_data)
    def get_domains(self, domain_name=None):
        """
        Domain Operation

        Retrieve all domains associated with your partner_id or a specific domain_name if supplied

        :return: List of Domain objects.
        """

        response = process_request(self, '/api/domain/%s' % domain_name if domain_name else '/api/domain', 'GET')

        if not response.get('domains'):
            return []

        domain_list = list()
        for d in response.domains:
            domain = Domain(d.domain_name)
            domain.set_netki_client(self)

            domain_list.append(domain)

        return domain_list
    def create_partner_domain(self, domain_name, sub_partner_id=None):
        """
        Domain Operation

        Create a partner domain used to offer Wallet Names.

        :param domain_name: ``partnerdomain.com``
        :param (Optional) sub_partner_id: When provided, create a domain_name under the sub_partner_id that you are
            managing.
        :return: Domain object with status and information required to complete domain setup.
        """

        post_data = {'partner_id': sub_partner_id} if sub_partner_id else ''

        response = process_request(self, '/v1/partner/domain/' + domain_name, 'POST', post_data)

        domain = Domain(response.domain_name)
        domain.status = response.status
        domain.nameservers = response.nameservers

        domain.set_netki_client(self)

        return domain