Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/improve error message #95

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 70 additions & 3 deletions backend/src/contaxy/managers/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class AuthManager(AuthOperations):
_API_TOKEN_COLLECTION = "tokens"
_USER_COLLECTION = "users"
_LOGIN_ID_MAPPING_COLLECTION = "login-id-mapping"
_PROJECT_COLLECTION = "projects"

def __init__(
self,
Expand Down Expand Up @@ -972,9 +973,75 @@ def delete_user(self, user_id: str) -> None:
Raises:
ResourceNotFoundError: If no user with the specified ID exists.
"""
self._json_db_manager.delete_json_document(
config.SYSTEM_INTERNAL_PROJECT, self._USER_COLLECTION, user_id
)
try:
self._json_db_manager.delete_json_document(
config.SYSTEM_INTERNAL_PROJECT, self._USER_COLLECTION, user_id
)
except ResourceNotFoundError:
logger.warning(
f"ResourceNotFoundError: No JSON document was found in the useres table with the given key: {user_id}."
)

try:
self._json_db_manager.delete_json_document(
config.SYSTEM_INTERNAL_PROJECT, self._USER_PASSWORD_COLLECTION, user_id
)
except ResourceNotFoundError:
logger.warning(
f"ResourceNotFoundError: No JSON document was found in the password table with the given key: {user_id}."
)

try:
self._json_db_manager.delete_json_document(
config.SYSTEM_INTERNAL_PROJECT,
self._PERMISSION_COLLECTION,
"users/" + user_id,
)
except ResourceNotFoundError:
logger.warning(
f"ResourceNotFoundError: No JSON document was found in the permissions table with the given key: {user_id}."
)

try:
for token in self._json_db_manager.list_json_documents(
config.SYSTEM_INTERNAL_PROJECT, self._API_TOKEN_COLLECTION
):
user_mapping = ApiToken.parse_raw(token.json_value).subject
if user_mapping == "users/" + user_id:
self._json_db_manager.delete_json_document(
config.SYSTEM_INTERNAL_PROJECT,
self._API_TOKEN_COLLECTION,
token.key,
)
except ResourceNotFoundError:
logger.warning(
f"ResourceNotFoundError: No JSON document was found in the token table with the given key: {user_id}."
)

try:
for doc in self._json_db_manager.list_json_documents(
config.SYSTEM_INTERNAL_PROJECT, self._LOGIN_ID_MAPPING_COLLECTION
):
user_id_mapping = LoginIdMapping.parse_raw(doc.json_value).user_id
if user_id_mapping == user_id:
self._json_db_manager.delete_json_document(
config.SYSTEM_INTERNAL_PROJECT,
self._LOGIN_ID_MAPPING_COLLECTION,
doc.key,
)
except ResourceNotFoundError:
logger.warning(
f"ResourceNotFoundError: No JSON document was found in the loginID table with the given key: {user_id}."
)

try:
self._json_db_manager.delete_json_document(
config.SYSTEM_INTERNAL_PROJECT, self._PROJECT_COLLECTION, user_id
)
except ResourceNotFoundError:
logger.warning(
f"ResourceNotFoundError: No JSON document was found in the project table with the given key: {user_id}."
)

def _propose_username(self, email: str) -> str:
MAX_RETRIES = 10000
Expand Down
68 changes: 55 additions & 13 deletions backend/tests/test_auth_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from contaxy.managers.auth import AuthManager
from contaxy.managers.json_db.inmemory_dict import InMemoryDictJsonDocumentManager
from contaxy.managers.json_db.postgres import PostgresJsonDocumentManager
from contaxy.operations import JsonDocumentOperations
from contaxy.schema.auth import (
AccessLevel,
OAuth2Error,
Expand All @@ -21,14 +22,18 @@
User,
UserRegistration,
)
from contaxy.schema.exceptions import PermissionDeniedError, UnauthenticatedError
from contaxy.schema.exceptions import (
PermissionDeniedError,
ResourceNotFoundError,
UnauthenticatedError,
)
from contaxy.utils import id_utils
from contaxy.utils.state_utils import GlobalState, RequestState

from .conftest import test_settings
from .utils import ComponentManagerMock

DEFAULT_USERS_TO_GENERATE = 10
DEFAULT_USERS_TO_GENERATE = 3


def _generate_user_data(users_to_generate: int) -> List[UserRegistration]:
Expand Down Expand Up @@ -58,6 +63,11 @@ class AuthOperationsTests(ABC):
def auth_manager(self) -> AuthManager:
pass

@property
@abstractmethod
def json_db(self) -> JsonDocumentOperations:
pass

def test_change_password(self, faker: Faker) -> None:
user_id = id_utils.generate_short_uuid()
user_password = faker.password()
Expand Down Expand Up @@ -456,13 +466,35 @@ def test_update_user(self, user_data: List[UserRegistration]) -> None:
assert updated_user.email == updated_user_data.email
assert created_user.created_at == updated_user.created_at

def test_delete_user(self, user_data: List[UserRegistration]) -> None:
def test_delete_user(self) -> None:
# Create and delete single user
created_user = self.auth_manager.create_user(_generate_user_data(1)[0])
user_resource_name = f"users/{created_user.id}"
self.auth_manager.add_permission(user_resource_name, "test#read")
self.auth_manager.delete_user(created_user.id)
assert len(self.auth_manager.list_users()) == 0
# Check that all other resources have been cleaned up
# assert len(self.auth_manager.list_permissions(user_resource_name)) == 0
with pytest.raises(ResourceNotFoundError):
self.json_db.get_json_document(
config.SYSTEM_INTERNAL_PROJECT,
AuthManager._USER_PASSWORD_COLLECTION,
key=created_user.id,
)
with pytest.raises(ResourceNotFoundError):
self.json_db.get_json_document(
config.SYSTEM_INTERNAL_PROJECT,
AuthManager._LOGIN_ID_MAPPING_COLLECTION,
key=created_user.username,
)
with pytest.raises(ResourceNotFoundError):
self.json_db.get_json_document(
config.SYSTEM_INTERNAL_PROJECT,
AuthManager._LOGIN_ID_MAPPING_COLLECTION,
key=created_user.email,
)

# Create and delete multiple users
def test_delete_multiple_users(self, user_data: List[UserRegistration]) -> None:
created_users: List[User] = []
for user in user_data:
created_users.append(self.auth_manager.create_user(user))
Expand All @@ -485,35 +517,45 @@ class TestAuthManagerWithPostgresDB(AuthOperationsTests):
def _init_auth_manager(
self, global_state: GlobalState, request_state: RequestState
) -> Generator:
json_db = PostgresJsonDocumentManager(global_state, request_state)
self._json_db = PostgresJsonDocumentManager(global_state, request_state)
# Cleanup everything at the startup
json_db.delete_json_collections(config.SYSTEM_INTERNAL_PROJECT)
self._json_db.delete_json_collections(config.SYSTEM_INTERNAL_PROJECT)
self._auth_manager = AuthManager(
ComponentManagerMock(global_state, request_state, json_db_manager=json_db)
ComponentManagerMock(
global_state, request_state, json_db_manager=self._json_db
)
)
yield
json_db.delete_json_collections(config.SYSTEM_INTERNAL_PROJECT)
# Do cleanup

@property
def auth_manager(self) -> AuthManager:
return self._auth_manager

@property
def json_db(self) -> JsonDocumentOperations:
return self._json_db


@pytest.mark.unit
class TestAuthManagerWithInMemoryDB(AuthOperationsTests):
@pytest.fixture(autouse=True)
def _init_auth_manager(
self, global_state: GlobalState, request_state: RequestState
) -> Generator:
json_db = InMemoryDictJsonDocumentManager(global_state, request_state)
json_db.delete_json_collections(config.SYSTEM_INTERNAL_PROJECT)
self._json_db = InMemoryDictJsonDocumentManager(global_state, request_state)
self._json_db.delete_json_collections(config.SYSTEM_INTERNAL_PROJECT)
self._auth_manager = AuthManager(
ComponentManagerMock(global_state, request_state, json_db_manager=json_db)
ComponentManagerMock(
global_state, request_state, json_db_manager=self._json_db
)
)
yield
json_db.delete_json_collections(config.SYSTEM_INTERNAL_PROJECT)
self._json_db.delete_json_collections(config.SYSTEM_INTERNAL_PROJECT)

@property
def auth_manager(self) -> AuthManager:
return self._auth_manager

@property
def json_db(self) -> JsonDocumentOperations:
return self._json_db
11 changes: 9 additions & 2 deletions webapp/src/pages/Services/Services.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import GlobalStateContainer from '../../app/store';
import ResourceActionsDialog from '../../components/Dialogs/ResourceActionsDialog';
import ServicesContainer from './ServicesContainer';
import showStandardSnackbar from '../../app/showStandardSnackbar';
import { BodyIntrospectTokenAuthOauthIntrospectPost } from '../../services/contaxy-client';

function Services(props) {
const { className } = props;
Expand Down Expand Up @@ -46,8 +47,14 @@ function Services(props) {
onClose();
reloadServices();
} catch (err) {
showStandardSnackbar(`Could not deploy service '${deploymentName}'.`);
}
if (err.body.code == 409){
showStandardSnackbar(`Service with name '${deploymentName}' already exists.`);
}
else {
showStandardSnackbar(`Could not deploy service '${deploymentName}'.`);
}

}
},
});
}, [activeProject.id, showAppDialog, reloadServices]);
Expand Down