forked from Github-Mirrors/canaille
Client deletion also delete related objects
This commit is contained in:
parent
baf402d5da
commit
b059e6e719
5 changed files with 90 additions and 16 deletions
|
@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
|
||||
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
|
||||
|
||||
Fixed
|
||||
*****
|
||||
|
||||
- Client deletion also deletes related Consent, Token and
|
||||
AuthorizationCode objects. :issue:`126` :pr:`98`
|
||||
|
||||
[0.0.20] - 2023-01-28
|
||||
=====================
|
||||
|
||||
|
|
|
@ -32,6 +32,9 @@ class LDAPObject:
|
|||
return f"<{self.__class__.__name__} {self.rdn}={rdn}>"
|
||||
|
||||
def __eq__(self, other):
|
||||
for attr in self.may + self.must:
|
||||
if getattr(self, attr) != getattr(other, attr):
|
||||
print(getattr(self, attr), getattr(other, attr))
|
||||
return (
|
||||
isinstance(other, self.__class__)
|
||||
and self.may == other.may
|
||||
|
|
|
@ -95,6 +95,18 @@ class Client(LDAPObject, ClientMixin):
|
|||
metadata["scope"] = " ".join(metadata["scope"])
|
||||
return metadata
|
||||
|
||||
def delete(self):
|
||||
for consent in Consent.filter(client=self.dn):
|
||||
consent.delete()
|
||||
|
||||
for code in AuthorizationCode.filter(client=self.dn):
|
||||
code.delete()
|
||||
|
||||
for token in Token.filter(client=self.dn):
|
||||
token.delete()
|
||||
|
||||
super().delete()
|
||||
|
||||
|
||||
class AuthorizationCode(LDAPObject, AuthorizationCodeMixin):
|
||||
object_class = ["oauthAuthorizationCode"]
|
||||
|
|
|
@ -8,44 +8,76 @@ from werkzeug.security import gen_salt
|
|||
|
||||
def test_clean_command(testclient, slapd_connection, client, user):
|
||||
AuthorizationCode.ldap_object_classes(slapd_connection)
|
||||
code = AuthorizationCode(
|
||||
valid_code = AuthorizationCode(
|
||||
authorization_code_id=gen_salt(48),
|
||||
code="my-code",
|
||||
code="my-valid-code",
|
||||
client=client.dn,
|
||||
subject=user.dn,
|
||||
redirect_uri="https://foo.bar/callback",
|
||||
response_type="code",
|
||||
scope="openid profile",
|
||||
nonce="nonce",
|
||||
issue_date=(datetime.datetime.now() - datetime.timedelta(days=1)),
|
||||
lifetime="3600",
|
||||
issue_date=datetime.datetime.now().replace(microsecond=0),
|
||||
lifetime=3600,
|
||||
challenge="challenge",
|
||||
challenge_method="method",
|
||||
revokation="",
|
||||
)
|
||||
code.save()
|
||||
valid_code.save()
|
||||
expired_code = AuthorizationCode(
|
||||
authorization_code_id=gen_salt(48),
|
||||
code="my-expired-code",
|
||||
client=client.dn,
|
||||
subject=user.dn,
|
||||
redirect_uri="https://foo.bar/callback",
|
||||
response_type="code",
|
||||
scope="openid profile",
|
||||
nonce="nonce",
|
||||
issue_date=(
|
||||
datetime.datetime.now().replace(microsecond=0) - datetime.timedelta(days=1)
|
||||
),
|
||||
lifetime=3600,
|
||||
challenge="challenge",
|
||||
challenge_method="method",
|
||||
revokation="",
|
||||
)
|
||||
expired_code.save()
|
||||
|
||||
Token.ldap_object_classes(slapd_connection)
|
||||
token = Token(
|
||||
valid_token = Token(
|
||||
token_id=gen_salt(48),
|
||||
access_token="my-token",
|
||||
access_token="my-valid-token",
|
||||
client=client.dn,
|
||||
subject=user.dn,
|
||||
type=None,
|
||||
refresh_token=gen_salt(48),
|
||||
scope="openid profile",
|
||||
issue_date=(datetime.datetime.now() - datetime.timedelta(days=1)),
|
||||
lifetime=str(3600),
|
||||
issue_date=(datetime.datetime.now().replace(microsecond=0)),
|
||||
lifetime=3600,
|
||||
)
|
||||
token.save()
|
||||
valid_token.save()
|
||||
expired_token = Token(
|
||||
token_id=gen_salt(48),
|
||||
access_token="my-expired-token",
|
||||
client=client.dn,
|
||||
subject=user.dn,
|
||||
type=None,
|
||||
refresh_token=gen_salt(48),
|
||||
scope="openid profile",
|
||||
issue_date=(
|
||||
datetime.datetime.now().replace(microsecond=0) - datetime.timedelta(days=1)
|
||||
),
|
||||
lifetime=3600,
|
||||
)
|
||||
expired_token.save()
|
||||
|
||||
assert AuthorizationCode.get(code="my-code")
|
||||
assert Token.get(access_token="my-token")
|
||||
assert code.is_expired()
|
||||
assert token.is_expired()
|
||||
assert AuthorizationCode.get(code="my-expired-code")
|
||||
assert Token.get(access_token="my-expired-token")
|
||||
assert expired_code.is_expired()
|
||||
assert expired_token.is_expired()
|
||||
|
||||
runner = testclient.app.test_cli_runner()
|
||||
runner.invoke(cli, ["clean"])
|
||||
|
||||
assert not AuthorizationCode.get(code="my-code")
|
||||
assert not Token.get(access_token="my-token")
|
||||
assert AuthorizationCode.all() == [valid_code]
|
||||
assert Token.all() == [valid_token]
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import datetime
|
||||
|
||||
from canaille.oidc.models import AuthorizationCode
|
||||
from canaille.oidc.models import Client
|
||||
from canaille.oidc.models import Consent
|
||||
from canaille.oidc.models import Token
|
||||
|
||||
|
||||
def test_no_logged_no_access(testclient):
|
||||
|
@ -125,10 +130,26 @@ def test_client_edit_missing_fields(testclient, client, logged_admin, other_clie
|
|||
def test_client_delete(testclient, logged_admin):
|
||||
client = Client(client_id="client_id")
|
||||
client.save()
|
||||
token = Token(
|
||||
token_id="id", client=client.dn, issue_datetime=datetime.datetime.utcnow()
|
||||
)
|
||||
token.save()
|
||||
consent = Consent(
|
||||
cn="cn", subject=logged_admin.dn, client=client.dn, scope="openid"
|
||||
)
|
||||
consent.save()
|
||||
code = AuthorizationCode(
|
||||
authorization_code_id="id", client=client.dn, subject=client.dn
|
||||
)
|
||||
|
||||
res = testclient.get("/admin/client/edit/" + client.client_id)
|
||||
res = res.forms["clientadd"].submit(name="action", value="delete").follow()
|
||||
|
||||
assert not Client.get()
|
||||
assert not Token.get()
|
||||
assert not AuthorizationCode.get()
|
||||
assert not Consent.get()
|
||||
|
||||
|
||||
def test_client_delete_invalid_client(testclient, logged_admin):
|
||||
testclient.post("/admin/client/edit/invalid", {"action": "delete"}, status=404)
|
||||
|
|
Loading…
Reference in a new issue