def test_fail_bad_request(self, user): useradmm = ApiClient(useradm.URL_MGMT) devauthm = ApiClient(deviceauth_v2.URL_MGMT) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # id data not json priv, pub = util.crypto.rsa_get_keypair() id_data = '{\"mac\": \"foo\"}' body = deviceauth_v2.preauth_req( id_data, pub) r = devauthm.with_auth(utoken).call('POST', deviceauth_v2.URL_DEVICES, body) assert r.status_code == 400 # not a valid key id_data = {'mac': 'foo'} body = deviceauth_v2.preauth_req( id_data, 'not a public key') r = devauthm.with_auth(utoken).call('POST', deviceauth_v2.URL_DEVICES, body) assert r.status_code == 400
def do_test_delete_status_failed(self, devs_authsets, user): useradmm = ApiClient(useradm.URL_MGMT) devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # not found: valid device, bogus authset r = devauthm.with_auth(utoken).call('DELETE', deviceauth_v2.URL_AUTHSET, path_params={ 'did': devs_authsets[0].id, 'aid': "foo" }) assert r.status_code == 404 # not found: bogus device r = devauthm.with_auth(utoken).call('DELETE', deviceauth_v2.URL_AUTHSET, path_params={ 'did': "foo", 'aid': "bar" }) assert r.status_code == 404
def do_test_get_device(self, devs_authsets, user): da = ApiClient(deviceauth_v2.URL_MGMT) ua = ApiClient(useradm.URL_MGMT) # log in user r = ua.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # existing devices for dev in devs_authsets: r = da.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICE, path_params={'id': dev.id}) assert r.status_code == 200 api_dev = r.json() self._compare_dev(dev, api_dev) # non-existent devices for id in ['foo', 'bar']: r = da.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICE, path_params={'id': id}) assert r.status_code == 404
def do_test_delete_device_ok(self, devs_authsets, user, tenant_token=''): devapim = ApiClient(deviceauth_v2.URL_MGMT) devapid = ApiClient(deviceauth_v1.URL_DEVICES) userapi = ApiClient(useradm.URL_MGMT) depapi = ApiClient(deployments.URL_DEVICES) # log in user r = userapi.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # decommission a pending device dev_pending = filter_and_page_devs(devs_authsets, status='pending')[0] r = devapim.with_auth(utoken).call('DELETE', deviceauth_v2.URL_DEVICE, path_params={'id': dev_pending.id}) assert r.status_code == 204 # only verify the device is gone r = devapim.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICE, path_params={'id': dev_pending.id}) assert r.status_code == 404 # log in an accepted device dev_acc = filter_and_page_devs(devs_authsets, status='accepted')[0] body, sighdr = deviceauth_v1.auth_req(dev_acc.id_data, dev_acc.authsets[0].pubkey, dev_acc.authsets[0].privkey, tenant_token) r = devapid.call('POST', deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 dtoken = r.text # decommission the accepted device r = devapim.with_auth(utoken).call('DELETE', deviceauth_v2.URL_DEVICE, path_params={'id': dev_acc.id}) assert r.status_code == 204 # verify the device lost access r = depapi.with_auth(dtoken).call('GET', deployments.URL_NEXT, qs_params={'device_type': 'foo', 'artifact_name': 'bar'}) assert r.status_code == 401 # verify the device is gone r = devapim.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICE, path_params={'id': dev_acc.id}) assert r.status_code == 404
def do_test_delete_device_not_found(self, devs_authsets, user): ua = ApiClient(useradm.URL_MGMT) da = ApiClient(deviceauth_v2.URL_MGMT) # log in user r = ua.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # try delete r = da.with_auth(utoken).call('DELETE', deviceauth_v2.URL_DEVICE, path_params={'id': 'foo'}) assert r.status_code == 404 # check device list unmodified r = da.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 200 api_devs = r.json() self._compare_devs(devs_authsets, api_devs)
def do_test_get_authset_status(self, devs_authsets, user): devauthm = ApiClient(deviceauth_v2.URL_MGMT) useradmm = ApiClient(useradm.URL_MGMT) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # try valid authsets for d in devs_authsets: for a in d.authsets: r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_AUTHSET_STATUS, path_params={'did': d.id, 'aid': a.id }) assert r.status_code == 200 assert r.json()['status'] == a.status # invalid authset or device for did, aid in [(devs_authsets[0].id, "foo"), ("foo", "bar")]: r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_AUTHSET_STATUS, path_params={'did': did, 'aid': aid }) assert r.status_code == 404
def test_authenticated_dev_is_rejected(self, tenants_users_devices): dac = ApiClient(deviceadm.URL_MGMT) uc = ApiClient(useradm.URL_MGMT) devauth = ApiClient(deviceauth.URL_DEVICES) tc = ApiClient(tenantadm.URL_INTERNAL) dc = ApiClient(deployments.URL_DEVICES) # accept a dev device = tenants_users_devices[0].devices[0] user = tenants_users_devices[0].users[0] r = uc.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text dev = tenants_users_devices[0].devices[0] r = dac.with_auth(utoken).call( 'PUT', deviceadm.URL_AUTHSET_STATUS, deviceadm.req_status('accepted'), path_params={'id': get_authset_id(dev.pubkey, utoken)}) assert r.status_code == 200 # request auth body, sighdr = deviceauth.auth_req(device.id_data, device.pubkey, device.privkey, device.tenant_token) r = devauth.call('POST', deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 dtoken = r.text # check device can access APIs r = dc.with_auth(dtoken).call('GET', deployments.URL_NEXT, qs_params={ 'device_type': 'foo', 'artifact_name': 'bar' }) assert r.status_code == 204 # suspend r = tc.call('PUT', tenantadm.URL_INTERNAL_SUSPEND, tenantadm.req_status('suspended'), path_params={'tid': tenants_users_devices[0].id}) assert r.status_code == 200 time.sleep(10) # check device is rejected r = dc.with_auth(dtoken).call('GET', deployments.URL_NEXT, qs_params={ 'device_type': 'foo', 'artifact_name': 'bar' }) assert r.status_code == 401
def test_authenticated_user_is_rejected(self, tenants_users): tc = ApiClient(tenantadm.URL_INTERNAL) uc = ApiClient(useradm.URL_MGMT) dc = ApiClient(deviceauth_v2.URL_MGMT) u = tenants_users[0].users[0] # log in r = uc.call('POST', useradm.URL_LOGIN, auth=(u.name, u.pwd)) assert r.status_code == 200 token = r.text # check can access an api r = dc.with_auth(token).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 200 # suspend tenant r = tc.call('PUT', tenantadm.URL_INTERNAL_SUSPEND, tenantadm.req_status('suspended'), path_params={'tid': tenants_users[0].id}) assert r.status_code == 200 time.sleep(10) # check token is rejected r = dc.with_auth(token).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 401
def test_ok(self, user): useradmm = ApiClient(useradm.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) invm = ApiClient(inventory.URL_MGMT) invd = ApiClient(inventory.URL_DEV) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # prepare accepted devices devs = make_accepted_devices(utoken, devauthd, 3) # wait for devices to be provisioned time.sleep(3) for i, d in enumerate(devs): payload = [ { "name": "mac", "value": "mac-new-" + str(d.id) }, { #empty value for existing "name": "sn", "value": "", }, { #empty value for new "name": "new-empty", "value": "", } ] r = invd.with_auth(d.token).call('PATCH', inventory.URL_DEVICE_ATTRIBUTES, payload) assert r.status_code == 200 for d in devs: r = invm.with_auth(utoken).call('GET', inventory.URL_DEVICE, path_params={'id': d.id}) assert r.status_code == 200 api_dev = r.json() assert len(api_dev['attributes']) == 3 for a in api_dev['attributes']: if a['name'] == 'mac': assert a['value'] == 'mac-new-' + str(api_dev['id']) elif a['name'] == 'sn': assert a['value'] == '' elif a['name'] == 'new-empty': assert a['value'] == '' else: assert False, 'unexpected attribute ' + a['name']
def do_test_put_status_failed(self, devs_authsets, user): useradmm = ApiClient(useradm.URL_MGMT) devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # not found: valid device, bogus authset r = devauthm.with_auth(utoken).call( 'PUT', deviceauth_v2.URL_AUTHSET_STATUS, deviceauth_v2.req_status('accepted'), path_params={ 'did': devs_authsets[0].id, 'aid': "foo" }) assert r.status_code == 404 # not found: bogus device r = devauthm.with_auth(utoken).call( 'PUT', deviceauth_v2.URL_AUTHSET_STATUS, deviceauth_v2.req_status('accepted'), path_params={ 'did': "foo", 'aid': "bar" }) assert r.status_code == 404 # bad request - invalid status r = devauthm.with_auth(utoken).call( 'PUT', deviceauth_v2.URL_AUTHSET_STATUS, deviceauth_v2.req_status('invalid'), path_params={ 'did': devs_authsets[0].id, 'aid': devs_authsets[0].authsets[0].id }) assert r.status_code == 400 # bad request - invalid payload r = devauthm.with_auth(utoken).call('PUT', deviceauth_v2.URL_AUTHSET_STATUS, '{"foo": "bar"}', path_params={ 'did': devs_authsets[0].id, 'aid': devs_authsets[0].authsets[0].id }) assert r.status_code == 400
def get_device_by_id_data(id_data, utoken): devauthm = ApiClient(deviceauth_v2.URL_MGMT) page = 0 per_page = 20 qs_params = {} found = None while True: page = page + 1 qs_params['page'] = page qs_params['per_page'] = per_page r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES, qs_params=qs_params) assert r.status_code == 200 api_devs = r.json() found = [d for d in api_devs if d['identity_data'] == id_data] if len(found) > 0: break if len(api_devs) == 0: break assert len(found) == 1 return found[0]
def test_fail_no_attr_value(self, user): useradmm = ApiClient(useradm.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) invm = ApiClient(inventory.URL_MGMT) invd = ApiClient(inventory.URL_DEV) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # prepare accepted devices devs = make_accepted_devices(utoken, devauthd, 1) # wait for devices to be provisioned time.sleep(3) for i, d in enumerate(devs): payload = [{ "name": "mac", }] r = invd.with_auth(d.token).call('PATCH', inventory.URL_DEVICE_ATTRIBUTES, payload) assert r.status_code == 400
def change_authset_status(did, aid, status, utoken): devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = devauthm.with_auth(utoken).call('PUT', deviceauth_v2.URL_AUTHSET_STATUS, deviceauth_v2.req_status(status), path_params={'did': did, 'aid': aid }) assert r.status_code == 204
def do_test_get_devices_ok(self, user, tenant_token=''): useradmm = ApiClient(useradm.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) invm = ApiClient(inventory.URL_MGMT) invd = ApiClient(inventory.URL_DEV) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # prepare accepted devices devs = make_accepted_devices(utoken, devauthd, 40, tenant_token) # wait for devices to be provisioned time.sleep(3) r = invm.with_auth(utoken).call('GET', inventory.URL_DEVICES, qs_params={'per_page': 100}) assert r.status_code == 200 api_devs = r.json() assert len(api_devs) == 40
def verify_devices_unmodified(self, user, in_devices): devauthm = ApiClient(deviceauth_v2.URL_MGMT) useradmm = ApiClient(useradm.URL_MGMT) r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 200 api_devs = r.json() assert len(api_devs) == len(in_devices) for ad in api_devs: assert ad['status'] == 'pending' orig_device = [d for d in in_devices if d.id_data == ad['identity_data']] assert len(orig_device) == 1 orig_device = orig_device[0] assert len(ad['auth_sets']) == 1 aset = ad['auth_sets'][0] assert util.crypto.rsa_compare_keys(aset['pubkey'], orig_device.pubkey)
def verify_dev_provisioned(self, dev, utoken): invm = ApiClient(inventory.URL_MGMT) r = invm.with_auth(utoken).call('GET', inventory.URL_DEVICE, path_params={'id': dev.id}) assert r.status_code == 200 api_dev = r.json()
def do_test_filter_devices_ok(self, user, tenant_token=''): useradmm = ApiClient(useradm.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) invm = ApiClient(inventory.URL_MGMT) invd = ApiClient(inventory.URL_DEV) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # prepare accepted devices devs = make_accepted_devices(utoken, devauthd, 40, tenant_token) # wait for devices to be provisioned time.sleep(3) r = invm.with_auth(utoken).call('GET', inventory.URL_DEVICES, qs_params={'per_page': 100}) assert r.status_code == 200 api_devs = r.json() assert len(api_devs) == 40 # upload inventory attributes for i, d in enumerate(devs): payload = [{"name": "mac", "value": "de:ad:be:ef:06:" + str(i)}] r = invd.with_auth(d.token).call('PATCH', inventory.URL_DEVICE_ATTRIBUTES, payload) assert r.status_code == 200 # get device with exact mac value qs_params = {} qs_params['per_page'] = 100 qs_params['mac'] = 'de:ad:be:ef:06:7' r = invm.with_auth(utoken).call('GET', inventory.URL_DEVICES, qs_params=qs_params) assert r.status_code == 200 api_devs = r.json() assert len(api_devs) == 1
def get_device_by_id_data(id_data, utoken): devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 200 api_devs = r.json() found = [d for d in api_devs if d['identity_data'] == id_data] assert len(found) == 1 return found[0]
def get_authset_id(pubkey, utoken): devadmm = ApiClient(deviceadm.URL_MGMT) r = devadmm.with_auth(utoken).call('GET', deviceadm.URL_AUTHSETS) assert r.status_code == 200 api_devs = r.json() api_dev = [ x for x in api_devs if util.crypto.rsa_compare_keys(x['key'], pubkey) ][0] return api_dev['id']
def do_test_fail_duplicate(self, user, devices): useradmm = ApiClient(useradm.URL_MGMT) devauthm = ApiClient(deviceauth_v2.URL_MGMT) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # preauth duplicate device priv, pub = util.crypto.rsa_get_keypair() id_data = devices[0].id_data body = deviceauth_v2.preauth_req( id_data, pub) r = devauthm.with_auth(utoken).call('POST', deviceauth_v2.URL_DEVICES, body) assert r.status_code == 409 # device list is unmodified r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 200 api_devs = r.json() assert len(api_devs) == len(devices) # existing device has no new auth sets existing = [d for d in api_devs if d['identity_data'] == id_data] assert len(existing) == 1 existing = existing[0] assert len(existing['auth_sets']) == 1 aset = existing['auth_sets'][0] assert util.crypto.rsa_compare_keys(aset['pubkey'], devices[0].pubkey) assert aset['status'] == 'pending'
def do_test_device_count(self, devs_authsets, user): ua = ApiClient(useradm.URL_MGMT) da = ApiClient(deviceauth_v2.URL_MGMT) # log in user r = ua.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # test cases: successful counts for status in [None, \ 'pending', \ 'accepted', \ 'rejected', \ 'preauthorized']: qs_params={} if status is not None: qs_params={'status': status} r = da.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES_COUNT, qs_params=qs_params) assert r.status_code == 200 count = r.json() ref_devs = filter_and_page_devs(devs_authsets, status=status) ref_count = len(ref_devs) assert ref_count == count['count'] # fail: bad request r = da.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES_COUNT, qs_params={'status': 'foo'}) assert r.status_code == 400
def tenants_users_devices(tenants_users, mongo): devauthd = ApiClient(deviceauth.URL_DEVICES) devadmm = ApiClient(deviceadm.URL_MGMT) for t in tenants_users: for _ in range(2): priv, pub = deviceauth.get_keypair() mac = ":".join([ "{:02x}".format(random.randint(0x00, 0xFF), 'x') for i in range(6) ]) d = Device({'mac': mac}, pub, priv, t.tenant_token) body, sighdr = deviceauth.auth_req(d.id_data, d.pubkey, d.privkey, d.tenant_token) # submit auth req r = devauthd.call('POST', deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401 # get the authset id for future acceptance useradmm = ApiClient(useradm.URL_MGMT) r = useradmm.call('POST', useradm.URL_LOGIN, auth=(t.users[0].name, t.users[0].pwd)) assert r.status_code == 200 utoken = r.text r = devadmm.with_auth(utoken).call('GET', deviceadm.URL_AUTHSETS) assert r.status_code == 200 api_devs = r.json() api_dev = [ x for x in api_devs if compare_keys(x['key'], d.pubkey) ][0] d.authset_id = api_dev['id'] t.devices.append(d) yield tenants_users mongo_cleanup(mongo)
def verify_dev_after_status_update(self, dev, utoken): devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICE, path_params={'id': dev.id}) assert r.status_code == 200 api_dev = r.json() assert api_dev['status'] == dev.status assert len(api_dev['auth_sets']) == len(dev.authsets) for api_aset in api_dev['auth_sets']: aset = [a for a in dev.authsets if a.id == api_aset['id']] assert len(aset) == 1 aset = aset[0] compare_aset(aset, api_aset)
def do_test_ok_get_devices(self, devs_authsets, user): da = ApiClient(deviceauth_v2.URL_MGMT) ua = ApiClient(useradm.URL_MGMT) # log in user r = ua.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # test cases for status, page, per_page in [ (None, None, None), ('pending', None, None), ('accepted', None, None), ('rejected', None, None), ('preauthorized', None, None), (None, 1, 10), (None, 3, 10), (None, 2, 5), ('accepted', 1, 4), ('accepted', 2, 4), ('accepted', 5, 2), ('pending', 2, 2)]: qs_params = {} if status is not None: qs_params['status'] = status if page is not None: qs_params['page'] = page if per_page is not None: qs_params['per_page'] = per_page r = da.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES, qs_params=qs_params) assert r.status_code == 200 api_devs = r.json() ref_devs = filter_and_page_devs(devs_authsets, page=page, per_page=per_page, status=status) self._compare_devs(ref_devs, api_devs)
def test_accepted_dev_cant_authenticate(self, tenants_users_devices): dac = ApiClient(deviceadm.URL_MGMT) uc = ApiClient(useradm.URL_MGMT) devauth = ApiClient(deviceauth.URL_DEVICES) tc = ApiClient(tenantadm.URL_INTERNAL) # accept a dev device = tenants_users_devices[0].devices[0] user = tenants_users_devices[0].users[0] r = uc.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text dev = tenants_users_devices[0].devices[0] r = dac.with_auth(utoken).call( 'PUT', deviceadm.URL_AUTHSET_STATUS, deviceadm.req_status('accepted'), path_params={'id': get_authset_id(dev.pubkey, utoken)}) assert r.status_code == 200 # suspend r = tc.call('PUT', tenantadm.URL_INTERNAL_SUSPEND, tenantadm.req_status('suspended'), path_params={'tid': tenants_users_devices[0].id}) assert r.status_code == 200 time.sleep(10) # try requesting auth body, sighdr = deviceauth.auth_req(device.id_data, device.pubkey, device.privkey, device.tenant_token) r = devauth.call('POST', deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401 assert r.json()['error'] == 'Account suspended'
def make_preauthd_device(utoken): devauthm = ApiClient(deviceauth_v2.URL_MGMT) priv, pub = util.crypto.rsa_get_keypair() id_data = rand_id_data() body = deviceauth_v2.preauth_req(id_data, pub) r = devauthm.with_auth(utoken).call('POST', deviceauth_v2.URL_DEVICES, body) assert r.status_code == 201 api_dev = get_device_by_id_data(id_data, utoken) assert len(api_dev['auth_sets']) == 1 aset = api_dev['auth_sets'][0] dev = Device(api_dev['id'], id_data, pub) dev.authsets.append( Authset(aset['id'], dev.id, id_data, pub, priv, 'preauthorized')) dev.status = 'preauthorized' return dev
def do_test_ok(self, user, tenant_token=''): useradmm = ApiClient(useradm.URL_MGMT) devauthm = ApiClient(deviceauth_v2.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # preauth device priv, pub = util.crypto.rsa_get_keypair() id_data = {'mac': 'pretenditsamac'} body = deviceauth_v2.preauth_req( id_data, pub) r = devauthm.with_auth(utoken).call('POST', deviceauth_v2.URL_DEVICES, body) assert r.status_code == 201 # device appears in device list r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 200 api_devs = r.json() assert len(api_devs) == 1 api_dev = api_devs[0] assert api_dev['status'] == 'preauthorized' assert api_dev['identity_data'] == id_data assert len(api_dev['auth_sets']) == 1 aset = api_dev['auth_sets'][0] assert aset['identity_data'] == id_data assert util.crypto.rsa_compare_keys(aset['pubkey'], pub) assert aset['status'] == 'preauthorized' # actual device can obtain auth token body, sighdr = deviceauth_v1.auth_req(id_data, pub, priv, tenant_token) r = devauthd.call('POST', deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 # device and authset changed status to 'accepted' r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES, path_params={'id': api_dev['id']}) api_devs = r.json() assert len(api_devs) == 1 api_dev = api_devs[0] assert api_dev['status'] == 'accepted' assert len(api_dev['auth_sets']) == 1 aset = api_dev['auth_sets'][0] assert aset['status'] == 'accepted'
def do_test_put_status_reject(self, devs_authsets, user, tenant_token=''): devauthm = ApiClient(deviceauth_v2.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) useradmm = ApiClient(useradm.URL_MGMT) deploymentsd = ApiClient(deployments.URL_DEVICES) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text devs = [] for status in ['pending', 'accepted', 'preauthorized']: found = filter_and_page_devs(devs_authsets, status=status) devs.extend(found) for dev in devs: aset = None dtoken = None # for accepted or preauthd devs, reject the accepted/preauthd set # otherwise just select something if dev.status in ['accepted', 'preauthorized']: aset = [a for a in dev.authsets if a.status == dev.status] assert len(aset) == 1 aset = aset[0] else: aset = dev.authsets[0] # for accepted devs, also have an active device and check it loses api access if dev.status == 'accepted': body, sighdr = deviceauth_v1.auth_req(aset.id_data, aset.pubkey, aset.privkey, tenant_token) r = devauthd.call('POST', deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 dtoken = r.text # reject the authset change_authset_status(dev.id, aset.id, 'rejected', utoken) # the given authset always changes to 'rejected' aset.status='rejected' # if all other asets are also rejected, the device becomes too # otherwise it's 'pending' rej_asets = [a for a in dev.authsets if a.id != aset.id and a.status == 'rejected'] if len(rej_asets) == len(dev.authsets) - 1: dev.status = 'rejected' else: dev.status = 'pending' # check if the api device is consistent self.verify_dev_after_status_update(dev, utoken) # if we rejected an accepted, active device, check that it lost access if dtoken is not None: r = deploymentsd.with_auth(dtoken).call('GET', deployments.URL_NEXT, qs_params={'device_type': 'foo', 'artifact_name': 'bar'}) assert r.status_code == 401
def do_test_put_status_accept(self, devs_authsets, user, tenant_token=''): devauthm = ApiClient(deviceauth_v2.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) useradmm = ApiClient(useradm.URL_MGMT) deploymentsd = ApiClient(deployments.URL_DEVICES) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # select interesting devices - pending, rejected, or accepted/preauthd with extra authsets devs = [] for status in ['pending', 'rejected', 'accepted', 'preauthorized']: found = filter_and_page_devs(devs_authsets, status=status) if status == 'accepted' or status == 'preauthorized': found = [d for d in found if len(d.authsets) > 1] devs.extend(found) # test acceptance for various kinds of devs for dev in devs: # for accepted devs - first actually get a device token dtoken = None if dev.status == 'accepted': accepted = [a for a in dev.authsets if a.status == 'accepted'][0] body, sighdr = deviceauth_v1.auth_req(accepted.id_data, accepted.pubkey, accepted.privkey, tenant_token) r = devauthd.call('POST', deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 dtoken = r.text # find some pending or rejected authset aset = [a for a in dev.authsets if a.status == 'pending' or a.status == 'rejected'][0] # accept the authset change_authset_status(dev.id, aset.id, 'accepted', utoken) # in case of originally preauthd/accepted devs: the original authset must be rejected now if dev.status in ['accepted', 'preauthorized']: aset_to_reject = [a for a in dev.authsets if a.status == dev.status] assert len(aset_to_reject) == 1 aset_to_reject[0].status = 'rejected' # in all cases, device is now 'accepted', along with the just accepted authset dev.status = 'accepted' aset.status = 'accepted' # verify device is correct in the api self.verify_dev_after_status_update(dev, utoken) # if the device used to be accepted - check it lost access if dtoken is not None: r = deploymentsd.with_auth(dtoken).call('GET', deployments.URL_NEXT, qs_params={'device_type': 'foo', 'artifact_name': 'bar'}) assert r.status_code == 401 # device should also be provisioned in inventory time.sleep(1) self.verify_dev_provisioned(dev, utoken)
def test_limits_max_devices(self, tenants_devs_authsets): devauthi = ApiClient(deviceauth_v1.URL_INTERNAL) devauthm = ApiClient(deviceauth_v2.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) useradmm = ApiClient(useradm.URL_MGMT) for t in tenants_devs_authsets: # get num currently accepted devices num_acc = len(filter_and_page_devs(t.devices, status='accepted')) # set limit to that r = devauthi.call('PUT', deviceauth_v1.URL_LIMITS_MAX_DEVICES, {'limit': num_acc}, path_params={'tid': t.id}) assert r.status_code == 204 # get limit via internal api r = devauthi.call('GET', deviceauth_v1.URL_LIMITS_MAX_DEVICES, path_params={'tid': t.id}) assert r.status_code == 200 assert r.json()['limit'] == num_acc # get limit via mgmt api r = useradmm.call('POST', useradm.URL_LOGIN, auth=(t.users[0].name, t.users[0].pwd)) assert r.status_code == 200 utoken = r.text r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_LIMITS_MAX_DEVICES) assert r.status_code == 200 assert r.json()['limit'] == num_acc # try accept a device manually pending = filter_and_page_devs(t.devices, status='pending')[0] r = devauthm.with_auth(utoken).call('PUT', deviceauth_v2.URL_AUTHSET_STATUS, deviceauth_v2.req_status('accepted'), path_params={'did': pending.id, 'aid': pending.authsets[0].id }) assert r.status_code == 422 # try exceed the limit via preauth'd device preauthd = filter_and_page_devs(t.devices, status='preauthorized')[0] body, sighdr = deviceauth_v1.auth_req(preauthd.id_data, preauthd.authsets[0].pubkey, preauthd.authsets[0].privkey, t.tenant_token) r = devauthd.call('POST', deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401