def test_post_with_revoked_refresh_token_returns_204( self, http_client, base_url, user ): url = f"{base_url}/api/v1/token/revoke" refresh_token = issue_token_pair(user)["refresh"] body = json.dumps({"refresh": refresh_token}) UserToken.drop_collection() response = yield http_client.fetch(url, method="POST", body=body) assert response.code == 204
def test_post_with_expired_refresh_token_returns_204( self, http_client, base_url, user ): url = f"{base_url}/api/v1/token/revoke" refresh_token = issue_token_pair(user, refresh_expiration=datetime.utcnow())[ "refresh" ] body = json.dumps({"refresh": refresh_token}) response = yield http_client.fetch(url, method="POST", body=body) assert response.code == 204
def test_post_with_expired_refresh_token_returns_400( self, http_client, base_url, user ): url = f"{base_url}/api/v1/token/refresh" refresh_token = issue_token_pair(user, refresh_expiration=datetime.utcnow())[ "refresh" ] body = json.dumps({"refresh": refresh_token}) with pytest.raises(HTTPError) as excinfo: yield http_client.fetch(url, method="POST", body=body) assert excinfo.value.code == 400
def test_auth_enabled_blocks_access_with_refresh_token( self, http_client, base_url, app_config_auth_enabled, user): url = f"{base_url}/api/v1/whoami" refresh_token = issue_token_pair(user)["refresh"] headers = {"Authorization": f"Bearer {refresh_token}"} with pytest.raises(HTTPError) as excinfo: yield http_client.fetch(url, headers=headers) response_body = json.loads(excinfo.value.response.body.decode("utf-8")) assert excinfo.value.code == 401 assert "invalid" in response_body["message"]
def test_post_with_valid_refresh_token_expires_token( self, http_client, base_url, user, app_config_auth_enabled ): url = f"{base_url}/api/v1/token/revoke" refresh_token = issue_token_pair(user)["refresh"] body = json.dumps({"refresh": refresh_token}) token_headers = jwt.get_unverified_header(refresh_token) decoded_refresh_token = jwt.decode( refresh_token, key=app_config_auth_enabled.auth.token_secret, algorithms=[token_headers["alg"]], ) assert len(UserToken.objects.filter(uuid=decoded_refresh_token["jti"])) == 1 response = yield http_client.fetch(url, method="POST", body=body) assert response.code == 204 assert len(UserToken.objects.filter(uuid=decoded_refresh_token["jti"])) == 0
def test_auth_enabled_allows_sync_users_patch_with_permissions_to_all_gardens( self, monkeypatch, http_client, base_url, app_config_auth_enabled, user, garden_admin_role, ): monkeypatch.setattr( beer_garden.api.http.handlers.v1.garden, "initiate_user_sync", Mock() ) user.role_assignments.append( RoleAssignment( role=garden_admin_role, domain={ "scope": "Global", }, ), ) access_token = issue_token_pair(user)["access"] url = f"{base_url}/api/v1/gardens" headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json", } patch_body = { "operation": "sync_users", } request = HTTPRequest( url, method="PATCH", headers=headers, body=json.dumps(patch_body) ) response = yield http_client.fetch(request) assert response.code == 204 assert beer_garden.api.http.handlers.v1.garden.initiate_user_sync.called is True
def test_auth_enabled_allows_post_permitted_system( self, http_client, base_url, app_config_auth_enabled, garden, user, system_admin_role, system_cleanup, ): garden_role_assignment = RoleAssignment( role=system_admin_role, domain={"scope": "Garden", "identifiers": {"name": garden.name}}, ) user.role_assignments.append(garden_role_assignment) access_token = issue_token_pair(user)["access"] url = f"{base_url}/api/v1/systems" headers = {"Authorization": f"Bearer {access_token}"} post_body = { "version": "1.0.0", "namespace": garden.name, "name": "newsystem", "commands": [ { "name": "mycommand", } ], } request = HTTPRequest( url, method="POST", headers=headers, body=json.dumps(post_body) ) response = yield http_client.fetch(request) assert response.code == 201 assert len(System.objects.filter(name="newsystem", namespace=garden.name)) == 1
def test_post_with_valid_refresh_token_returns_new_token_pair( self, http_client, base_url, user, app_config_auth_enabled ): url = f"{base_url}/api/v1/token/refresh" expiration = datetime.now(tz=timezone.utc) + timedelta(days=1) refresh_token = issue_token_pair(user, expiration)["refresh"] body = json.dumps({"refresh": refresh_token}) response = yield http_client.fetch(url, method="POST", body=body) response_body = json.loads(response.body.decode("utf-8")) new_access_token = response_body["access"] token_headers = jwt.get_unverified_header(new_access_token) decoded_access_token = jwt.decode( new_access_token, key=app_config_auth_enabled.auth.token_secret, algorithms=[token_headers["alg"]], ) new_refresh_token = response_body["refresh"] token_headers = jwt.get_unverified_header(new_refresh_token) decoded_refresh_token = jwt.decode( new_refresh_token, key=app_config_auth_enabled.auth.token_secret, algorithms=[token_headers["alg"]], ) assert response.code == 200 assert decoded_access_token["sub"] == str(user.id) assert decoded_access_token["jti"] == decoded_refresh_token["jti"] # Milliseconds get lost during jwt.encode, so we just check the timedelta assert ( expiration - datetime.fromtimestamp(decoded_refresh_token["exp"], tz=timezone.utc) ) < timedelta(seconds=1)
def test_auth_enabled_blocks_access_with_expired_token( self, monkeypatch, http_client, base_url, app_config_auth_enabled, user): def yesterday(): return datetime.utcnow() - timedelta(days=1) monkeypatch.setattr( beer_garden.api.http.authentication, "_get_access_token_expiration", yesterday, ) url = f"{base_url}/api/v1/whoami" access_token = issue_token_pair(user)["access"] headers = {"Authorization": f"Bearer {access_token}"} with pytest.raises(HTTPError) as excinfo: yield http_client.fetch(url, headers=headers) response_body = json.loads(excinfo.value.response.body.decode("utf-8")) assert excinfo.value.code == 401 assert "expired" in response_body["message"]
def access_token_permitted(user_with_permission): yield issue_token_pair(user_with_permission)["access"]
def access_token(user): yield issue_token_pair(user)["access"]
def access_token_user_admin(user_admin): yield issue_token_pair(user_admin)["access"]
def read_only_access_token(read_only_user): yield issue_token_pair(read_only_user)["access"]