def test_set_password(self, api_client_mgmt, cli, clean_db): password = '******' new_password = '******' email = '*****@*****.**' tenant = 'tenant1id' users_db = {tenant: [email]} cli.create_user(email, password, tenant_id=tenant) with tenantadm.run_fake_user_tenants(users_db): _, r = api_client_mgmt.login(email, password) assert r.status_code == 200 cli.set_password(email, new_password, tenant) status_code = 200 try: _, r = api_client_mgmt.login(email, password) except bravado.exception.HTTPError as e: assert e.response.status_code == 401 status_code = 401 assert status_code == 401 _, r = api_client_mgmt.login(email, new_password) assert r.status_code == 200 token = r.text assert token _, claims, _ = explode_jwt(token) assert claims['mender.tenant'] == tenant
def test_set_password(self, api_client_mgmt, cli, clean_db): user = { "password": "******", "new_password": "******", "email": "*****@*****.**", "tenant": TENANT_ONE, } users_db = {user["tenant"]: [user["email"]]} with tenantadm.run_fake_create_user(user): cli.create_user(user["email"], user["password"], tenant_id=user["tenant"]) with tenantadm.run_fake_user_tenants(users_db): _, r = api_client_mgmt.login(user["email"], user["password"]) assert r.status_code == 200 cli.set_password(user["email"], user["new_password"], user["tenant"]) status_code = 200 try: _, r = api_client_mgmt.login(user["email"], user["password"]) except bravado.exception.HTTPError as e: assert e.response.status_code == 401 status_code = 401 assert status_code == 401 _, r = api_client_mgmt.login(user["email"], user["new_password"]) assert r.status_code == 200 token = r.text assert token _, claims, _ = explode_jwt(token) assert claims["mender.tenant"] == user["tenant"]
def test_ok(self, api_client_mgmt, init_users): email = "*****@*****.**" password = "******" _, r = api_client_mgmt.login(email, password) assert r.status_code == 200 token = r.text assert len(token) _, claims, _ = explode_jwt(token) assert 'mender.user' in claims and claims['mender.user'] == True
def verify_tokens(api_client_int, tokens, removed_tenant=None, removed_user=None): for t in tokens: if removed_tenant is None: verify_token(api_client_int, t, 200) else: _, claims, _ = explode_jwt(t) tenant = claims['mender.tenant'] user = claims['sub'] if (removed_user is None or user == removed_user) and tenant == removed_tenant: verify_token(api_client_int, t, 401) else: verify_token(api_client_int, t, 200)
def test_tamper_claims(self, api_client_int, init_users, user_tokens): for user, token in zip(init_users, user_tokens): hdr, claims, sign = explode_jwt(token) claims['mender.tenant'] = 'foobar' tampered = '.'.join([urlsafe_b64encode(json.dumps(hdr).encode()).decode(), urlsafe_b64encode(json.dumps(claims).encode()).decode(), urlsafe_b64encode(sign).decode()]) try: _, r = api_client_int.verify(tampered) except bravado.exception.HTTPError as herr: assert herr.response.status_code == 401
def test_delete_by_non_existent_user_ok(self, api_client_int, user_tokens_mt_f): tokens = user_tokens_mt_f for t in tokens: verify_token(api_client_int, t, 200) _, claims, _ = explode_jwt(user_tokens_mt_f[0]) tenant = claims['mender.tenant'] payload = {'user_id': 'foo', 'tenant_id': tenant} rsp = requests.delete(api_client_int.make_api_url("/tokens"), params=payload) assert rsp.status_code == 204 verify_tokens(api_client_int, tokens)
def test_ok(self, api_client_mgmt, init_users_mt): password = "******" users_db = { tenant: [user.email for user in users] \ for tenant, users in init_users_mt.items() } with tenantadm.run_fake_user_tenants(users_db): for tenant, users in users_db.items(): for email in users: _, r = api_client_mgmt.login(email, password) assert r.status_code == 200 assert r.headers['Content-Type'] == "application/jwt" _, claims, _ = explode_jwt(r.text) assert claims['mender.tenant'] == tenant
def test_token_delete(self, device_token, token_verify_url, management_api): _, tclaims, _ = explode_jwt(device_token) # bravado cannot handle DELETE requests either # self.client.tokens.delete_tokens_id(id=tclaims['jti']) # use requests instead rsp = requests.delete(management_api.make_api_url('/tokens/{}'.format(tclaims['jti']))) assert rsp.status_code == 204 auth_hdr = 'Bearer {}'.format(device_token) # unsuccessful verification rsp = requests.post(token_verify_url, data='', headers={'Authorization': auth_hdr}) assert rsp.status_code == 401
def test_delete_by_user_ok(self, api_client_int, user_tokens_mt_f): tokens = user_tokens_mt_f for t in tokens: verify_token(api_client_int, t, 200) _, claims, _ = explode_jwt(user_tokens_mt_f[0]) tenant = claims["mender.tenant"] user = claims["sub"] payload = {"user_id": user, "tenant_id": tenant} rsp = requests.delete(api_client_int.make_api_url("/tokens"), params=payload) assert rsp.status_code == 204 verify_tokens(api_client_int, tokens, tenant, user)
def test_token_claims(self, accepted_device, management_api, device_api): devid, d, da = accepted_device token = request_token(d, da, device_api.auth_requests_url) assert len(token) > 0 print("device token:", d.token) thdr, tclaims, tsign = explode_jwt(d.token) assert 'typ' in thdr and thdr['typ'] == 'JWT' assert 'jti' in tclaims assert 'exp' in tclaims assert 'sub' in tclaims and tclaims['sub'] == devid assert 'iss' in tclaims and tclaims['iss'] == 'Mender' assert 'mender.device' in tclaims and tclaims['mender.device'] == True
def test_create_user_login(self, api_client_mgmt, cli, clean_db): email = '*****@*****.**' password = '******' tenant = 'tenant1id' users_db = {tenant: [email]} cli.create_user(email, password, tenant_id=tenant) with tenantadm.run_fake_user_tenants(users_db): _, r = api_client_mgmt.login(email, password) assert r.status_code == 200 token = r.text assert token _, claims, _ = explode_jwt(token) assert claims['mender.tenant'] == tenant
def test_create_user_login(self, api_client_mgmt, cli, clean_db): user = {"email": "*****@*****.**", "password": "******"} users_db = {TENANT_ONE: [user["email"]]} with tenantadm.run_fake_create_user(user): cli.create_user(user["email"], user["password"], tenant_id=TENANT_ONE) with tenantadm.run_fake_user_tenants(users_db): _, r = api_client_mgmt.login(user["email"], user["password"]) assert r.status_code == 200 token = r.text assert token _, claims, _ = explode_jwt(token) assert claims["mender.tenant"] == TENANT_ONE
def test_token_claims(self, accepted_device, management_api, device_api): devid, d, da = accepted_device try: with orchestrator.run_fake_for_device_id(devid) as server: token = request_token(d, da, device_api.auth_requests_url) except bravado.exception.HTTPError as e: assert e.response.status_code == 204 assert len(token) > 0 print("device token:", d.token) thdr, tclaims, tsign = explode_jwt(d.token) assert "typ" in thdr and thdr["typ"] == "JWT" assert "jti" in tclaims assert "exp" in tclaims assert "sub" in tclaims and tclaims["sub"] == devid assert "iss" in tclaims and tclaims["iss"] == "Mender" assert "mender.device" in tclaims and tclaims["mender.device"] == True
def test_token_claims(self, accepted_device, management_api, device_api): devid, d, da = accepted_device try: with orchestrator.run_fake_for_device_id(devid) as server: token = request_token(d, da, device_api.auth_requests_url) except bravado.exception.HTTPError as e: assert e.response.status_code == 204 assert len(token) > 0 print("device token:", d.token) thdr, tclaims, tsign = explode_jwt(d.token) assert 'typ' in thdr and thdr['typ'] == 'JWT' assert 'jti' in tclaims assert 'exp' in tclaims assert 'sub' in tclaims and tclaims['sub'] == devid assert 'iss' in tclaims and tclaims['iss'] == 'Mender' assert 'mender.device' in tclaims and tclaims['mender.device'] == True
def test_token(self): d = Device() da = DevAuthorizer() url = self.devapi.make_api_url("/auth_requests") # poke devauth so that device appears with deviceadm.run_fake_for_device(d) as server: rsp = device_auth_req(url, da, d) assert rsp.status_code == 401 # try to find our devices in all devices listing mc = SimpleManagementClient() dev = mc.find_device_by_identity(d.identity) self.log.debug('found matching device with ID: %s', dev.id) devid = dev.id # extract authentication data set ID aid = dev.auth_sets[0].id try: with inventory.run_fake_for_device_id(devid) as server: self.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 with deviceadm.run_fake_for_device(d) 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 self.log.info("device token: %s", d.token) thdr, tclaims, tsign = explode_jwt(d.token) assert 'typ' in thdr and thdr['typ'] == 'JWT' assert 'jti' in tclaims assert 'exp' in tclaims assert 'sub' in tclaims and tclaims['sub'] == devid assert 'iss' in tclaims and tclaims['iss'] == 'Mender' assert 'mender.device' in tclaims and tclaims['mender.device'] == True # TODO: signature verification? # verify token; the token is to be placed in the Authorization header # and it looks like bravado cannot handle a POST request with no data # in body, hence we fall back to sending request directly verify_url = self.intclient.make_api_url("/tokens/verify") self.log.info("verify URL: %s", verify_url) auth_hdr = 'Bearer {}'.format(d.token) # no auth header should raise an error rsp = requests.post(verify_url, data='') assert rsp.status_code == 401 # successful verification rsp = requests.post(verify_url, data='', headers={'Authorization': auth_hdr}) assert rsp.status_code == 200 # use a bogus token that is not a valid JWT rsp = requests.post(verify_url, data='', headers={'Authorization': 'bogus'}) assert rsp.status_code == 401 # or a correct token with data appended at the end rsp = requests.post(verify_url, data='', headers={'Authorization': auth_hdr + "==foo"}) assert rsp.status_code == 401 # bravado cannot handle DELETE requests either # self.client.tokens.delete_tokens_id(id=tclaims['jti']) # use requests instead rsp = requests.delete( self.make_api_url('/tokens/{}'.format(tclaims['jti']))) assert rsp.status_code == 204 # unsuccessful verification rsp = requests.post(verify_url, data='', headers={'Authorization': auth_hdr}) assert rsp.status_code == 401
def test_token(self): d = Device() da = DevAuthorizer() url = self.make_api_url("/auth_requests") # generate fake identity devid = make_devid(d.identity) try: self.accept_device(devid) except bravado.exception.HTTPError as e: assert e.response.status_code == 404 # poke devauth so that device appears rsp = device_auth_req(url, da, d) assert rsp.status_code == 401 try: self.accept_device(devid) except bravado.exception.HTTPError as e: assert e.response.status_code == 200 # 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 self.log.info("device token: %s", d.token) thdr, tclaims, tsign = explode_jwt(d.token) assert 'typ' in thdr and thdr['typ'] == 'JWT' assert 'jti' in tclaims assert 'exp' in tclaims assert 'sub' in tclaims and tclaims['sub'] == devid assert 'iss' in tclaims and tclaims['iss'] == 'Mender' # TODO: signature verification? # verify token; the token is to be placed in the Authorization header # and it looks like bravado cannot handle a POST request with no data # in body, hence we fall back to sending request directly verify_url = self.make_api_url("/tokens/verify") self.log.info("verify URL: %s", verify_url) auth_hdr = 'Bearer {}'.format(d.token) # no auth header should raise an error rsp = requests.post(verify_url, data='') assert rsp.status_code == 401 # successful verification rsp = requests.post(verify_url, data='', headers={'Authorization': auth_hdr}) assert rsp.status_code == 200 # use a bogus token that is not a valid JWT rsp = requests.post(verify_url, data='', headers={'Authorization': 'bogus'}) assert rsp.status_code == 401 # or a correct token with data appended at the end rsp = requests.post(verify_url, data='', headers={'Authorization': auth_hdr + "==foo"}) assert rsp.status_code == 401 # bravado cannot handle DELETE requests either # self.client.tokens.delete_tokens_id(id=tclaims['jti']) # use requests instead rsp = requests.delete( self.make_api_url('/tokens/{}'.format(tclaims['jti']))) assert rsp.status_code == 204 # unsuccessful verification rsp = requests.post(verify_url, data='', headers={'Authorization': auth_hdr}) assert rsp.status_code == 401