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 test_authenticated_user_is_rejected(self, tenants): tc = ApiClient(tenantadm.URL_INTERNAL) uc = ApiClient(useradm.URL_MGMT) dc = ApiClient(deviceauth_v2.URL_MGMT) u = tenants[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[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 create_tenant_test_setup(user_name, tenant_name, nr_deployments=3, nr_devices=100): """ Creates a tenant, and a user belonging to the tenant belonging to the user with 'nr_deployments', and 'nr_devices' """ api_mgmt_deploy = ApiClient(deployments.URL_MGMT) tenant = create_tenant(tenant_name) user = create_tenant_user(user_name, tenant) r = ApiClient(useradm.URL_MGMT).call( 'POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 user.utoken = r.text tenant.users = [user] upload_image("/tests/test-artifact.mender", user.utoken) # Create three deployments for the user for i in range(nr_deployments): request_body = { "name": str(i) + "st-dummy-deployment", "artifact_name": "deployments-phase-testing", "devices": ["uuid not needed" + str(i) for i in range(nr_devices)], } resp = api_mgmt_deploy.with_auth(user.utoken).call( 'POST', '/deployments', body=request_body, ) assert resp.status_code == 201 # Verify that the 'nr_deployments' expected deployments have been created resp = api_mgmt_deploy.with_auth(user.utoken).call('GET', '/deployments') assert resp.status_code == 200 assert len(resp.json()) == nr_deployments return tenant
def try_update(device, expected_status_code=200, artifact_name="bugs-bunny"): """ Try to make an update with a device :param devices: list of devices :param expected_status_code: expected status code :param artifact_name: artifact name used in the request """ api_dev_deploy = ApiClient(deployments.URL_DEVICES) # Try to retrieve next update and assert expected status code resp = api_dev_deploy.with_auth(device.token).call( 'GET', deployments.URL_NEXT, qs_params={"artifact_name": artifact_name, "device_type" : "qemux86-64"} ) assert resp.status_code == expected_status_code if resp.status_code == 200: # Update device status upon successful request api_dev_deploy.with_auth(device.token).call( "PUT", deployments.URL_STATUS.format(id=resp.json()["id"]), body={"status": "success"} )
def _test_args_object(self, tenant_users, events): alogs = ApiClient(auditlogs.URL_MGMT) expected = events[0] # id filter resp = alogs.with_auth(tenant_users.users[0].token).call( "GET", auditlogs.URL_LOGS + "?object_id=" + expected["object"]["id"]) resp = resp.json() assert len(resp) == 1 for i in range(len(resp)): check_log(resp[0], expected) # type filter for obj_type in ["deployment"]: expected = [e for e in events if e["object"]["type"] == obj_type] resp = alogs.with_auth(tenant_users.users[0].token).call( "GET", auditlogs.URL_LOGS + "?object_type=" + obj_type) resp = resp.json() assert len(resp) == len(expected) for i in range(len(resp)): check_log(resp[i], expected[i])
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 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_args_actor(self, tenant_users, events): alogs = ApiClient(auditlogs.URL_MGMT) ids = [user.id for user in tenant_users.users] emails = [user.name for user in tenant_users.users] for id in ids: expected = [e for e in events if e["actor"]["id"] == id] resp = alogs.with_auth(tenant_users.users[0].token).call( "GET", auditlogs.URL_LOGS + "?actor_id=" + id) assert resp.status_code == 200 resp = resp.json() assert len(resp) == len(expected) for i in range(len(resp)): check_log(resp[i], expected[i]) for email in emails: expected = [e for e in events if e["actor"]["email"] == email] resp = alogs.with_auth(tenant_users.users[0].token).call( "GET", auditlogs.URL_LOGS + "?actor_email=" + urllib.parse.quote(email)) assert resp.status_code == 200 resp = resp.json() assert len(resp) == len(expected) for i in range(len(resp)): check_log(resp[i], expected[i])
def test_authenticated_user_is_rejected(self, tenants): tc = ApiClient(tenantadm.URL_INTERNAL, host=tenantadm.HOST, schema="http://") uc = ApiClient(useradm.URL_MGMT) dc = ApiClient(deviceauth.URL_MGMT) u = tenants[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.URL_MGMT_DEVICES) assert r.status_code == 200 # suspend tenant r = tc.call( "PUT", tenantadm.URL_INTERNAL_SUSPEND, tenantadm.req_status("suspended"), path_params={"tid": tenants[0].id}, ) assert r.status_code == 200 time.sleep(10) # check token is rejected r = dc.with_auth(token).call("GET", deviceauth.URL_MGMT_DEVICES) assert r.status_code == 401
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 = testutils.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 testutils.util.crypto.rsa_compare_keys(aset["pubkey"], devices[0].pubkey) assert aset["status"] == "pending"
def try_update(device, default_artifact_name="bugs-bunny", default_device_type="qemux86-64"): """ Try to make an update with a device :param devices: list of devices :param expected_status_code: expected status code :param default_artifact_name: default artifact name of the artifact used in the request NOTE: You can override the device type and artifact name by creating a device_type/artifact_name member of the Device object. """ api_dev_deploy = ApiClient(deployments.URL_DEVICES) # Try to retrieve next update and assert expected status code resp = api_dev_deploy.with_auth(device.token).call( 'GET', deployments.URL_NEXT, qs_params={"artifact_name": getattr( device, "artifact_name", default_artifact_name), "device_type": getattr( device, "device_type", default_device_type)} ) if resp.status_code == 200: # Update device status upon successful request api_dev_deploy.with_auth(device.token).call( "PUT", deployments.URL_STATUS.format(id=resp.json()["id"]), body={"status": "success"} ) return resp.status_code
def test_regular_deployment(self, clean_mongo): user, tenant, utoken, devs = setup_devices_and_management() api_mgmt_dep = ApiClient(deployments.URL_MGMT) # Make deployment request deployment_req = { "name": "phased-deployment", "artifact_name": "deployments-phase-testing", "devices": [dev.id for dev in devs], } api_mgmt_dep.with_auth(utoken).call("POST", deployments.URL_DEPLOYMENTS, deployment_req) for dev in devs: status_code = try_update(dev) assert status_code == 200 dev.artifact_name = deployment_req["artifact_name"] for dev in devs: # Deployment already finished status_code = try_update(dev) assert status_code == 204 deployment_req["name"] = "really-old-update" api_mgmt_dep.with_auth(utoken).call("POST", deployments.URL_DEPLOYMENTS, deployment_req) for dev in devs: # Already installed status_code = try_update(dev) assert status_code == 204
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 test_deploy_to_group(self, clean_mongo, test_case): """ Tests adding group restrinction to roles and checking that users are not allowed to deploy to devices outside the restricted groups. """ dplmnt_MGMT = ApiClient(deployments.URL_MGMT) i = 0 self.logger.info("RUN: %s", test_case["name"]) tenant = create_org("org%d" % i, "*****@*****.**" % i, "password", plan="enterprise") test_user = create_user(tid=tenant.id, **test_case["user"]) tenant.users.append(test_user) login_tenant_users(tenant) # Initialize tenant's devices grouped_devices = setup_tenant_devices(tenant, test_case["device_groups"]) # Add user to deployment group role = UserRole("RBAC_DEVGRP", test_case["permissions"]) add_user_to_role(test_user, tenant, role) # Upload a bogus artifact artifact = Artifact("tester", ["qemux86-64"], payload="bogus") rsp = dplmnt_MGMT.with_auth(test_user.token).call( "POST", deployments.URL_DEPLOYMENTS_ARTIFACTS, files=(( "artifact", ( "artifact.mender", artifact.make(), "application/octet-stream", ), ), ), ) assert rsp.status_code == 201, rsp.text # Attempt to create deployment with test user devices = [] for group in test_case["deploy_groups"]: for device in grouped_devices[group]: devices.append(device.id) rsp = dplmnt_MGMT.with_auth(test_user.token).call( "POST", deployments.URL_DEPLOYMENTS, body={ "artifact_name": "tester", "name": "dplmnt", "devices": devices }, ) assert rsp.status_code == test_case["status_code"], rsp.text self.logger.info("PASS: %s" % test_case["name"])
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_deploy_to_devices(self, clean_mongo, test_case): """ Tests adding group restrinction to roles and checking that users are not allowed to deploy to devices by providing list of device IDs. The only exception is single device deployment. """ self.logger.info("RUN: %s", test_case["name"]) uuidv4 = str(uuid.uuid4()) tenant, username, password = ( "test.mender.io-" + uuidv4, "some.user+" + uuidv4 + "@example.com", "secretsecret", ) tenant = create_org(tenant, username, password, "enterprise") test_case["user"]["name"] = test_case["user"]["name"].replace("UUID", uuidv4) test_user = create_user(tid=tenant.id, **test_case["user"]) tenant.users.append(test_user) login_tenant_users(tenant) # Initialize tenant's devices grouped_devices = setup_tenant_devices(tenant, test_case["device_groups"]) # Add user to deployment group role = UserRole("RBAC_DEVGRP", test_case["permissions"]) add_user_to_role(test_user, tenant, role) # Upload a bogus artifact artifact = Artifact("tester", ["qemux86-64"], payload="bogus") dplmnt_MGMT = ApiClient(deployments.URL_MGMT) rsp = dplmnt_MGMT.with_auth(test_user.token).call( "POST", deployments.URL_DEPLOYMENTS_ARTIFACTS, files=( ( "artifact", ("artifact.mender", artifact.make(), "application/octet-stream"), ), ), ) assert rsp.status_code == 201, rsp.text # Attempt to create deployment with test user devices = [] for group in test_case["deploy_groups"]: for device in grouped_devices[group]: devices.append(device.id) rsp = dplmnt_MGMT.with_auth(test_user.token).call( "POST", deployments.URL_DEPLOYMENTS, body={"artifact_name": "tester", "name": "dplmnt", "devices": devices}, ) assert rsp.status_code == test_case["status_code"], rsp.text self.logger.info("PASS: %s" % test_case["name"])
def setup_upload_artifact_selection(self, plan, artifacts=()): tenant, username, password = self.get_tenant_username_and_password( plan=plan) auth_token = self.get_auth_token(username, password) api_client = ApiClient(deployments.URL_MGMT) api_client.headers = {} # avoid default Content-Type: application/json api_client.with_auth(auth_token) # create and upload the mender artifact for artifact_kw in artifacts: artifact_kw.setdefault("artifact_name", "test") artifact_kw.setdefault("device_types", ["arm1"]) with get_mender_artifact(**artifact_kw) as artifact: r = api_client.with_auth(auth_token).call( "POST", deployments.URL_DEPLOYMENTS_ARTIFACTS, files=( ("description", (None, "description")), ("size", (None, str(os.path.getsize(artifact)))), ( "artifact", ( artifact, open(artifact, "rb"), "application/octet-stream", ), ), ), ) assert r.status_code == 201 # create a new accepted device devauthd = ApiClient(deviceauth.URL_DEVICES) devauthm = ApiClient(deviceauth.URL_MGMT) dev = make_accepted_device( devauthd, devauthm, auth_token, tenant.tenant_token if tenant is not None else "", ) assert dev is not None # create a deployment resp = api_client.with_auth(auth_token).call( "POST", deployments.URL_DEPLOYMENTS, body={ "name": "deployment-1", "artifact_name": "test", "devices": [dev.id], }, ) assert resp.status_code == 201 return dev
def test_set_and_deploy_configuration(self, clean_mongo, test_case): """ Tests adding group restrinction to roles and checking that users are not allowed to set and deploy configuration to devices outside the restricted groups. """ self.logger.info("RUN: %s", test_case["name"]) uuidv4 = str(uuid.uuid4()) tenant, username, password = ( "test.mender.io-" + uuidv4, "some.user+" + uuidv4 + "@example.com", "secretsecret", ) tenant = create_org(tenant, username, password, "enterprise") update_tenant(tenant.id, addons=["configure"]) test_case["user"]["name"] = test_case["user"]["name"].replace( "UUID", uuidv4) test_user = create_user(tid=tenant.id, **test_case["user"]) tenant.users.append(test_user) login_tenant_users(tenant) # Initialize tenant's devices grouped_devices = setup_tenant_devices(tenant, test_case["device_groups"]) # Add user to deployment group role = UserRole("RBAC_DEVGRP", test_case["permissions"]) add_user_to_role(test_user, tenant, role) deviceconf_MGMT = ApiClient(deviceconfig.URL_MGMT) device_id = grouped_devices[test_case["deploy_group"]][0].id # Attempt to set configuration rsp = deviceconf_MGMT.with_auth(test_user.token).call( "PUT", deviceconfig.URL_MGMT_DEVICE_CONFIGURATION.format(id=device_id), body={"foo": "bar"}, ) assert rsp.status_code == test_case[ "set_configuration_status_code"], rsp.text # Attempt to deploy the configuration rsp = deviceconf_MGMT.with_auth(test_user.token).call( "POST", deviceconfig.URL_MGMT_DEVICE_CONFIGURATION_DEPLOY.format( id=device_id), body={"retries": 0}, ) assert (rsp.status_code == test_case["deploy_configuration_status_code"]), rsp.text self.logger.info("PASS: %s" % test_case["name"])
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 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 setup_devices_and_management(nr_devices=100): """ Sets up user and tenant and creates authorized devices. """ tenant = create_tenant('acme') user = create_tenant_user('bugs-bunny', tenant) useradmm = ApiClient(useradm.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) invm = ApiClient(inventory.URL_MGMT) api_mgmt_deploy = ApiClient(deployments.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 # Upload a dummy artifact to the server upload_image("/tests/test-artifact.mender", utoken) # prepare accepted devices devs = make_accepted_devices(utoken, devauthd, nr_devices, tenant.tenant_token) # wait for devices to be provisioned time.sleep(3) # Check that the number of devices were created r = invm.with_auth(utoken).call( 'GET', inventory.URL_DEVICES, qs_params={ 'per_page': nr_devices }) assert r.status_code == 200 api_devs = r.json() assert len(api_devs) == nr_devices return user, tenant, utoken, devs
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 make_device_with_inventory(attributes, utoken, tenant_token): devauthm = ApiClient(deviceauth.URL_MGMT) devauthd = ApiClient(deviceauth.URL_DEVICES) invm = ApiClient(inventory.URL_MGMT) d = make_accepted_device(devauthd, devauthm, utoken, tenant_token) """ verify that the status of the device in inventory is "accepted" """ accepted = False timeout = 10 for i in range(timeout): r = invm.with_auth(utoken).call("GET", inventory.URL_DEVICE.format(id=d.id)) if r.status_code == 200: dj = r.json() for attr in dj["attributes"]: if attr["name"] == "status" and attr["value"] == "accepted": accepted = True break if accepted: break time.sleep(1) if not accepted: raise ValueError( "status for device %s has not been propagated within %d seconds" % (d.id, timeout)) submit_inventory(attributes, d.token) d.attributes = attributes return d
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 test_upload_artifact_selection_match_depends_multiple_artifacts( self, mongo, clean_mongo): dev = self.setup_upload_artifact_selection( plan="enterprise", artifacts=( { "artifact_name": "test", "device_types": ["arm1"], "depends": ("rootfs_image_checksum:checksum", ), "provides": ("rootfs_image_checksum:provided", ), }, { "artifact_name": "test", "device_types": ["arm1"], "depends": ("rootfs_image_checksum:another-checksum", ), "provides": ("rootfs_image_checksum:provided", ), }, ), ) deploymentsd = ApiClient(deployments.URL_DEVICES) r = deploymentsd.with_auth(dev.token).call( "POST", deployments.URL_NEXT, body={ "device_type": "arm1", "artifact_name": "old-artifact", "rootfs_image_checksum": "another-checksum", }, ) assert r.status_code == 200
def create_org(name, username, password, plan="os"): cli = CliTenantadm() user_id = None tenant_id = cli.create_org(name, username, password, plan=plan) tenant_token = json.loads(cli.get_tenant(tenant_id))["tenant_token"] api = ApiClient(useradm.URL_MGMT) # Try log in every second for 3 minutes. # - There usually is a slight delay (in order of ms) for propagating # the created user to the db. for i in range(3 * 60): rsp = api.call("POST", useradm.URL_LOGIN, auth=(username, password)) if rsp.status_code == 200: break time.sleep(1) if rsp.status_code != 200: raise ValueError( "User could not log in within three minutes after organization has been created." ) user_token = rsp.text rsp = api.with_auth(user_token).call("GET", useradm.URL_USERS) users = json.loads(rsp.text) for user in users: if user["email"] == username: user_id = user["id"] break if user_id == None: raise ValueError("Error retrieving user id.") tenant = Tenant(name, tenant_id, tenant_token) user = User(user_id, username, password) tenant.users.append(user) return tenant
def test_reporting_search(self, user_reporting, test_case): reporting_client = ApiClient(reporting.URL_MGMT) rsp = reporting_client.with_auth(user_reporting.api_token).call( "POST", reporting.URL_MGMT_DEVICES_SEARCH, test_case["request"] ) assert rsp.status_code == test_case["status_code"], ( "Unexpected status code (%d) from /devices/search response: %s" % (rsp.status_code, rsp.text) ) if rsp.status_code == 200 and "response" in test_case: body = rsp.json() if body is None: body = [] test_case_response = test_case["response"](user_reporting) self.logger.info("expected: %r", test_case_response) self.logger.info("received: %r", body) assert len(body) == len(test_case_response), ( "Unexpected number of results: %s != %s" % ( [dev["id"] for dev in test_case_response], [dev["id"] for dev in body], ) ) if len(test_case_response) > 0: if "sort" not in test_case["request"]: body = sorted(body, key=lambda dev: dev["id"]) test_case_response = sorted( test_case_response, key=lambda dev: dev["id"] ) for i, dev in enumerate(test_case_response): assert dev["id"] == body[i]["id"], "Unexpected device in response" assert_device_attributes(dev, body[i])
def add_devices_to_user(user, dev_inventories): try: user.devices except AttributeError: user.devices = [] useradmm = ApiClient(useradm.URL_MGMT) devauthd = ApiClient(deviceauth.URL_DEVICES) devauthm = ApiClient(deviceauth.URL_MGMT) invd = ApiClient(inventory.URL_DEV) utoken = useradmm.call("POST", useradm.URL_LOGIN, auth=(user.name, user.pwd)).text assert utoken != "" user.api_token = utoken for inv in dev_inventories: device = make_accepted_device(devauthd, devauthm, utoken) user.devices.append(device) attrs = dict_to_inventoryattrs(inv) rsp = invd.with_auth(device.token).call( "PATCH", inventory.URL_DEVICE_ATTRIBUTES, body=attrs ) assert rsp.status_code == 200 device.inventory = inv return user