refactor: move BackendModel.delete to Backend.delete

This commit is contained in:
Éloi Rivard 2024-04-14 20:37:52 +02:00
parent 09588e0f48
commit 2ccdaeadf6
No known key found for this signature in database
GPG key ID: 7EDA204EA57DD184
40 changed files with 139 additions and 118 deletions

View file

@ -89,6 +89,10 @@ class BaseBackend:
"""Validate the current modifications in the database."""
raise NotImplementedError()
def delete(self, instance):
"""Remove the current instance from the database."""
raise NotImplementedError()
def check_user_password(self, user, password: str) -> bool:
"""Check if the password matches the user password in the database."""
raise NotImplementedError()

View file

@ -130,7 +130,7 @@ class Backend(BaseBackend):
password="correct horse battery staple",
)
BaseBackend.instance.save(user)
user.delete()
BaseBackend.instance.delete(user)
except ldap.INSUFFICIENT_ACCESS as exc:
raise ConfigurationException(
@ -155,7 +155,7 @@ class Backend(BaseBackend):
members=[user],
)
BaseBackend.instance.save(group)
group.delete()
BaseBackend.instance.delete(group)
except ldap.INSUFFICIENT_ACCESS as exc:
raise ConfigurationException(
@ -164,7 +164,7 @@ class Backend(BaseBackend):
) from exc
finally:
user.delete()
BaseBackend.instance.delete(user)
@classmethod
def login_placeholder(cls):
@ -388,6 +388,19 @@ class Backend(BaseBackend):
# run the instance save callback again if existing
next(save_callback, None)
def delete(self, instance):
# run the instance delete callback if existing
save_callback = instance.delete() if hasattr(instance, "delete") else iter([])
next(save_callback, None)
try:
self.connection.delete_s(instance.dn)
except ldap.NO_SUCH_OBJECT:
pass
# run the instance delete callback again if existing
next(save_callback, None)
def setup_ldap_models(config):
from canaille.app import models

View file

@ -262,10 +262,3 @@ class LDAPObject(BackendModel, metaclass=LDAPObjectMetaclass):
result = conn.search_s(self.dn, ldap.SCOPE_SUBTREE, None, ["+", "*"])
self.changes = {}
self.state = result[0][1]
def delete(self):
conn = Backend.instance.connection
try:
conn.delete_s(self.dn)
except ldap.NO_SUCH_OBJECT:
pass

View file

@ -108,3 +108,13 @@ class Backend(BaseBackend):
instance.index_delete()
instance.index_save()
instance._cache = {}
def delete(self, instance):
# run the instance delete callback if existing
delete_callback = instance.delete() if hasattr(instance, "delete") else iter([])
next(delete_callback, None)
instance.index_delete()
# run the instance delete callback again if existing
next(delete_callback, None)

View file

@ -65,9 +65,6 @@ class MemoryModel(BackendModel):
return value
def delete(self):
self.index_delete()
def index_save(self):
# update the id index
self.index()[self.id] = copy.deepcopy(self._state)

View file

@ -88,10 +88,6 @@ class BackendModel:
implemented for every model and for every backend.
"""
def delete(self):
"""Remove the current instance from the database."""
raise NotImplementedError()
def update(self, **kwargs):
"""Assign a whole dict to the current instance. This is useful to
update models based on forms.

View file

@ -118,3 +118,14 @@ class Backend(BaseBackend):
Backend.instance.db_session.add(instance)
Backend.instance.db_session.commit()
def delete(self, instance):
# run the instance delete callback if existing
save_callback = instance.delete() if hasattr(instance, "delete") else iter([])
next(save_callback, None)
Backend.instance.db_session.delete(instance)
Backend.instance.db_session.commit()
# run the instance delete callback again if existing
next(save_callback, None)

View file

@ -47,10 +47,6 @@ class SqlAlchemyModel(BackendModel):
return getattr(cls, name) == value
def delete(self):
Backend.instance.db_session.delete(self)
Backend.instance.db_session.commit()
def reload(self):
Backend.instance.db_session.refresh(self)

