diff --git a/backend/infrahub/auth.py b/backend/infrahub/auth.py index 21f3f4b3bf..e0ca469037 100644 --- a/backend/infrahub/auth.py +++ b/backend/infrahub/auth.py @@ -3,7 +3,7 @@ import uuid from datetime import datetime, timedelta, timezone from enum import Enum -from typing import TYPE_CHECKING, Callable +from typing import TYPE_CHECKING import bcrypt import jwt @@ -233,29 +233,6 @@ async def validate_api_key(db: InfrahubDatabase, token: str) -> AccountSession: return AccountSession(account_id=account_id, auth_type=AuthType.API) -def _validate_update_account(account_session: AccountSession, node_id: str, fields: list[str]) -> None: - if account_session.account_id != node_id: - # A regular account is not allowed to modify another account - raise PermissionError("You are not allowed to modify this account") - - allowed_fields = ["description", "label", "password"] - for field in fields: - if field not in allowed_fields: - raise PermissionError(f"You are not allowed to modify '{field}'") - - -def validate_mutation_permissions_update_node( - operation: str, node_id: str, account_session: AccountSession, fields: list[str] -) -> None: - validation_map: dict[str, Callable[[AccountSession, str, list[str]], None]] = { - f"{InfrahubKind.ACCOUNT}Update": _validate_update_account, - f"{InfrahubKind.ACCOUNT}Upsert": _validate_update_account, - } - - if validator := validation_map.get(operation): - validator(account_session, node_id, fields) - - async def invalidate_refresh_token(db: InfrahubDatabase, token_id: str) -> None: refresh_token = await NodeManager.get_one(id=token_id, db=db) if refresh_token: diff --git a/backend/infrahub/graphql/mutations/account.py b/backend/infrahub/graphql/mutations/account.py index 94f72e9a80..500c2cee5f 100644 --- a/backend/infrahub/graphql/mutations/account.py +++ b/backend/infrahub/graphql/mutations/account.py @@ -35,8 +35,8 @@ class InfrahubAccountTokenDeleteInput(InputObjectType): class InfrahubAccountUpdateSelfInput(InputObjectType): - password = InputField(String(required=False), description="The new password") - description = InputField(String(required=False), description="The new description") + password = InputField(String(required=False), description="Password to use instead of the current one") + description = InputField(String(required=False), description="Description to use instead of the current one") class ValueType(InfrahubObjectType): @@ -123,7 +123,7 @@ async def delete_token( raise NodeNotFoundError(node_type="AccountToken", identifier=token_id) async with db.start_transaction() as dbt: - await results[0].delete(db=dbt) # type: ignore[arg-type] + await results[0].delete(db=dbt) return cls(ok=True) # type: ignore[call-arg] @@ -137,7 +137,7 @@ async def update_self( getattr(account, field).value = value async with db.start_transaction() as dbt: - await account.save(db=dbt) # type: ignore[arg-type] + await account.save(db=dbt) return cls(ok=True) # type: ignore[call-arg] diff --git a/backend/infrahub/graphql/mutations/main.py b/backend/infrahub/graphql/mutations/main.py index e6f4864243..1dc1871b62 100644 --- a/backend/infrahub/graphql/mutations/main.py +++ b/backend/infrahub/graphql/mutations/main.py @@ -8,7 +8,6 @@ from typing_extensions import Self from infrahub import config, lock -from infrahub.auth import validate_mutation_permissions_update_node from infrahub.core import registry from infrahub.core.constants import InfrahubKind, MutationAction from infrahub.core.constraint.node.runner import NodeConstraintRunner @@ -270,14 +269,8 @@ async def mutate_update( @classmethod async def mutate_update_object( - cls, - db: InfrahubDatabase, - info: GraphQLResolveInfo, - data: InputObjectType, - branch: Branch, - obj: Node, + cls, db: InfrahubDatabase, info: GraphQLResolveInfo, data: InputObjectType, branch: Branch, obj: Node ) -> Node: - context: GraphqlContext = info.context component_registry = get_component_registry() node_constraint_runner = await component_registry.get_component(NodeConstraintRunner, db=db, branch=branch) @@ -285,15 +278,11 @@ async def mutate_update_object( await obj.from_graphql(db=db, data=data) fields_to_validate = list(data) await node_constraint_runner.check(node=obj, field_filters=fields_to_validate) - node_id = data.get("id", obj.id) + fields = list(data.keys()) - if "id" in fields: - fields.remove("id") - if "hfid" in fields: - fields.remove("hfid") - validate_mutation_permissions_update_node( - operation=cls.__name__, node_id=node_id, account_session=context.account_session, fields=fields - ) + for field in ("id", "hfid"): + if field in fields: + fields.remove(field) await obj.save(db=db, fields=fields) obj = await cls._refresh_for_profile_update( diff --git a/changelog/5455.fixed.md b/changelog/5455.fixed.md new file mode 100644 index 0000000000..cd4a16960e --- /dev/null +++ b/changelog/5455.fixed.md @@ -0,0 +1 @@ +Allow to change any attributes and relationships when using a mutation on `CoreAccount` \ No newline at end of file