def accepted_device(device_api, management_api, clean_migrated_db): """Fixture that sets up an accepted device. Yields a tuple: (device ID, instance of Device, instance of DevAuthorizer)""" d = Device() da = DevAuthorizer() url = device_api.auth_requests_url # poke devauth so that device appears rsp = device_auth_req(url, da, d) assert rsp.status_code == 401 # try to find our devices in all devices listing dev = management_api.find_device_by_identity(d.identity) print('found matching device with ID', dev.id) devid = dev.id # extract authentication data set ID aid = dev.auth_sets[0].id try: with orchestrator.run_fake_for_device_id(devid) as server: management_api.accept_device(devid, aid) except bravado.exception.HTTPError as e: assert e.response.status_code == 204 yield (devid, d, da)
def test_device_limit_applied(self, management_api, internal_api, tenant_foobar_devices, tenant_foobar): """Verify that max accepted devices limit is indeed applied. Since device limits can only be set on per-tenant basis, use fixtures that setup tenant 'foobar' with devices and a token """ expected = 2 internal_api.put_max_devices_limit('foobar', expected) accepted = 0 try: with orchestrator.run_fake_for_device_id(orchestrator.ANY_DEVICE): for dev, dev_auth in tenant_foobar_devices: auth = 'Bearer ' + tenant_foobar fdev = management_api.find_device_by_identity( dev.identity, Authorization=auth) aid = fdev.auth_sets[0].id management_api.accept_device(fdev.id, aid, Authorization=auth) accepted += 1 except bravado.exception.HTTPError as e: assert e.response.status_code == 422 finally: if accepted > expected: pytest.fail( "expected only {} devices to be accepted".format(expected))
def test_device_count_simple(self, devices, management_api): """We have 15 devices, each with a single auth set, verify that accepting/rejecting affects the count""" count = management_api.count_devices() assert count == 15 pending_count = management_api.count_devices(status='pending') assert pending_count == 15 # accept device[0] and reject device[1] for idx, (d, da) in enumerate(devices[0:2]): dev = management_api.find_device_by_identity(d.identity) assert dev devid = dev.id print('found matching device with ID:', dev.id) aid = dev.auth_sets[0].id try: with orchestrator.run_fake_for_device_id(devid) as server: if idx == 0: management_api.accept_device(devid, aid) elif idx == 1: management_api.reject_device(devid, aid) except bravado.exception.HTTPError as e: assert e.response.status_code == 204 TestDevice.verify_device_count(management_api, 'pending', 13) TestDevice.verify_device_count(management_api, 'accepted', 1) TestDevice.verify_device_count(management_api, 'rejected', 1)
def accept_device(device_api, management_api, tenant_token=None): d = Device() da = DevAuthorizer(tenant_token) url = device_api.auth_requests_url kwargs = {} if tenant_token is not None: kwargs["Authorization"] = "Bearer " + tenant_token try: with orchestrator.run_fake_for_device_id(1) as server: with mock_tenantadm_auth(): # poke devauth so that device appears rsp = device_auth_req(url, da, d) assert rsp.status_code == 401 # try to find our devices in all devices listing dev = management_api.find_device_by_identity(d.identity, **kwargs) assert dev is not None print("found matching device with ID", dev.id) devid = dev.id # extract authentication data set ID aid = dev.auth_sets[0].id with orchestrator.run_fake_for_device_id(devid) as server: management_api.accept_device(devid, aid, **kwargs) except bravado.exception.HTTPError as e: assert e.response.status_code == 204 return devid, d, da
def _do_test_error_preauth_limit(self, management_api, device_api, tenant_token=""): auth = management_api.make_auth(tenant_token) devs = management_api.list_devices(**auth) assert len(devs) == 6 limit = 3 for i in range(limit): dev = devs[i] aid = dev.auth_sets[0].id with orchestrator.run_fake_for_device_id(dev.id): management_api.accept_device(dev.id, aid, **auth) try: d = Device(IDDATA) d.public_key = PUBKEY d.private_key = PRIVKEY da = DevAuthorizer(tenant_token) rsp = device_auth_req(device_api.auth_requests_url, da, d) except bravado.exception.HTTPError as e: assert e.response.status_code == 401 dev = management_api.find_device_by_identity(d.identity, **auth) assert dev.auth_sets[0].status == 'preauthorized'
def test_device_count_multiple_auth_sets(self, devices, management_api, device_api): """"Verify that auth sets are properly counted. Take a device, make sure it has 2 auth sets, switch each auth sets between accepted/rejected/pending states """ dev, dauth = devices[0] # pretend device rotates its keys dev.rotate_key() with deviceadm.run_fake_for_device(deviceadm.ANY_DEVICE) as server: device_auth_req(device_api.auth_requests_url, dauth, dev) # should have 2 auth sets now found_dev = management_api.find_device_by_identity(dev.identity) assert len(found_dev.auth_sets) == 2 first_aid, second_aid = found_dev.auth_sets[0].id, found_dev.auth_sets[ 1].id # device [0] has 2 auth sets, but still counts as 1 device TestDevice.verify_device_count(management_api, 'pending', 5) devid = found_dev.id with orchestrator.run_fake_for_device_id( orchestrator.ANY_DEVICE) as server: # accept first auth set management_api.accept_device(devid, first_aid) TestDevice.verify_device_count(management_api, 'pending', 4) TestDevice.verify_device_count(management_api, 'accepted', 1) TestDevice.verify_device_count(management_api, 'rejected', 0) # reject the other management_api.reject_device(devid, second_aid) TestDevice.verify_device_count(management_api, 'pending', 4) TestDevice.verify_device_count(management_api, 'accepted', 1) TestDevice.verify_device_count(management_api, 'rejected', 0) # reject both management_api.reject_device(devid, first_aid) TestDevice.verify_device_count(management_api, 'pending', 4) TestDevice.verify_device_count(management_api, 'accepted', 0) TestDevice.verify_device_count(management_api, 'rejected', 1) # switch the first back to pending, 2nd remains rejected management_api.put_device_status(devid, first_aid, 'pending') TestDevice.verify_device_count(management_api, 'pending', 5) TestDevice.verify_device_count(management_api, 'accepted', 0) TestDevice.verify_device_count(management_api, 'rejected', 0)
def test_device_accept_reject_cycle(self, devices, device_api, management_api): d, da = devices[0] url = device_api.auth_requests_url dev = management_api.get_single_device() assert dev devid = dev.id print("found device with ID:", dev.id) aid = dev.auth_sets[0].id with orchestrator.run_fake_for_device_id(devid) as server: _, rsp = management_api.accept_device(devid, aid) assert rsp.status_code == 204 # device is accepted, we should get a token now rsp = device_auth_req(url, da, d) assert rsp.status_code == 200 da.parse_rsp_payload(d, rsp.text) assert len(d.token) > 0 # reject it now _, rsp = management_api.reject_device(devid, aid) print("RSP:", rsp) assert rsp.status_code == 204 # device is rejected, should get unauthorized rsp = device_auth_req(url, da, d) assert rsp.status_code == 401
def test_device_accept_orchestrator_failure(self, devices, device_api, management_api): d, da = devices[0] url = device_api.auth_requests_url dev = management_api.get_single_device() assert dev devid = dev.id print("found device with ID:", dev.id) aid = dev.auth_sets[0].id status = None try: with orchestrator.run_fake_for_device_id(devid, 500) as server: management_api.accept_device(devid, aid) except bravado.exception.HTTPError as e: status = e.response.status_code assert status == 500
def test_device_accept_reject_cycle(self, devices, device_api, management_api): d, da = devices[0] url = device_api.auth_requests_url dev = management_api.find_device_by_identity(d.identity) assert dev devid = dev.id print("found matching device with ID:", dev.id) aid = dev.auth_sets[0].id try: with orchestrator.run_fake_for_device_id(devid) as server: management_api.accept_device(devid, aid) except bravado.exception.HTTPError as e: assert e.response.status_code == 204 # device is accepted, we should get a token now try: with orchestrator.run_fake_for_device_id(devid) as server: rsp = device_auth_req(url, da, d) assert rsp.status_code == 200 da.parse_rsp_payload(d, rsp.text) assert len(d.token) > 0 # reject it now try: management_api.reject_device(devid, aid) except bravado.exception.HTTPError as e: assert e.response.status_code == 204 # device is rejected, should get unauthorized rsp = device_auth_req(url, da, d) assert rsp.status_code == 401 except bravado.exception.HTTPError as e: assert e.response.status_code == 204
def accepted_tenants_devices(device_api, management_api, clean_migrated_db, cli, request): """Fixture that sets up an accepted devices for tenants. The fixture can be parametrized with a tenants, number of devices and number of authentication sets. Yields a dict: [tenant ID: [device object, ...], ]""" requested = request.param tenants_devices = dict() url = device_api.auth_requests_url for (tenant, dev_count, auth_count) in requested: tenant_devices = [] cli.migrate(tenant=tenant) tenant_token = make_fake_tenant_token(tenant) for _ in range(int(dev_count)): d = Device() for i in range(int(auth_count)): d.rotate_key() da = DevAuthorizer(tenant_token=tenant_token) # poke devauth so that device appears handlers = [ ( "POST", "/api/internal/v1/tenantadm/tenants/verify", lambda _: ( 200, {}, { "id": "507f191e810c19729de860ea", "name": "Acme", }, ), ), ] try: with orchestrator.run_fake_for_device_id(1) as server: with mockserver.run_fake(get_fake_tenantadm_addr(), handlers=handlers) as fake: rsp = device_auth_req(url, da, d) assert rsp.status_code == 401 except bravado.exception.HTTPError as e: assert e.response.status_code == 204 # try to find our devices in all devices listing dev = management_api.find_device_by_identity( d.identity, Authorization="Bearer " + tenant_token) devid = dev.id for a in dev.auth_sets: if compare_keys(a.pubkey, d.public_key): aid = a.id break try: with orchestrator.run_fake_for_device_id(devid) as server: management_api.accept_device(devid, aid, Authorization="Bearer " + tenant_token) token = request_token(d, da, device_api.auth_requests_url) assert len(token) > 0 except bravado.exception.HTTPError as e: assert e.response.status_code == 204 assert dev tenant_devices.append(d) tenants_devices[tenant] = tenant_devices yield tenants_devices
def test_device_accept_nonexistent(self, management_api): try: management_api.accept_device('funnyid', 'funnyid') except bravado.exception.HTTPError as e: assert e.response.status_code == 404