View file

@ -818,7 +818,7 @@ def profile_delete(user, edited_user):
),
"success",
)
edited_user.delete()
BaseBackend.instance.delete(edited_user)
if self_deletion:
return redirect(url_for("core.account.index"))

View file

@ -162,5 +162,5 @@ def delete_group(group):
_("The group %(group)s has been sucessfully deleted", group=group.display_name),
"success",
)
group.delete()
BaseBackend.instance.delete(group)
return redirect(url_for("core.groups.groups"))

View file

@ -13,11 +13,11 @@ def clean():
"""Remove expired tokens and authorization codes."""
for t in BaseBackend.instance.query(models.Token):
if t.is_expired():
t.delete()
BaseBackend.instance.delete(t)
for a in BaseBackend.instance.query(models.AuthorizationCode):
if a.is_expired():
a.delete()
BaseBackend.instance.delete(a)
def register(cli):

View file

@ -151,5 +151,5 @@ def client_delete(client):
_("The client has been deleted."),
"success",
)
client.delete()
BaseBackend.instance.delete(client)
return redirect(url_for("oidc.clients.index"))

View file

@ -97,15 +97,15 @@ class Client(BaseClient, ClientMixin):
def delete(self):
for consent in BaseBackend.instance.query(models.Consent, client=self):
consent.delete()
BaseBackend.instance.delete(consent)
for code in BaseBackend.instance.query(models.AuthorizationCode, client=self):
code.delete()
BaseBackend.instance.delete(code)
for token in BaseBackend.instance.query(models.Token, client=self):
token.delete()
BaseBackend.instance.delete(token)
super().delete()
yield
class AuthorizationCode(BaseAuthorizationCode, AuthorizationCodeMixin):

View file

@ -246,7 +246,7 @@ class AuthorizationCodeGrant(_AuthorizationCodeGrant):
return item[0]
def delete_authorization_code(self, authorization_code):
authorization_code.delete()
BaseBackend.instance.delete(authorization_code)
def authenticate_user(self, authorization_code):
if authorization_code.subject and not authorization_code.subject.locked:
@ -481,7 +481,7 @@ class ClientConfigurationEndpoint(ClientManagementMixin, _ClientConfigurationEnd
return True
def delete_client(self, client, request):
client.delete()
BaseBackend.instance.delete(client)
def update_client(self, client, client_metadata, request):
client.update(**self.client_convert_data(**client_metadata))

View file

@ -24,4 +24,4 @@ def test_model_references_set_unsaved_object(
testclient.get("/groups/foo", status=200)
group.delete()
backend.delete(group)

View file

@ -60,8 +60,8 @@ def test_object_class_update(backend, testclient):
"extensibleObject",
}
user1.delete()
user2.delete()
backend.delete(user1)
backend.delete(user2)
def test_keep_old_object_classes(backend, testclient, slapd_server):
@ -97,4 +97,4 @@ homeDirectory: /home/foobar
# saving an object should not raise a ldap.OBJECT_CLASS_VIOLATION exception
backend.save(user)
user.delete()
backend.delete(user)

View file

@ -30,7 +30,7 @@ def test_object_creation(app, backend):
user = backend.get(models.User, id=user.id)
assert user.exists
user.delete()
backend.delete(user)
def test_repr(backend, foo_group, user):
@ -56,7 +56,7 @@ def test_dn_when_leading_space_in_id_attribute(testclient, backend):
assert user == backend.get(models.User, user_name=user.user_name)
assert user == backend.get(models.User, dn)
user.delete()
backend.delete(user)
def test_special_chars_in_rdn(testclient, backend):
@ -77,7 +77,7 @@ def test_special_chars_in_rdn(testclient, backend):
assert user == backend.get(models.User, user_name=user.user_name)
assert user == backend.get(models.User, dn)
user.delete()
backend.delete(user)
def test_filter(backend, foo_group, bar_group):

View file

@ -24,8 +24,8 @@ def test_model_comparison(testclient, backend):
assert foo1 == foo2
assert foo1 != bar
foo1.delete()
bar.delete()
backend.delete(foo1)
backend.delete(bar)
def test_model_lifecycle(testclient, backend):
@ -56,12 +56,12 @@ def test_model_lifecycle(testclient, backend):
assert user.family_name == "family_name"
user.delete()
backend.delete(user)
assert not backend.query(models.User, id=user.id)
assert not backend.get(models.User, id=user.id)
user.delete()
backend.delete(user)
def test_model_attribute_edition(testclient, backend):
@ -100,7 +100,7 @@ def test_model_attribute_edition(testclient, backend):
backend.save(user)
assert not user.display_name
user.delete()
backend.delete(user)
def test_model_indexation(testclient, backend):
@ -133,7 +133,7 @@ def test_model_indexation(testclient, backend):
assert backend.get(models.User, emails=["email2@user.com"]) == user
assert not backend.get(models.User, emails=["email3@user.com"])
user.delete()
backend.delete(user)
assert not backend.get(models.User, family_name="family_name")
assert not backend.get(models.User, family_name="new_family_name")
@ -219,4 +219,4 @@ def test_model_creation_edition_datetime(testclient, backend):
2021, 1, 1, 2, tzinfo=datetime.timezone.utc
)
user.delete()
backend.delete(user)

