register a signal that caches the user's credentials on login
[plstackapi.git] / plstackapi / core / admin.py
1 from plstackapi.core.models import Site
2 from plstackapi.core.models import *
3 from django.contrib import admin
4 from django.contrib.auth.models import Group
5
6 from django import forms
7 from django.utils.safestring import mark_safe
8 from django.contrib.auth.admin import UserAdmin
9 from django.contrib.admin.widgets import FilteredSelectMultiple
10 from django.contrib.auth.forms import ReadOnlyPasswordHashField
11 from django.contrib.auth.signals import user_logged_in 
12
13
14 class ReadonlyTabularInline(admin.TabularInline):
15     can_delete = False
16     extra = 0
17     editable_fields = []
18
19     def get_readonly_fields(self, request, obj=None):
20         fields = []
21         for field in self.model._meta.get_all_field_names():
22             if (not field == 'id'):
23                 if (field not in self.editable_fields):
24                     fields.append(field)
25         return fields
26
27     def has_add_permission(self, request):
28         return False
29
30 class SliverInline(admin.TabularInline):
31     model = Sliver
32     fields = ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']
33     extra = 0
34
35 class SiteInline(admin.TabularInline):
36     model = Site
37     extra = 0
38
39 class NodeInline(admin.TabularInline):
40     model = Node
41     extra = 0
42
43 class PlanetStackBaseAdmin(admin.ModelAdmin):
44     save_on_top = False
45
46 class DeploymentNetworkAdminForm(forms.ModelForm):
47     sites = forms.ModelMultipleChoiceField(
48         queryset=Site.objects.all(),
49         required=False,
50         widget=FilteredSelectMultiple(
51             verbose_name=('Sites'), is_stacked=False
52         )
53     )
54     class Meta:
55         model = DeploymentNetwork
56
57     def __init__(self, *args, **kwargs):
58         super(DeploymentNetworkAdminForm, self).__init__(*args, **kwargs)
59
60         if self.instance and self.instance.pk:
61             self.fields['sites'].initial = self.instance.sites.all()
62
63     def save(self, commit=True):
64         deploymentNetwork = super(DeploymentNetworkAdminForm, self).save(commit=False)
65
66         if commit:
67             deploymentNetwork.save()
68
69         if deploymentNetwork.pk:
70             deploymentNetwork.sites = self.cleaned_data['sites']
71             self.save_m2m()
72
73         return deploymentNetwork
74
75 class DeploymentNetworkAdmin(PlanetStackBaseAdmin):
76     form = DeploymentNetworkAdminForm
77     inlines = [NodeInline,]
78
79 class SiteAdmin(admin.ModelAdmin):
80     fieldsets = [
81         (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
82         ('Location', {'fields': ['latitude', 'longitude']}),
83         ('Deployment Networks', {'fields': ['deployments']})
84     ]
85     list_display = ('name', 'login_base','site_url', 'enabled')
86     filter_horizontal = ('deployments',)
87     inlines = [NodeInline,]
88     search_fields = ['name']
89
90 class KeyAdmin(admin.ModelAdmin):
91     fieldsets = [
92         ('Key', {'fields': ['name', 'key', 'type', 'blacklisted', 'user']})
93     ]
94     list_display = ['name', 'key', 'type', 'blacklisted', 'user']
95
96 class SliceAdmin(PlanetStackBaseAdmin):
97     fields = ['name', 'site', 'instantiation', 'description', 'slice_url']
98     list_display = ('name', 'site','slice_url', 'instantiation')
99     inlines = [SliverInline]
100
101 class SubnetAdmin(admin.ModelAdmin):
102     fields = ['cidr', 'ip_version', 'start', 'end', 'slice']
103     list_display = ('slice','cidr', 'start', 'end', 'ip_version' )
104
105 class ImageAdmin(admin.ModelAdmin):
106     fields = ['image_id', 'name', 'disk_format', 'container_format']
107
108 class NodeAdmin(admin.ModelAdmin):
109     list_display = ('name', 'site', 'deploymentNetwork')
110     list_filter = ('deploymentNetwork',)
111
112 class RoleAdmin(admin.ModelAdmin):
113     fieldsets = [
114         ('Role', {'fields': ['role_type']})
115     ]
116     list_display = ('role_type',)
117
118 class PlainTextWidget(forms.Widget):
119     def render(self, _name, value, attrs):
120         return mark_safe(value) if value is not None else ''
121
122 class SliverForm(forms.ModelForm):
123     class Meta:
124         ip = forms.CharField(widget=PlainTextWidget)
125         model = Sliver
126         widgets = {
127             'ip': PlainTextWidget(),
128         }
129
130 class SliverAdmin(admin.ModelAdmin):
131     form = SliverForm
132     fieldsets = [
133         ('Sliver', {'fields': ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']})
134     ]
135     list_display = ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']
136
137 class UserCreationForm(forms.ModelForm):
138     """A form for creating new users. Includes all the required
139     fields, plus a repeated password."""
140     password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
141     password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
142
143     class Meta:
144         model = PLUser
145         fields = ('email', 'firstname', 'lastname', 'phone', 'site')
146
147     def clean_password2(self):
148         # Check that the two password entries match
149         password1 = self.cleaned_data.get("password1")
150         password2 = self.cleaned_data.get("password2")
151         if password1 and password2 and password1 != password2:
152             raise forms.ValidationError("Passwords don't match")
153         return password2
154
155     def save(self, commit=True):
156         # Save the provided password in hashed format
157         user = super(UserCreationForm, self).save(commit=False)
158         user.set_password(self.cleaned_data["password1"])
159         if commit:
160             user.save()
161         return user
162
163
164 class UserChangeForm(forms.ModelForm):
165     """A form for updating users. Includes all the fields on
166     the user, but replaces the password field with admin's
167     password hash display field.
168     """
169     password = ReadOnlyPasswordHashField()
170
171     class Meta:
172         model = PLUser
173
174     def clean_password(self):
175         # Regardless of what the user provides, return the initial value.
176         # This is done here, rather than on the field, because the
177         # field does not have access to the initial value
178         return self.initial["password"]
179
180
181 class PLUserAdmin(UserAdmin):
182     class Meta:
183         app_label = "core"
184
185     # The forms to add and change user instances
186     form = UserChangeForm
187     add_form = UserCreationForm
188
189     # The fields to be used in displaying the User model.
190     # These override the definitions on the base UserAdmin
191     # that reference specific fields on auth.User.
192     list_display = ('email', 'site', 'firstname', 'lastname', 'last_login')
193     list_filter = ('site',)
194     fieldsets = (
195         (None, {'fields': ('email', 'password')}),
196         ('Personal info', {'fields': ('firstname','lastname','phone','site')}),
197         #('Important dates', {'fields': ('last_login',)}),
198     )
199     add_fieldsets = (
200         (None, {
201             'classes': ('wide',),
202             'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'password1', 'password2')}
203         ),
204     )
205     search_fields = ('email',)
206     ordering = ('email',)
207     filter_horizontal = ()
208
209 # register a signal that caches the user's credentials when they log in
210 def cache_credentials(sender, user, request, **kwds):
211     auth = {'username': request.POST['username'],
212             'password': request.POST['password']}
213     request.session['auth'] = auth
214 user_logged_in.connect(cache_credentials)
215
216 # Now register the new UserAdmin...
217 admin.site.register(PLUser, PLUserAdmin)
218 # ... and, since we're not using Django's builtin permissions,
219 # unregister the Group model from admin.
220 admin.site.unregister(Group)
221
222 admin.site.register(Site, SiteAdmin)
223 admin.site.register(SitePrivilege)
224 admin.site.register(Slice, SliceAdmin)
225 admin.site.register(SliceMembership)
226 admin.site.register(Subnet, SubnetAdmin)
227 admin.site.register(Image, ImageAdmin)
228 admin.site.register(Node, NodeAdmin)
229 admin.site.register(Sliver, SliverAdmin)
230 admin.site.register(Flavor)
231 admin.site.register(Key, KeyAdmin)
232 admin.site.register(Role, RoleAdmin)
233 admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)
234