Skip to content

Commit

Permalink
Improved MDM software management
Browse files Browse the repository at this point in the history
  • Loading branch information
tnurse18 committed Nov 11, 2021
1 parent 6cd069e commit 7d89902
Show file tree
Hide file tree
Showing 10 changed files with 492 additions and 229 deletions.
78 changes: 42 additions & 36 deletions devices/forms.py
Expand Up @@ -1401,33 +1401,32 @@ def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_class = "form-horizontal col-md-6"
self.helper.layout = Layout(
Fieldset(title, 'name', 'identifier', 'developer', 'version', 'description'),
Fieldset(title, 'name', 'version', 'developer', 'description', 'developer_website'),
FormActions(Submit('save', "Submit"))
)
super(NewAppForm, self).__init__(*args, **kwargs)

self.fields['name'].label = "Application Name"
self.fields['identifier'].help_text = "A list of applications compatible with the MDM can be found " \
"<a href='" + reverse("mdm:app-list") + "' target='_blank'>here</a>. " \
"Please enter the respective identifier above."
self.fields['developer_website'].label = "Website"
self.fields['developer_website'].help_text = "Please enter a fully formed URL (i.e. https://lnl.wpi.edu)"

class Meta:
model = MacOSApp
fields = ['name', 'identifier', 'developer', 'version', 'description']
fields = ['name', 'developer', 'version', 'description', 'developer_website']

class FieldAccess:
def __init__(self):
pass

can_request = FieldAccessLevel(
lambda user, instance: user.has_perm('devices.view_apps', instance),
enable=('name', 'identifier', 'developer'),
exclude=('version', 'description')
lambda user, instance: user.has_perm('devices.add_apps', instance),
enable=('name', 'developer', 'version', 'developer_website'),
exclude=('description',)
)

can_edit = FieldAccessLevel(
lambda user, instance: user.has_perm('devices.manage_apps', instance),
enable=('name', 'identifier', 'developer', 'version', 'description')
enable=('name', 'developer', 'version', 'description', 'developer_website')
)


Expand All @@ -1444,64 +1443,71 @@ def __init__(self, *args, **kwargs):
'developer',
'version',
'description',
'update_available',
'developer_website',
'requires_license',
css_class="col-md-12"
)
),
FormActions(
Submit("save", "Delete", css_class="btn-danger"),
Submit("save", "Merge"),
Submit("save", "Save Changes")
)
)
super(UpdateAppForm, self).__init__(*args, **kwargs)

self.fields['identifier'].help_text = "A list of applications compatible with the MDM can be found " \
self.fields['identifier'].help_text = "If the application is available in homebrew, it can be found " \
"<a href='" + reverse("mdm:app-list") + "' target='_blank'>here</a>. " \
"Please enter the respective identifier above."
self.fields['update_available'].help_text = "Check this to instruct the MDM to update this application to " \
"the newest version"
self.fields['version'].help_text = "Include the version to make the application available for deployment"
"Enter the respective identifier above (if applicable)."
self.fields['identifier'].label = "Homebrew Identifier"
self.fields['developer_website'].label = "Website"
self.fields['developer_website'].help_text = "Please enter a fully formed URL (i.e. https://lnl.wpi.edu)"

class Meta:
model = MacOSApp
fields = ['name', 'identifier', 'developer', 'version', 'description', 'update_available']
fields = ['name', 'identifier', 'developer', 'version', 'description', 'developer_website', 'requires_license']


class UninstallAppForm(forms.Form):
options = forms.ChoiceField(choices=[('auto', 'I would like to have this app removed from all managed devices'),
('manual', 'I would like to leave the applications as they are')],
widget=forms.RadioSelect, label="Before continuing, please select one of the following")
class AppMergeForm(forms.Form):
options = forms.ChoiceField(label="Select the application to merge this into", choices=[])

def __init__(self, *args, **kwargs):
pk = kwargs.pop('pk')
app_name = MacOSApp.objects.get(pk=pk).name
self.helper = FormHelper()
self.helper.form_class = "form-horizontal col-md-6"
self.helper.layout = Layout(
Fieldset('Merge ' + app_name + ' into...', 'options'),
FormActions(Submit('save', 'Merge'))
)
super(AppMergeForm, self).__init__(*args, **kwargs)

items = [(app.pk, app.name) for app in MacOSApp.objects.exclude(pk=pk, merged_into__isnull=False).all()]
self.fields['options'].choices = items