View file

@ -193,7 +193,7 @@ def user(app, backend):
)
backend.save(u)
yield u
u.delete()
backend.delete(u)
@pytest.fixture
@ -207,7 +207,7 @@ def admin(app, backend):
)
backend.save(u)
yield u
u.delete()
backend.delete(u)
@pytest.fixture
@ -221,7 +221,7 @@ def moderator(app, backend):
)
backend.save(u)
yield u
u.delete()
backend.delete(u)
@pytest.fixture
@ -254,7 +254,7 @@ def foo_group(app, user, backend):
backend.save(group)
user.reload()
yield group
group.delete()
backend.delete(group)
@pytest.fixture
@ -266,7 +266,7 @@ def bar_group(app, admin, backend):
backend.save(group)
admin.reload()
yield group
group.delete()
backend.delete(group)
@pytest.fixture

View file

@ -11,7 +11,7 @@ def test_populate_users(testclient, backend):
assert res.exit_code == 0, res.stdout
assert len(backend.query(models.User)) == 10
for user in backend.query(models.User):
user.delete()
backend.delete(user)
def test_populate_groups(testclient, backend):
@ -24,7 +24,7 @@ def test_populate_groups(testclient, backend):
assert len(backend.query(models.Group)) == 10
for group in backend.query(models.Group):
group.delete()
backend.delete(group)
for user in backend.query(models.User):
user.delete()
backend.delete(user)

View file

@ -33,7 +33,7 @@ def test_user_deleted_in_session(testclient, backend):
with testclient.session_transaction() as session:
session["user_id"] = [u.id]
u.delete()
backend.delete(u)
testclient.get("/profile/jake", status=404)
with testclient.session_transaction() as session:

View file

