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

[bug] Deleting VPN template does not delete VpnClient objects #831

Open
pandafy opened this issue Feb 9, 2024 · 2 comments
Open

[bug] Deleting VPN template does not delete VpnClient objects #831

pandafy opened this issue Feb 9, 2024 · 2 comments
Labels

Comments

@pandafy
Copy link
Member

pandafy commented Feb 9, 2024

How to replicate

  1. Open Django shell (in command line) and check the number of VpnClient objects using this query VpnClient.objects.count()
  2. Create a VPN server object with OpenVPN backend
  3. Create a VPN template for this VPN server
  4. Add the VPN template to a device
  5. Go to the VPN template page and delete the Template
  6. Open Django shell (in command line) and check the number of VpnClient objects using this query VpnClient.objects.count()

Expected outcome
The number of VpnClients is different in Step 1 and Step 6 should be same.

Actual outcome

The number of VpnClients is different in Step 1 and Step 6 (increased by one). It is because the deletion of VPN template didn't trigger deletion of related VpnClient objects (there is no direct relation).

@pandafy pandafy added the bug label Feb 9, 2024
@pandafy
Copy link
Member Author

pandafy commented Feb 9, 2024

I found that it is possible to have two different VPN templates for the same VPN server object. But, it is not possible to apply both the templates on the same device, as the JSONSchema generates the following error

There is a conflict with the specified templates. Invalid configuration triggered by "#/files", validator says:

Screenshot from 2024-02-09 17-53-02

I think we should discourage using different templates for the same VPN server object on the same device using validation (we can create a separate issue for this).

@pandafy
Copy link
Member Author

pandafy commented Feb 9, 2024

We should double check the working of the following code. I think, it is not getting triggered when the template object is deleted.

@classmethod
def manage_vpn_clients(cls, action, instance, pk_set, **kwargs):
"""
automatically manages associated vpn clients if the
instance is using templates which have type set to "VPN"
and "auto_cert" set to True.
This method is called from a django signal (m2m_changed)
see config.apps.ConfigConfig.connect_signals
"""
if action not in ['post_add', 'post_remove']:
return
vpn_client_model = cls.vpn.through
# coming from signal
if isinstance(pk_set, set):
template_model = cls.get_template_model()
# Ordering the queryset here doesn't affect the functionality
# since pk_set is a set. Though ordering the queryset is required
# for tests.
templates = template_model.objects.filter(pk__in=list(pk_set)).order_by(
'created'
)
# coming from admin ModelForm
else:
templates = pk_set
# delete VPN clients which have been cleared
# by sortedm2m and have not been added back
if action == 'post_add':
vpn_list = instance.templates.filter(type='vpn').values_list('vpn')
instance.vpnclient_set.exclude(vpn__in=vpn_list).delete()
# when adding or removing specific templates
for template in templates.filter(type='vpn'):
if action == 'post_add':
if vpn_client_model.objects.filter(
config=instance, vpn=template.vpn
).exists():
continue
client = vpn_client_model(
config=instance,
vpn=template.vpn,
auto_cert=template.auto_cert,
)
client.full_clean()
client.save()
elif action == 'post_remove':
for client in instance.vpnclient_set.filter(vpn=template.vpn):
client.delete()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: To do (Python & Django)
Development

No branches or pull requests

1 participant