class UninstallAppForm(forms.Form):
def __init__(self, *args, **kwargs):
mode = kwargs.pop('mode')
self.helper = FormHelper()
self.helper.form_class = "form-horizontal col-md-6"
warning = '<p style="font-weight: bold"><span style="color: red">WARNING:</span> This app has been ' \
'deployed to one or more devices. Before removing this app from the MDM, you will need to decide ' \
'what to do with the existing installs.</p><p>There are two ways to handle this:</p><ul>' \
'<li><strong>[Recommended]</strong> The first option is to have the MDM uninstall the app ' \
'automatically. The app will be removed from each device the next time the device checks in. If ' \
'you are currently using a managed device, you can sign out and sign back in to force a checkin.' \
'</li><li>The second option is to leave the applications as they are. Managed applications can be ' \
'removed at any time using the same method you would use to remove any other application.</li></ul>'
warning = '<p style="font-weight: bold"><span style="color: red">WARNING:</span> Our records indicate that ' \
'this app might still be installed on one or more devices. Note that if this application is still ' \
'installed, it will reappear here the next time that device checks in. Managed applications can be ' \
'uninstalled using the Managed Software Center or Homebrew (if applicable).</li></ul>'
if mode == 'disassociate':
warning = '<p>This app may still be installed on the device. Select an option to continue.</p>'
warning = '<p>This app may still be installed on the device. Note that if it is, it could reappear here ' \
'the next time the device checks in. Would you like to continue anyways?</p>'
self.helper.layout = Layout(
Fieldset(
'Remove Application',
Div(
HTML(warning),
HTML('<div class="col-md-12">'),
'options',
HTML('</div><br><br>'),
HTML('<br><br>'),
FormActions(
Submit('save', 'Continue')
)
)
)
)
super(UninstallAppForm, self).__init__(*args, **kwargs)

if mode == 'disassociate':
self.fields['options'].choices = [('auto', 'I would like the app to be uninstalled at the next check-in'),
('manual', 'The app has already been removed manually')]
43 changes: 43 additions & 0 deletions devices/migrations/0010_auto_20211110_1552.py
@@ -0,0 +1,43 @@
# Generated by Django 3.1.8 on 2021-11-10 20:52

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('devices', '0009_auto_20201028_2249'),
]

operations = [
migrations.RemoveField(
model_name='macosapp',
name='update_available',
),
migrations.AddField(
model_name='macosapp',
name='developer_website',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='macosapp',
name='managed',
field=models.BooleanField(default=False, verbose_name='Available in MSC'),
),
migrations.AddField(
model_name='macosapp',
name='merged_into',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devices.macosapp', verbose_name='mergedapps'),
),
migrations.AddField(
model_name='macosapp',
name='requires_license',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='macosapp',
name='identifier',
field=models.CharField(blank=True, help_text='Homebrew Identifier', max_length=64, null=True),
),
]
11 changes: 8 additions & 3 deletions devices/models.py
Expand Up @@ -76,14 +76,19 @@ def __str__(self):
class MacOSApp(models.Model):
"""Used to keep track of managed applications for LNL's MacBooks"""
name = models.CharField(max_length=128)
identifier = models.CharField(max_length=64, help_text="Homebrew Identifier")
identifier = models.CharField(max_length=64, blank=True, null=True, help_text="Homebrew Identifier")
version = models.CharField(max_length=36, blank=True, null=True)
developer = models.CharField(max_length=64, blank=True, null=True)
description = models.TextField(blank=True, null=True)
developer = models.CharField(max_length=64, blank=True, null=True)
developer_website = models.URLField(blank=True, null=True)
requires_license = models.BooleanField(default=False)
managed = models.BooleanField(default=False, verbose_name="Available in MSC")

pending_install = models.ManyToManyField(Laptop, related_name="apps_pending", blank=True)
pending_removal = models.ManyToManyField(Laptop, related_name="apps_remove", blank=True)
installed = models.ManyToManyField(Laptop, related_name="apps_installed", blank=True)
update_available = models.BooleanField(blank=True, default=False)

merged_into = models.ForeignKey("self", on_delete=models.SET_NULL, blank=True, null=True, verbose_name="mergedapps")

def __str__(self):
return self.name
Expand Down

0 comments on commit 7d89902

Please sign in to comment.