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