Skip to main content
Glama
test_admin_groups_api.py34.9 kB
# mcp-server/tests/integration/test_admin_groups_api.py from fastapi.testclient import TestClient import pytest import json import os # Helper to load current rbac data for assertions def load_rbac_data(rbac_file_path): with open(rbac_file_path, 'r') as f: return json.load(f) BASE_TEST_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # ./tests WORKING_RBAC_FILE = os.path.join(BASE_TEST_DIR, "data", "test_rbac.json") # Tests for Group Management by Global Admin # Requires globaladmin token (password: "password_global") def test_create_group_success(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") assert token, "Failed to get token for globaladmin" headers = {"Authorization": f"Bearer {token}"} group_data = {"nome": "new_group_1", "descricao": "A brand new group"} response = client.post("/tools/grupos", headers=headers, json=group_data) assert response.status_code == 200 assert response.json() == {"message": "Grupo 'new_group_1' criado com sucesso."} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert "new_group_1" in rbac_data["grupos"] assert rbac_data["grupos"]["new_group_1"]["descricao"] == "A brand new group" assert rbac_data["grupos"]["new_group_1"]["admins"] == [] # Initially no admins assert rbac_data["grupos"]["new_group_1"]["users"] == [] assert rbac_data["grupos"]["new_group_1"]["ferramentas"] == [] def test_create_group_already_exists(client: TestClient, auth_token_for_user): # Obtém token para o globaladmin token = auth_token_for_user("globaladmin", "password_global") # Garante que o token foi obtido com sucesso assert token, "Falha ao obter token para o usuário globaladmin. Verifique se o usuário existe e a senha está correta." headers = {"Authorization": f"Bearer {token}"} # Tenta criar um grupo com o nome 'group1' que já deve existir no arquivo test_rbac_fixed.json group_data = {"nome": "group1", "descricao": "Attempt to recreate"} # Imprime o conteúdo atual do RBAC para debug print("Verificando conteúdo do RBAC antes do teste:") rbac_data = load_rbac_data(WORKING_RBAC_FILE) print(f"Grupos existentes: {list(rbac_data.get('grupos', {}).keys())}") response = client.post("/tools/grupos", headers=headers, json=group_data) assert response.status_code == 409 assert response.json() == {"detail": "Grupo já existe."} def test_create_group_no_name(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} group_data = {"descricao": "Group without a name"} # Missing "nome" response = client.post("/tools/grupos", headers=headers, json=group_data) assert response.status_code == 422 # Validation error def test_create_group_not_global_admin(client: TestClient, auth_token_for_user): token = auth_token_for_user("testuser1", "password123") # testuser1 is not global_admin assert token, "Failed to get token for testuser1" headers = {"Authorization": f"Bearer {token}"} group_data = {"nome": "group_by_user", "descricao": "Should fail"} response = client.post("/tools/grupos", headers=headers, json=group_data) assert response.status_code == 403 assert response.json() == {"detail": "Acesso restrito ao admin global."} def test_list_groups_success_global_admin(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} response = client.get("/tools/grupos", headers=headers) assert response.status_code == 200 groups = response.json() assert isinstance(groups, list) # Check for expected groups from master data group_names = [g["nome"] for g in groups] assert "group1" in group_names assert "group_for_request" in group_names for group in groups: if group["nome"] == "group1": assert group["descricao"] == "Test Group 1" assert "admin_group1" in group["administradores"] assert "testuser1" in group["usuarios"] assert "admin_group1" in group["usuarios"] # Check if tool_x is correctly represented in ferramentas_disponiveis tool_x_found = any(t["id"] == "tool_x" and t["nome"] == "Ferramenta X" for t in group["ferramentas_disponiveis"]) assert tool_x_found, "Tool X not found in group1's available tools" def test_list_groups_not_global_admin(client: TestClient, auth_token_for_user): token = auth_token_for_user("testuser1", "password123") headers = {"Authorization": f"Bearer {token}"} response = client.get("/tools/grupos", headers=headers) assert response.status_code == 403 assert response.json() == {"detail": "Acesso restrito ao admin global."} def test_edit_group_success(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} edit_data = {"nome": "group1_renamed", "descricao": "Updated description for group1"} response = client.put("/tools/grupos/group1", headers=headers, json=edit_data) assert response.status_code == 200 assert response.json() == {"message": "Grupo 'group1_renamed' editado com sucesso."} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert "group1" not in rbac_data["grupos"] # Old name should be gone assert "group1_renamed" in rbac_data["grupos"] assert rbac_data["grupos"]["group1_renamed"]["descricao"] == "Updated description for group1" # Ensure other properties like admins, users, ferramentas are preserved assert rbac_data["grupos"]["group1_renamed"]["admins"] == ["admin_group1"] assert "tool_x" in rbac_data["grupos"]["group1_renamed"]["ferramentas"] # Also check if users who were in "group1" are now in "group1_renamed" assert "group1_renamed" in rbac_data["usuarios"]["testuser1"]["grupos"] assert "group1" not in rbac_data["usuarios"]["testuser1"]["grupos"] assert "group1_renamed" in rbac_data["usuarios"]["admin_group1"]["grupos"] assert "group1" not in rbac_data["usuarios"]["admin_group1"]["grupos"] def test_edit_group_only_description(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} edit_data = {"descricao": "Only description updated for group_for_request"} response = client.put("/tools/grupos/group_for_request", headers=headers, json=edit_data) assert response.status_code == 200 assert response.json() == {"message": "Grupo 'group_for_request' editado com sucesso."} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert rbac_data["grupos"]["group_for_request"]["descricao"] == "Only description updated for group_for_request" assert rbac_data["grupos"]["group_for_request"]["admins"] == ["admin_group_for_request"] # Check if other data is intact def test_edit_group_rename_to_existing_name(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} # Create a temporary group to avoid conflict with master data for other tests client.post("/tools/grupos", headers=headers, json={"nome": "temp_group_for_edit_test", "descricao": "temp"}) edit_data = {"nome": "group1"} # Try to rename "temp_group_for_edit_test" to "group1" which exists response = client.put("/tools/grupos/temp_group_for_edit_test", headers=headers, json=edit_data) assert response.status_code == 409 assert response.json() == {"detail": "Já existe um grupo com o nome 'group1'."} # Cleanup: delete the temporary group client.delete("/tools/grupos/temp_group_for_edit_test", headers=headers) def test_edit_group_not_found(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} edit_data = {"nome": "non_existent_group_new_name"} response = client.put("/tools/grupos/non_existent_group", headers=headers, json=edit_data) assert response.status_code == 404 assert response.json() == {"detail": "Grupo não encontrado."} def test_edit_group_not_global_admin(client: TestClient, auth_token_for_user): token = auth_token_for_user("admin_group1", "password_admin_g1") # admin_group1 is not global_admin headers = {"Authorization": f"Bearer {token}"} edit_data = {"descricao": "Attempt by group admin"} response = client.put("/tools/grupos/group1", headers=headers, json=edit_data) assert response.status_code == 403 assert response.json() == {"detail": "Acesso restrito ao admin global."} def test_delete_group_success(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} # First, create a group to delete to avoid altering master data needed for other tests group_to_delete_name = "group_to_be_deleted_test" client.post("/tools/grupos", headers=headers, json={"nome": group_to_delete_name, "descricao": "temp group"}) # Add a user to this group to test if user's group list is updated rbac_data_before_delete = load_rbac_data(WORKING_RBAC_FILE) rbac_data_before_delete["usuarios"]["testuser1"]["grupos"].append(group_to_delete_name) rbac_data_before_delete["grupos"][group_to_delete_name]["users"].append("testuser1") with open(WORKING_RBAC_FILE, 'w') as f: json.dump(rbac_data_before_delete, f) response = client.delete(f"/tools/grupos/{group_to_delete_name}", headers=headers) assert response.status_code == 200 assert response.json() == {"message": f"Grupo '{group_to_delete_name}' removido com sucesso."} rbac_data_after_delete = load_rbac_data(WORKING_RBAC_FILE) assert group_to_delete_name not in rbac_data_after_delete["grupos"] # Check if user "testuser1" no longer has this group assert group_to_delete_name not in rbac_data_after_delete["usuarios"]["testuser1"]["grupos"] def test_delete_group_not_found(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} response = client.delete("/tools/grupos/non_existent_group_for_delete", headers=headers) assert response.status_code == 404 assert response.json() == {"detail": "Grupo não encontrado."} def test_delete_group_not_global_admin(client: TestClient, auth_token_for_user): token = auth_token_for_user("admin_group1", "password_admin_g1") headers = {"Authorization": f"Bearer {token}"} # admin_group1 should not be able to delete group1 even if they are admin of it response = client.delete("/tools/grupos/group1", headers=headers) assert response.status_code == 403 assert response.json() == {"detail": "Acesso restrito ao admin global."} # TODO: Add more tests for other group management endpoints: # - POST /grupos/{grupo}/admins # - DELETE /grupos/{grupo}/admins/{username_param} # - POST /grupos/{grupo}/usuarios # - DELETE /grupos/{grupo}/usuarios/{username} # - POST /grupos/{grupo}/promover-admin # - GET /grupos/{grupo}/usuarios # - POST /grupos/{grupo}/ferramentas # - DELETE /grupos/{grupo}/ferramentas/{tool_id} # - GET /grupos/disponivel (though this is more user-centric) # --- Tests for Managing Users and Admins within Groups --- @pytest.fixture def setup_group_for_user_management(client: TestClient, auth_token_for_user): """Creates a fresh group and a new user for user management tests.""" ga_token = auth_token_for_user("globaladmin", "password_global") headers_ga = {"Authorization": f"Bearer {ga_token}"} group_name = "user_manage_group" user_to_add_name = "user_for_group_manage" # Clean up if exists from previous failed run client.delete(f"/tools/grupos/{group_name}", headers=headers_ga) client.delete(f"/tools/usuarios/{user_to_add_name}", headers=headers_ga) # Assuming this endpoint exists # Create group client.post("/tools/grupos", headers=headers_ga, json={"nome": group_name, "descricao": "Test group for user management"}) # Create user (assuming /tools/usuarios for user creation by global admin exists and works) # If not, this user needs to be in test_rbac_master.json or created manually in rbac file for tests # For now, let's assume it needs to be pre-existing or created via a different mechanism if /tools/usuarios POST is not ready. # We will use 'requesteruser' which is already in master data and not in any group initially. user_to_add_name = "requesteruser" return group_name, user_to_add_name, headers_ga def test_add_user_to_group_global_admin(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_add, headers_ga = setup_group_for_user_management response = client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_add}) assert response.status_code == 200, response.text assert response.json() == {"message": f"Usuário '{user_to_add}' adicionado ao grupo '{group_name}'"} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert user_to_add in rbac_data["grupos"][group_name]["users"] assert group_name in rbac_data["usuarios"][user_to_add]["grupos"] def test_add_user_to_group_group_admin(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_add, headers_ga = setup_group_for_user_management # Adiciona 'admin_group1' como membro antes de promover a admin client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": "admin_group1"}) client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": "admin_group1"}) group_admin_token = auth_token_for_user("admin_group1", "password_admin_g1") headers_group_admin = {"Authorization": f"Bearer {group_admin_token}"} response = client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_group_admin, json={"username": user_to_add}) assert response.status_code == 200, response.text assert response.json() == {"message": f"Usuário '{user_to_add}' adicionado ao grupo '{group_name}'"} def test_add_user_to_group_user_already_in_group(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_add, headers_ga = setup_group_for_user_management client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_add}) # Add first time response = client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_add}) # Try adding again assert response.status_code == 200, response.text rbac_data = load_rbac_data(WORKING_RBAC_FILE) user_count_in_group = rbac_data["grupos"][group_name]["users"].count(user_to_add) assert user_count_in_group == 1, "User should not be duplicated in group's user list" group_count_in_user = rbac_data["usuarios"][user_to_add]["grupos"].count(group_name) assert group_count_in_user == 1, "Group should not be duplicated in user's group list" def test_add_user_to_group_user_not_exist(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, _, headers_ga = setup_group_for_user_management response = client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": "non_existent_user_for_add"}) assert response.status_code == 400, response.text assert response.json() == {"detail": "Usuário inválido."} def test_add_user_to_group_group_not_exist(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} response = client.post("/tools/grupos/non_existent_group_for_user_add/usuarios", headers=headers, json={"username": "testuser1"}) assert response.status_code == 404, response.text assert response.json() == {"detail": "Grupo não encontrado."} def test_add_user_to_group_no_permission(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_add, _ = setup_group_for_user_management regular_user_token = auth_token_for_user("testuser1", "password123") # testuser1 is not admin of group_name or global headers_user = {"Authorization": f"Bearer {regular_user_token}"} response = client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_user, json={"username": user_to_add}) assert response.status_code == 403, response.text assert response.json() == {"detail": "Acesso restrito ao admin do grupo ou global."} def test_remove_user_from_group_global_admin(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_manage, headers_ga = setup_group_for_user_management client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_manage}) # Add user first response = client.delete(f"/tools/grupos/{group_name}/usuarios/{user_to_manage}", headers=headers_ga) assert response.status_code == 200, response.text assert response.json() == {"message": f"Usuário '{user_to_manage}' removido do grupo '{group_name}'"} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert user_to_manage not in rbac_data["grupos"][group_name]["users"] assert group_name not in rbac_data["usuarios"][user_to_manage]["grupos"] # If user was also admin, ensure they are removed from admins list too assert user_to_manage not in rbac_data["grupos"][group_name]["admins"] def test_remove_user_from_group_group_admin(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_manage, headers_ga = setup_group_for_user_management # Adiciona 'admin_group1' como membro antes de promover a admin client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": "admin_group1"}) client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": "admin_group1"}) group_admin_token = auth_token_for_user("admin_group1", "password_admin_g1") headers_group_admin = {"Authorization": f"Bearer {group_admin_token}"} response = client.delete(f"/tools/grupos/{group_name}/usuarios/{user_to_manage}", headers=headers_group_admin) assert response.status_code == 200, response.text def test_remove_user_from_group_user_not_in_group(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, _, headers_ga = setup_group_for_user_management # user 'testuser1' is not in 'group_name' initially by this fixture response = client.delete(f"/tools/grupos/{group_name}/usuarios/testuser1", headers=headers_ga) assert response.status_code == 404, response.text assert response.json() == {"detail": "Usuário não está no grupo."} def test_remove_user_from_group_no_permission(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_manage, headers_ga = setup_group_for_user_management client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_manage}) # Add user non_admin_token = auth_token_for_user("plainuser", "plainpassword") # plainuser is not admin headers_non_admin = {"Authorization": f"Bearer {non_admin_token}"} response = client.delete(f"/tools/grupos/{group_name}/usuarios/{user_to_manage}", headers=headers_non_admin) assert response.status_code == 403, response.text assert response.json() == {"detail": "Acesso restrito ao admin do grupo ou global."} def test_designate_group_admin_global_admin(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_promote, headers_ga = setup_group_for_user_management # Add user to group first, as per API logic (must be member to be admin) client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_promote}) response = client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": user_to_promote}) assert response.status_code == 200, response.text assert response.json() == {"message": f"Usuário '{user_to_promote}' agora é admin do grupo '{group_name}'"} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert user_to_promote in rbac_data["grupos"][group_name]["admins"] def test_designate_group_admin_user_not_in_group(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_not_in_group, headers_ga = setup_group_for_user_management # user_not_in_group (requesteruser) is NOT added to group_name yet response = client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": user_not_in_group}) assert response.status_code == 400, response.text assert response.json() == {"detail": f"Usuário '{user_not_in_group}' não é membro do grupo '{group_name}'. Adicione como membro primeiro."} def test_remove_group_admin_global_admin(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_make_admin, headers_ga = setup_group_for_user_management client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_make_admin}) client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": user_to_make_admin}) response = client.delete(f"/tools/grupos/{group_name}/admins/{user_to_make_admin}", headers=headers_ga) assert response.status_code == 200, response.text assert response.json() == {"message": f"Usuário '{user_to_make_admin}' não é mais admin do grupo '{group_name}'."} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert user_to_make_admin not in rbac_data["grupos"][group_name]["admins"] def test_remove_group_admin_by_group_admin(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_demote, headers_ga = setup_group_for_user_management acting_admin_username = "admin_group1" # Add user_to_demote to the group and make them an admin client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_demote}) client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": user_to_demote}) # Make acting_admin_username an admin of this group too client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": acting_admin_username}) client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": acting_admin_username}) acting_admin_token = auth_token_for_user(acting_admin_username, "password_admin_g1") headers_acting_admin = {"Authorization": f"Bearer {acting_admin_token}"} response = client.delete(f"/tools/grupos/{group_name}/admins/{user_to_demote}", headers=headers_acting_admin) assert response.status_code == 200, response.text rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert user_to_demote not in rbac_data["grupos"][group_name]["admins"] def test_remove_last_group_admin_by_group_admin_fail(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, _, headers_ga = setup_group_for_user_management last_admin_username = "admin_group1" # Add last_admin_username as the only admin client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": last_admin_username}) client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": last_admin_username}) last_admin_token = auth_token_for_user(last_admin_username, "password_admin_g1") headers_last_admin = {"Authorization": f"Bearer {last_admin_token}"} # Try to remove self as last admin response = client.delete(f"/tools/grupos/{group_name}/admins/{last_admin_username}", headers=headers_last_admin) assert response.status_code == 400, response.text assert response.json() == {"detail": "Não é possível remover o último administrador do grupo."} def test_remove_last_group_admin_by_global_admin_success(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, _, headers_ga = setup_group_for_user_management last_admin_username = "admin_group1" client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": last_admin_username}) client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": last_admin_username}) # Global admin can remove the last admin response = client.delete(f"/tools/grupos/{group_name}/admins/{last_admin_username}", headers=headers_ga) assert response.status_code == 200, response.text rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert last_admin_username not in rbac_data["grupos"][group_name]["admins"] def test_promote_user_to_group_admin_global_admin(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_promote, headers_ga = setup_group_for_user_management client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_promote}) # Ensure user is in group response = client.post(f"/tools/grupos/{group_name}/promover-admin", headers=headers_ga, json={"username": user_to_promote}) assert response.status_code == 200, response.text assert response.json() == {"message": f"Usuário '{user_to_promote}' agora é admin do grupo '{group_name}'"} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert user_to_promote in rbac_data["grupos"][group_name]["admins"] def test_promote_user_to_group_admin_group_admin(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_to_promote, headers_ga = setup_group_for_user_management acting_admin = "admin_group1" # Add user_to_promote to group client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": user_to_promote}) # Make acting_admin an admin of this group client.post(f"/tools/grupos/{group_name}/usuarios", headers=headers_ga, json={"username": acting_admin}) client.post(f"/tools/grupos/{group_name}/admins", headers=headers_ga, json={"username": acting_admin}) group_admin_token = auth_token_for_user(acting_admin, "password_admin_g1") headers_group_admin = {"Authorization": f"Bearer {group_admin_token}"} response = client.post(f"/tools/grupos/{group_name}/promover-admin", headers=headers_group_admin, json={"username": user_to_promote}) assert response.status_code == 200, response.text rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert user_to_promote in rbac_data["grupos"][group_name]["admins"] def test_promote_user_to_group_admin_user_not_in_group(client: TestClient, auth_token_for_user, setup_group_for_user_management): group_name, user_not_member, headers_ga = setup_group_for_user_management # user_not_member (requesteruser) is not in group_name response = client.post(f"/tools/grupos/{group_name}/promover-admin", headers=headers_ga, json={"username": user_not_member}) assert response.status_code == 400, response.text assert response.json() == {"detail": f"Usuário '{user_not_member}' não é membro do grupo '{group_name}'. Não pode ser promovido."} def test_list_users_in_group_global_admin(client: TestClient, auth_token_for_user): token = auth_token_for_user("globaladmin", "password_global") headers = {"Authorization": f"Bearer {token}"} # group1 has admin_group1 (admin, user) and testuser1 (user) # Determine current name of group1 due to potential rename in test_edit_group_success_rename_and_description rbac_before = load_rbac_data(WORKING_RBAC_FILE) original_group1_current_name = "group1_renamed" if "group1_renamed" in rbac_before["grupos"] else "group1" response = client.get(f"/tools/grupos/{original_group1_current_name}/usuarios", headers=headers) assert response.status_code == 200, response.text data = response.json() assert "admin_group1" in data["admins"] assert "admin_group1" in data["users"] assert "testuser1" in data["users"] def test_list_users_in_group_group_admin(client: TestClient, auth_token_for_user): # admin_group1 is admin of group1 (or its renamed version) token = auth_token_for_user("admin_group1", "password_admin_g1") headers = {"Authorization": f"Bearer {token}"} rbac_before = load_rbac_data(WORKING_RBAC_FILE) original_group1_current_name = "group1_renamed" if "group1_renamed" in rbac_before["grupos"] else "group1" response = client.get(f"/tools/grupos/{original_group1_current_name}/usuarios", headers=headers) assert response.status_code == 200, response.text data = response.json() assert "admin_group1" in data["admins"] assert "testuser1" in data["users"] def test_list_users_in_group_group_member(client: TestClient, auth_token_for_user): # testuser1 is a member of group1 (or its renamed version), but not an admin of it. token = auth_token_for_user("testuser1", "password123") headers = {"Authorization": f"Bearer {token}"} rbac_before = load_rbac_data(WORKING_RBAC_FILE) original_group1_current_name = "group1_renamed" if "group1_renamed" in rbac_before["grupos"] else "group1" response = client.get(f"/tools/grupos/{original_group1_current_name}/usuarios", headers=headers) assert response.status_code == 200, response.text # Members can view user list of their group data = response.json() assert "admin_group1" in data["admins"] assert "testuser1" in data["users"] def test_list_users_in_group_no_permission(client: TestClient, auth_token_for_user): # plainuser is not a member or admin of group1 (or its renamed version) token = auth_token_for_user("plainuser", "plainpassword") headers = {"Authorization": f"Bearer {token}"} rbac_before = load_rbac_data(WORKING_RBAC_FILE) original_group1_current_name = "group1_renamed" if "group1_renamed" in rbac_before["grupos"] else "group1" response = client.get(f"/tools/grupos/{original_group1_current_name}/usuarios", headers=headers) assert response.status_code == 403, response.text assert response.json() == {"detail": "Acesso restrito. Você deve ser membro ou administrador do grupo, ou administrador global."} # --- Tests for Managing Tools within Groups (Basic Add/Remove by Global Admin) --- # Tool management by group admin will require similar tests. @pytest.fixture def setup_group_for_tool_management(client: TestClient, auth_token_for_user): ga_token = auth_token_for_user("globaladmin", "password_global") headers_ga = {"Authorization": f"Bearer {ga_token}"} group_name = "tool_manage_group" # Ensure tool_y exists in master data (it does) tool_id_to_manage = "tool_y" client.delete(f"/tools/grupos/{group_name}", headers=headers_ga) # Cleanup client.post("/tools/grupos", headers=headers_ga, json={"nome": group_name, "descricao": "Test group for tool management"}) return group_name, tool_id_to_manage, headers_ga def test_add_tool_to_group_global_admin(client: TestClient, auth_token_for_user, setup_group_for_tool_management): group_name, tool_id, headers_ga = setup_group_for_tool_management response = client.post(f"/tools/grupos/{group_name}/ferramentas", headers=headers_ga, json={"tool_id": tool_id}) assert response.status_code == 200, response.text assert response.json() == {"message": f"Ferramenta '{tool_id}' adicionada com sucesso ao grupo '{group_name}'"} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert tool_id in rbac_data["grupos"][group_name]["ferramentas"] def test_add_tool_to_group_tool_already_in_group(client: TestClient, auth_token_for_user, setup_group_for_tool_management): group_name, tool_id, headers_ga = setup_group_for_tool_management client.post(f"/tools/grupos/{group_name}/ferramentas", headers=headers_ga, json={"tool_id": tool_id}) # Add first time response = client.post(f"/tools/grupos/{group_name}/ferramentas", headers=headers_ga, json={"tool_id": tool_id}) # Try again assert response.status_code == 409, response.text assert response.json() == {"detail": f"Ferramenta '{tool_id}' já existe no grupo '{group_name}'."} def test_add_tool_to_group_tool_not_exist_globally(client: TestClient, auth_token_for_user, setup_group_for_tool_management): group_name, _, headers_ga = setup_group_for_tool_management non_existent_tool_id = "tool_non_existent" response = client.post(f"/tools/grupos/{group_name}/ferramentas", headers=headers_ga, json={"tool_id": non_existent_tool_id}) assert response.status_code == 404, response.text assert response.json() == {"detail": f"Ferramenta com ID '{non_existent_tool_id}' não encontrada nas definições globais."} def test_remove_tool_from_group_global_admin(client: TestClient, auth_token_for_user, setup_group_for_tool_management): group_name, tool_id, headers_ga = setup_group_for_tool_management client.post(f"/tools/grupos/{group_name}/ferramentas", headers=headers_ga, json={"tool_id": tool_id}) # Add tool first response = client.delete(f"/tools/grupos/{group_name}/ferramentas/{tool_id}", headers=headers_ga) assert response.status_code == 200, response.text assert response.json() == {"message": f"Ferramenta '{tool_id}' removida com sucesso do grupo '{group_name}'"} rbac_data = load_rbac_data(WORKING_RBAC_FILE) assert tool_id not in rbac_data["grupos"][group_name]["ferramentas"] def test_remove_tool_from_group_tool_not_in_group(client: TestClient, auth_token_for_user, setup_group_for_tool_management): group_name, tool_id_not_added, headers_ga = setup_group_for_tool_management # tool_id_not_added (tool_y) is not added to group_name by the fixture setup for this specific test path response = client.delete(f"/tools/grupos/{group_name}/ferramentas/{tool_id_not_added}", headers=headers_ga) assert response.status_code == 404, response.text assert response.json() == {"detail": f"Ferramenta '{tool_id_not_added}' não encontrada no grupo '{group_name}'."} # TODO: Add tests for tool management by group admins. # TODO: Add tests for GET /grupos/disponivel

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jowpereira/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server