@ -173,7 +173,7 @@ def test_user_without_password_first_login(testclient, backend, smtpd):
assert len(smtpd.messages) == 2
assert [message["X-RcptTo"] for message in smtpd.messages] == u.emails
assert "Password initialization" in smtpd.messages[0].get("Subject")
u.delete()
backend.delete(u)
@mock.patch("smtplib.SMTP")
@ -200,7 +200,7 @@ def test_first_login_account_initialization_mail_sending_failed(
) not in res.flashes
assert ("error", "Could not send the password initialization email") in res.flashes
assert len(smtpd.messages) == 0
u.delete()
backend.delete(u)
def test_first_login_form_error(testclient, backend, smtpd):
@ -219,7 +219,7 @@ def test_first_login_form_error(testclient, backend, smtpd):
name="action", value="sendmail", status=400, expect_errors=True
)
assert len(smtpd.messages) == 0
u.delete()
backend.delete(u)
def test_first_login_page_unavailable_for_users_with_password(
@ -249,7 +249,7 @@ def test_user_password_deleted_during_login(testclient, backend):
res = res.form.submit(status=302)
assert res.location == "/firstlogin/temp"
u.delete()
backend.delete(u)
def test_wrong_login(testclient, user):

View file

@ -7,7 +7,7 @@ def test_no_group(app, backend):
assert backend.query(models.Group) == []
def test_group_list_pagination(testclient, logged_admin, foo_group):
def test_group_list_pagination(testclient, logged_admin, foo_group, backend):
res = testclient.get("/groups")
res.mustcontain("1 item")
@ -26,7 +26,7 @@ def test_group_list_pagination(testclient, logged_admin, foo_group):
".groups tbody tr td:nth-of-type(2) a"
).text().split(" ")
for group in groups:
group.delete()
backend.delete(group)
res = testclient.get("/groups")
res.mustcontain("1 item")
@ -64,11 +64,11 @@ def test_group_deletion(testclient, backend):
user.reload()
assert user.groups == [group]
group.delete()
backend.delete(group)
user.reload()
assert not user.groups
user.delete()
backend.delete(user)
def test_group_list_search(testclient, logged_admin, foo_group, bar_group):
@ -127,7 +127,7 @@ def test_set_groups_with_leading_space_in_user_id_attribute(app, foo_group, back
foo_group.reload()
assert user.id not in foo_group.members
user.delete()
backend.delete(user)
def test_moderator_can_create_edit_and_delete_group(
@ -252,7 +252,7 @@ def test_user_list_pagination(testclient, logged_admin, foo_group, backend):
" "
)
for user in users:
user.delete()
backend.delete(user)
res = testclient.get("/groups/foo")
res.mustcontain("1 item")
@ -360,7 +360,7 @@ def test_remove_member_already_deleted(
res = testclient.get("/groups/foo")
form = res.forms[f"deletegroupmemberform-{user.id}"]
user.delete()
backend.delete(user)
res = form.submit(name="action", value="confirm-remove-member")
assert (
@ -379,7 +379,7 @@ def test_confirm_remove_member_already_deleted(
form = res.forms[f"deletegroupmemberform-{user.id}"]
res = form.submit(name="action", value="confirm-remove-member")
user.delete()
backend.delete(user)
res = res.form.submit(name="action", value="remove-member")
assert (

View file

@ -56,7 +56,7 @@ def test_invitation(testclient, logged_admin, foo_group, smtpd, backend):
del sess["user_id"]
res = testclient.get(url, status=302)
user.delete()
backend.delete(user)
def test_invitation_editable_user_name(
@ -110,7 +110,7 @@ def test_invitation_editable_user_name(
with testclient.session_transaction() as sess:
assert "user_id" in sess
del sess["user_id"]
user.delete()
backend.delete(user)
def test_generate_link(testclient, logged_admin, foo_group, smtpd, backend):
@ -159,7 +159,7 @@ def test_generate_link(testclient, logged_admin, foo_group, smtpd, backend):
del sess["user_id"]
res = testclient.get(url, status=302)
user.delete()
backend.delete(user)
def test_invitation_login_already_taken(testclient, logged_admin):
@ -334,4 +334,4 @@ def test_groups_are_saved_even_when_user_does_not_have_read_permission(
user = backend.get(models.User, user_name="someoneelse")
foo_group.reload()
assert user.groups == [foo_group]
user.delete()
backend.delete(user)

View file

@ -24,7 +24,7 @@ def test_user_has_password(testclient, backend):
assert user.password is not None
assert user.has_password()
user.delete()
backend.delete(user)
def test_user_set_and_check_password(testclient, user, backend):

View file

@ -95,7 +95,7 @@ def test_user_creation_without_password(testclient, logged_moderator, backend):
assert george.user_name == "george"
assert not george.has_password()
george.delete()
backend.delete(george)
def test_user_creation_form_validation_failed(
@ -146,7 +146,7 @@ def test_cn_setting_with_given_name_and_surname(testclient, logged_moderator, ba
george = backend.get(models.User, user_name="george")
assert george.formatted_name == "George Abitbol"
george.delete()
backend.delete(george)
def test_cn_setting_with_surname_only(testclient, logged_moderator, backend):
@ -161,7 +161,7 @@ def test_cn_setting_with_surname_only(testclient, logged_moderator, backend):
george = backend.get(models.User, user_name="george")
assert george.formatted_name == "Abitbol"
george.delete()
backend.delete(george)
def test_formcontrol(testclient, logged_admin):

View file

@ -18,7 +18,7 @@ def test_invalid_form_request(testclient, logged_user):
)
def test_user_list_pagination(testclient, logged_admin):
def test_user_list_pagination(testclient, logged_admin, backend):
res = testclient.get("/users")
res.mustcontain("1 item")
@ -35,7 +35,7 @@ def test_user_list_pagination(testclient, logged_admin):
".users tbody tr td:nth-of-type(2) a"
).text().split(" ")
for user in users:
user.delete()
backend.delete(user)
res = testclient.get("/users")
res.mustcontain("1 item")

View file

@ -121,7 +121,7 @@ def test_photo_on_profile_creation(testclient, jpeg_photo, logged_admin, backend
user = backend.get(models.User, user_name="foobar")
assert user.photo == jpeg_photo
user.delete()
backend.delete(user)
def test_photo_deleted_on_profile_creation(
@ -144,4 +144,4 @@ def test_photo_deleted_on_profile_creation(
user = backend.get(models.User, user_name="foobar")
assert user.photo is None
user.delete()
backend.delete(user)

View file

@ -193,7 +193,7 @@ def test_password_initialization_mail(smtpd, testclient, backend, logged_admin):
res = testclient.get("/profile/temp/settings", status=200)
res.mustcontain(no="This user does not have a password yet")
u.delete()
backend.delete(u)
@mock.patch("smtplib.SMTP")
@ -224,7 +224,7 @@ def test_password_initialization_mail_send_fail(
assert ("error", "Could not send the password initialization email") in res.flashes
assert len(smtpd.messages) == 0
u.delete()
backend.delete(u)
def test_password_initialization_invalid_user(smtpd, testclient, backend, logged_admin):
@ -310,7 +310,7 @@ def test_password_reset_email(smtpd, testclient, backend, logged_admin):
assert len(smtpd.messages) == 1
assert smtpd.messages[0]["X-RcptTo"] == "john@doe.com"
u.delete()
backend.delete(u)
@mock.patch("smtplib.SMTP")
@ -340,7 +340,7 @@ def test_password_reset_email_failed(SMTP, smtpd, testclient, backend, logged_ad
assert ("error", "Could not send the password reset email") in res.flashes
assert len(smtpd.messages) == 0
u.delete()
backend.delete(u)
def test_admin_bad_request(testclient, logged_admin):

View file

@ -24,7 +24,7 @@ def test_registration_without_email_validation(testclient, backend, foo_group):
user = backend.get(models.User, user_name="newuser")
assert user
user.delete()
backend.delete(user)
def test_registration_with_email_validation(testclient, backend, smtpd, foo_group):
@ -75,7 +75,7 @@ def test_registration_with_email_validation(testclient, backend, smtpd, foo_grou
user = backend.get(models.User, user_name="newuser")
assert user
user.delete()
backend.delete(user)
def test_registration_with_email_already_taken(

View file

@ -72,7 +72,7 @@ def client(testclient, trusted_client, backend):
backend.save(c)
yield c
c.delete()
backend.delete(c)
@pytest.fixture
@ -110,7 +110,7 @@ def trusted_client(testclient, backend):
backend.save(c)
yield c
c.delete()
backend.delete(c)
@pytest.fixture
@ -131,7 +131,7 @@ def authorization(testclient, user, client, backend):
)
backend.save(a)
yield a
a.delete()
backend.delete(a)
@pytest.fixture
@ -149,7 +149,7 @@ def token(testclient, client, user, backend):
)
backend.save(t)
yield t
t.delete()
backend.delete(t)
@pytest.fixture
@ -173,4 +173,4 @@ def consent(testclient, client, user, backend):
)
backend.save(t)
yield t
t.delete()
backend.delete(t)

View file

@ -98,7 +98,7 @@ def test_nominal_case(
assert res.json["name"] == "John (johnny) Doe"
for consent in consents:
consent.delete()
backend.delete(consent)
def test_invalid_client(testclient, logged_user, keypair):
@ -158,7 +158,7 @@ def test_redirect_uri(
assert token.subject == logged_user
for consent in consents:
consent.delete()
backend.delete(consent)
def test_preconsented_client(
@ -288,7 +288,7 @@ def test_logout_login(testclient, logged_user, client, backend):
assert res.json["name"] == "John (johnny) Doe"
for consent in consents:
consent.delete()
backend.delete(consent)
def test_deny(testclient, logged_user, client, backend):
@ -376,7 +376,7 @@ def test_code_challenge(testclient, logged_user, client, backend):
backend.save(client)
for consent in consents:
consent.delete()
backend.delete(consent)
def test_consent_already_given(testclient, logged_user, client, backend):
@ -432,7 +432,7 @@ def test_consent_already_given(testclient, logged_user, client, backend):
assert "code" in params
for consent in consents:
consent.delete()
backend.delete(consent)
def test_when_consent_already_given_but_for_a_smaller_scope(
@ -500,7 +500,7 @@ def test_when_consent_already_given_but_for_a_smaller_scope(
assert "groups" in consents[0].scope
for consent in consents:
consent.delete()
backend.delete(consent)
def test_user_cannot_use_oidc(testclient, user, client, keypair, trusted_client):
@ -559,7 +559,7 @@ def test_nonce_not_required_in_oauth_requests(testclient, logged_user, client, b
assert res.location.startswith(client.redirect_uris[0])
for consent in backend.query(models.Consent):
consent.delete()
backend.delete(consent)
def test_request_scope_too_large(testclient, logged_user, keypair, client, backend):
@ -628,7 +628,7 @@ def test_request_scope_too_large(testclient, logged_user, keypair, client, backe
assert res.json["name"] == "John (johnny) Doe"
for consent in consents:
consent.delete()
backend.delete(consent)
def test_code_expired(testclient, user, client):
@ -701,7 +701,7 @@ def test_code_with_invalid_user(testclient, admin, client, backend):
code = params["code"][0]
authcode = backend.get(models.AuthorizationCode, code=code)
user.delete()
backend.delete(user)
res = testclient.post(
"/oauth/token",
@ -718,7 +718,7 @@ def test_code_with_invalid_user(testclient, admin, client, backend):
"error": "invalid_grant",
"error_description": 'There is no "user" for this code.',
}
authcode.delete()
backend.delete(authcode)
def test_locked_account(

View file

@ -39,7 +39,7 @@ def test_prompt_none(testclient, logged_user, client, backend):
params = parse_qs(urlsplit(res.location).query)
assert "code" in params
consent.delete()
backend.delete(consent)
def test_prompt_not_logged(testclient, user, client, backend):
@ -73,7 +73,7 @@ def test_prompt_not_logged(testclient, user, client, backend):
)
assert "login_required" == res.json.get("error")
consent.delete()
backend.delete(consent)
def test_prompt_no_consent(testclient, logged_user, client):
@ -126,7 +126,7 @@ def test_prompt_create_logged(testclient, logged_user, client, backend):
)
assert res.location.startswith(client.redirect_uris[0])
consent.delete()
backend.delete(consent)
def test_prompt_create_registration_disabled(testclient, trusted_client, smtpd):

View file

@ -46,7 +46,7 @@ def test_client_list_pagination(
".clients tbody tr td:nth-of-type(2) a"
).text().split(" ")
for client in clients:
client.delete()
backend.delete(client)
res = testclient.get("/admin/client")
res.mustcontain("2 items")
@ -135,7 +135,7 @@ def test_client_add(testclient, logged_admin, backend):
assert not client.preconsent
assert client.post_logout_redirect_uris == ["https://foo.bar/disconnected"]
client.delete()
backend.delete(client)
def test_add_missing_fields(testclient, logged_admin):

View file

@ -40,7 +40,7 @@ def test_authorization_list_pagination(testclient, logged_admin, client, backend
".codes tbody tr td:nth-of-type(1) a"
).text().split(" ")
for authorization in authorizations:
authorization.delete()
backend.delete(authorization)
res = testclient.get("/admin/authorization")
res.mustcontain("0 items")

View file

@ -64,7 +64,7 @@ def test_client_registration_with_authentication_static_token(
assert client.logo_uri == "https://client.example.org/logo.webp"
assert client.jwks_uri == "https://client.example.org/my_public_keys.jwks"
assert client in client.audience
client.delete()
backend.delete(client)
def test_client_registration_with_authentication_no_token(
@ -177,7 +177,7 @@ def test_client_registration_with_software_statement(testclient, backend, keypai
"https://client.example.org/callback2",
]
assert client.token_endpoint_auth_method == "client_secret_basic"
client.delete()
backend.delete(client)
def test_client_registration_without_authentication_ok(testclient, backend):
@ -246,4 +246,4 @@ def test_client_registration_without_authentication_ok(testclient, backend):
assert client.policy_uri == "https://example.com/policy"
assert client.software_id == "example"
assert client.software_version == "x.y.z"
client.delete()
backend.delete(client)

View file

@ -40,7 +40,7 @@ def test_fieldlist_add(testclient, logged_admin, backend):
"https://foo.bar/callback2",
]
client.delete()
backend.delete(client)
def test_fieldlist_delete(testclient, logged_admin, backend):
@ -74,7 +74,7 @@ def test_fieldlist_delete(testclient, logged_admin, backend):
"https://foo.bar/callback1",
]
client.delete()
backend.delete(client)
def test_fieldlist_add_invalid_field(testclient, logged_admin):
@ -146,7 +146,7 @@ def test_fieldlist_empty_value(testclient, logged_admin, backend):
)
res.form.submit(status=302, name="action", value="edit")
client = backend.get(models.Client)
client.delete()
backend.delete(client)
def test_fieldlist_add_field_htmx(testclient, logged_admin):

View file

@ -71,7 +71,7 @@ def test_refresh_token(testclient, logged_user, client, backend):
assert res.json["name"] == "John (johnny) Doe"
for consent in consents:
consent.delete()
backend.delete(consent)
def test_refresh_token_with_invalid_user(testclient, client, backend):
@ -119,7 +119,7 @@ def test_refresh_token_with_invalid_user(testclient, client, backend):
refresh_token = res.json["refresh_token"]
access_token = res.json["access_token"]
user.delete()
backend.delete(user)
res = testclient.post(
"/oauth/token",
@ -134,7 +134,8 @@ def test_refresh_token_with_invalid_user(testclient, client, backend):
"error": "invalid_request",
"error_description": 'There is no "user" for this token.',
}
backend.get(models.Token, access_token=access_token).delete()
token = backend.get(models.Token, access_token=access_token)
backend.delete(token)
def test_cannot_refresh_token_for_locked_users(

View file

@ -50,7 +50,7 @@ def test_token_list_pagination(testclient, logged_admin, client, backend):
".tokens tbody tr:nth-of-type(1) td:nth-of-type(1) a"
).text().split(" ")
for token in tokens:
token.delete()
backend.delete(token)
res = testclient.get("/admin/token")
res.mustcontain("0 items")

View file

@ -56,7 +56,7 @@ def test_token_default_expiration_date(
consents = backend.query(models.Consent, client=client, subject=logged_user)
for consent in consents:
consent.delete()
backend.delete(consent)
def test_token_custom_expiration_date(
@ -116,4 +116,4 @@ def test_token_custom_expiration_date(
consents = backend.query(models.Consent, client=client, subject=logged_user)
for consent in consents:
consent.delete()
backend.delete(consent)