def create_authset(dauthd1, dauthm, id_data, pubkey, privkey, utoken, tenant_token=''): body, sighdr = deviceauth_v1.auth_req(id_data, pubkey, privkey, tenant_token) # submit auth req r = dauthd1.call('POST', deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401, r.text # dev must exist and have *this* aset api_dev = get_device_by_id_data(dauthm, id_data, utoken) assert api_dev is not None aset = [ a for a in api_dev['auth_sets'] if testutils.util.crypto.rsa_compare_keys(a['pubkey'], pubkey) ] assert len(aset) == 1, str(aset) aset = aset[0] assert aset['identity_data'] == id_data assert aset['status'] == 'pending' return Authset(aset['id'], api_dev['id'], id_data, pubkey, privkey, 'pending')
def initialize_os_setup(env): """ Seed the OS setup with all operational data - users and devices. Return {"os_devs": [...], "os_users": [...]} """ uadmm = ApiClient(useradm.URL_MGMT, host=env.get_mender_gateway()) dauthd = ApiClient(deviceauth.URL_DEVICES, host=env.get_mender_gateway()) dauthm = ApiClient(deviceauth.URL_MGMT, host=env.get_mender_gateway()) users = [ create_user("*****@*****.**", "correcthorse", containers_namespace=env.name), create_user("*****@*****.**", "correcthorse", containers_namespace=env.name), ] r = uadmm.call("POST", useradm.URL_LOGIN, auth=(users[0].name, users[0].pwd)) assert r.status_code == 200 utoken = r.text # create and accept some devs; save tokens devs = [] for _ in range(10): devs.append(make_accepted_device(dauthd, dauthm, utoken)) # get tokens for all for d in devs: body, sighdr = deviceauth.auth_req( d.id_data, d.authsets[0].pubkey, d.authsets[0].privkey ) r = dauthd.call("POST", deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 d.token = r.text return {"os_devs": devs, "os_users": users}
def create_authset(dauthd1, dauthm, id_data, pubkey, privkey, utoken, tenant_token=""): body, sighdr = deviceauth.auth_req(id_data, pubkey, privkey, tenant_token) # submit auth req r = dauthd1.call("POST", deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401, r.text # dev must exist and have *this* aset api_dev = get_device_by_id_data(dauthm, id_data, utoken) assert api_dev is not None aset = [ a for a in api_dev["auth_sets"] if testutils.util.crypto.compare_keys(a["pubkey"], pubkey) ] assert len(aset) == 1, str(aset) aset = aset[0] assert aset["identity_data"] == id_data assert aset["status"] == "pending" return Authset(aset["id"], api_dev["id"], id_data, pubkey, privkey, "pending")
def test_ok(self, tenants_and_accepted_devs): """ Basic JWT inspection: are we getting the right claims? """ for t in tenants_and_accepted_devs: dev = t.devices[0] aset = dev.authsets[0] body, sighdr = deviceauth_v1.auth_req(aset.id_data, aset.pubkey, aset.privkey, t.tenant_token) r = dauthd.call("POST", deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 token = r.text payload = token.split(".")[1] payload = base64.b64decode(payload + "==") payload = json.loads(payload.decode("utf-8")) # standard claims assert payload["sub"] == dev.id assert payload["iss"] == "Mender" assert payload["jti"] is not None assert payload["exp"] is not None # custom claims assert payload["mender.plan"] == t.plan assert payload["mender.tenant"] == t.id assert payload["mender.device"]
def make_accepted_device( dauthd1: ApiClient, dauthm: ApiClient, utoken: str, tenant_token: str = "", test_type: str = "regular", ) -> Device: """Create one device with "accepted" status.""" test_types = ["regular", "azure"] if test_type not in test_types: raise RuntimeError("Given test type is not allowed") dev = make_pending_device(dauthd1, dauthm, utoken, tenant_token=tenant_token) aset_id = dev.authsets[0].id change_authset_status(dauthm, dev.id, aset_id, "accepted", utoken) aset = dev.authsets[0] aset.status = "accepted" # TODO: very bad workaround for Azure IoT Hub backend test; following part is responsible for creating # TODO: additonal, unnecessary auth set which causes Azure test to fail if test_type == "regular": # obtain auth token body, sighdr = deviceauth.auth_req( aset.id_data, aset.pubkey, aset.privkey, tenant_token ) r = dauthd1.call("POST", deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 dev.token = r.text dev.status = "accepted" return dev
def test_accepted_dev_cant_authenticate(self, tenants_users_devices): dacd = ApiClient(deviceauth.URL_DEVICES) devauthm = ApiClient(deviceauth_v2.URL_MGMT) uc = ApiClient(useradm.URL_MGMT) 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 aset = device.authsets[0] change_authset_status(devauthm, aset.did, aset.id, 'accepted', utoken) # 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( aset.id_data, aset.pubkey, aset.privkey, tenants_users_devices[0].tenant_token) r = dacd.call('POST', deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401 assert r.json()['error'] == 'Account suspended'
def make_accepted_device(utoken, devauthd, tenant_token=''): devauthm = ApiClient(deviceauth_v2.URL_MGMT) dev = make_pending_device(utoken, tenant_token=tenant_token) aset_id = dev.authsets[0].id change_authset_status(devauthm, dev.id, aset_id, 'accepted', utoken) aset = dev.authsets[0] aset.status = 'accepted' # obtain auth token 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 dev.token = r.text dev.status = 'accepted' return dev
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 test_devs_ok(self, migrated_enterprise_setup): mender_gateway = migrated_enterprise_setup.get_mender_gateway() uadmm = ApiClient( "https://{}/api/management/v1/useradm".format(mender_gateway)) dauthd = ApiClient( "https://{}/api/devices/v1/authentication".format(mender_gateway)) dauthm = ApiClient( "https://{}/api/management/v2/devauth".format(mender_gateway)) depld = ApiClient( "https://{}/api/devices/v1/deployments".format(mender_gateway)) # current dev tokens don't work right off the bat # the deviceauth db is empty for d in migrated_enterprise_setup.init_data["os_devs"]: resp = depld.with_auth(d.token).call( "GET", deployments.URL_NEXT, qs_params={ "artifact_name": "foo", "device_type": "bar" }, ) assert resp.status_code == 401 # but even despite the 'dummy' tenant token # os devices can get into the deviceauth db for acceptance ent_user = migrated_enterprise_setup.init_data["tenant"].users[0] r = uadmm.call("POST", useradm.URL_LOGIN, auth=(ent_user.name, ent_user.pwd)) assert r.status_code == 200 utoken = r.text for d in migrated_enterprise_setup.init_data["os_devs"]: body, sighdr = deviceauth_v1.auth_req( d.id_data, d.authsets[0].pubkey, d.authsets[0].privkey, tenant_token="dummy", ) r = dauthd.call("POST", deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401 r = dauthm.with_auth(utoken).call("GET", deviceauth_v2.URL_DEVICES, path_params={"id": d.id}) assert r.status_code == 200 assert len(r.json()) == len( migrated_enterprise_setup.init_data["os_devs"])
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 = testutils.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 testutils.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 test_authenticated_dev_is_rejected(self, tenants_users_devices): dacd = ApiClient(deviceauth.URL_DEVICES) devauthm = ApiClient(deviceauth_v2.URL_MGMT) uc = ApiClient(useradm.URL_MGMT) tc = ApiClient(tenantadm.URL_INTERNAL) dc = ApiClient(deployments.URL_DEVICES) # accept a dev 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 aset = tenants_users_devices[0].devices[0].authsets[0] change_authset_status(devauthm, aset.did, aset.id, 'accepted', utoken) # request auth body, sighdr = deviceauth.auth_req(aset.id_data, aset.pubkey, aset.privkey, tenants_users_devices[0].tenant_token) r = dacd.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 initialize_os_setup(): """ Seed the OS setup with all operational data - users and devices. Return {"os_devs": [...], "os_users": [...]} """ uadmm = ApiClient('https://{}/api/management/v1/useradm'.format( get_mender_gateway())) dauthd = ApiClient('https://{}/api/devices/v1/authentication'.format( get_mender_gateway())) dauthm = ApiClient('https://{}/api/management/v2/devauth'.format( get_mender_gateway())) users = [ create_user("*****@*****.**", "correcthorse", docker_prefix=docker_compose_instance), create_user("*****@*****.**", "correcthorse", docker_prefix=docker_compose_instance) ] r = uadmm.call('POST', useradm.URL_LOGIN, auth=(users[0].name, users[0].pwd)) assert r.status_code == 200 utoken = r.text # create and accept some devs; save tokens devs = [] for i in range(10): devs.append(make_accepted_device(dauthd, dauthm, utoken)) # get tokens for all for d in devs: body, sighdr = deviceauth_v1.auth_req(d.id_data, d.authsets[0].pubkey, d.authsets[0].privkey) r = dauthd.call('POST', deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 d.token = r.text return {"os_devs": devs, "os_users": users}
def test_accepted_dev_cant_authenticate(self, tenants_users_devices): dacd = ApiClient(deviceauth.URL_DEVICES) devauthm = ApiClient(deviceauth.URL_MGMT) uc = ApiClient(useradm.URL_MGMT) tc = ApiClient(tenantadm.URL_INTERNAL, host=tenantadm.HOST, schema="http://") # 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 aset = device.authsets[0] change_authset_status(devauthm, aset.did, aset.id, "accepted", utoken) # 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( aset.id_data, aset.pubkey, aset.privkey, tenants_users_devices[0].tenant_token, ) r = dacd.call("POST", deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401 assert r.json()["error"] == "Account suspended"
def make_accepted_device(dauthd1, dauthm, utoken, tenant_token=""): dev = make_pending_device(dauthd1, dauthm, utoken, tenant_token=tenant_token) aset_id = dev.authsets[0].id change_authset_status(dauthm, dev.id, aset_id, "accepted", utoken) aset = dev.authsets[0] aset.status = "accepted" # obtain auth token body, sighdr = deviceauth_v1.auth_req( aset.id_data, aset.pubkey, aset.privkey, tenant_token ) r = dauthd1.call("POST", deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 dev.token = r.text dev.status = "accepted" return dev
def do_test_ok(self, user, device, tenant_token=None): devauthd = ApiClient(deviceauth.URL_DEVICES) devauthm = ApiClient(deviceauth_v2.URL_MGMT) useradmm = ApiClient(useradm.URL_MGMT) deploymentsd = ApiClient(deployments.URL_DEVICES) inventoryd = ApiClient(inventory.URL_DEV) inventorym = ApiClient(inventory.URL_MGMT) r = useradmm.call("POST", useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text aset = device.authsets[0] change_authset_status(devauthm, aset.did, aset.id, "accepted", utoken) # request auth body, sighdr = deviceauth.auth_req(aset.id_data, aset.pubkey, aset.privkey, tenant_token) r = devauthd.call("POST", deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 200 dtoken = r.text # wait for the device provisioning workflow to do its job timeout = time.time() + 60 while time.time() < timeout: r = inventorym.with_auth(utoken).call("GET", inventory.URL_DEVICE, path_params={"id": aset.did}) if r.status_code == 200: break else: logger.debug( "waiting for the device to be added to inventory...") time.sleep(1) else: assert False, "device not added to the inventory" # check if the device can access API by patching device inventory payload = [{"name": "mac", "value": "foo"}] r = inventoryd.with_auth(dtoken).call("PATCH", inventory.URL_DEVICE_ATTRIBUTES, payload) assert r.status_code == 200 # decommission r = devauthm.with_auth(utoken).call( "DELETE", deviceauth_v2.URL_DEVICE.format(id=aset.did)) # check device is rejected r = deploymentsd.with_auth(dtoken).call( "GET", deployments.URL_NEXT, qs_params={ "device_type": "foo", "artifact_name": "bar" }, ) assert r.status_code == 401 # check device gone from inventory # this may take some time because it's done as an async job (workflow) timeout = time.time() + (60 * 3) while time.time() < timeout: r = inventorym.with_auth(utoken).call("GET", inventory.URL_DEVICE, path_params={"id": aset.did}) if r.status_code == 404: break else: logger.debug( "waiting for the device to be removed from inventory...") time.sleep(1) else: assert False, "device not removed from the inventory" # check device gone from deviceauth timeout = time.time() + 60 while time.time() < timeout: r = devauthm.with_auth(utoken).call( "GET", deviceauth_v2.URL_DEVICE.format(id=aset.did)) if r.status_code == 404: break else: logger.debug( "waiting for the device to be removed from deviceauth...") time.sleep(1) else: assert False, "device not removed from the deviceauth"
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(devauthm, 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(devauthm, 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
def test_authenticated_dev_is_rejected(self, tenants_users_devices): dacd = ApiClient(deviceauth.URL_DEVICES) devauthm = ApiClient(deviceauth.URL_MGMT) uc = ApiClient(useradm.URL_MGMT) tc = ApiClient(tenantadm.URL_INTERNAL, host=tenantadm.HOST, schema="http://") dc = ApiClient(deployments.URL_DEVICES) # accept a dev 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 aset = tenants_users_devices[0].devices[0].authsets[0] change_authset_status(devauthm, aset.did, aset.id, "accepted", utoken) # request auth body, sighdr = deviceauth.auth_req( aset.id_data, aset.pubkey, aset.privkey, tenants_users_devices[0].tenant_token, ) r = dacd.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 do_test_delete_status(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 for dev in devs_authsets: 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 # delete authset r = devauthm.with_auth(utoken).call( "DELETE", deviceauth_v2.URL_AUTHSET, path_params={"did": dev.id, "aid": aset.id}, ) assert r.status_code == 204 # authset should be gone dev.authsets.remove(aset) # removing preauth authset - the device should be completely gone if dev.status == "preauthorized": r = devauthm.with_auth(utoken).call( "GET", deviceauth_v2.URL_DEVICE, path_params={"id": dev.id} ) assert r.status_code == 404 return else: # in other cases the device remains dev.status = self.compute_dev_status(dev.authsets) # check api dev is consistent self.verify_dev_after_status_update(dev, utoken) # verify the device lost access, if we had one 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