def table_update(request, pk, obj_type=None): """ Called from editableGrid tables when updating a field. Try to update an object specified by pk with the post data. """ # Infer obj_type from URL, saves trouble of having to specify # kwargs everywhere in the dispatchers. obj_type = obj_type or request.path.split('/')[2] Klass, FormKlass = get_klasses(obj_type) obj = get_object_or_404(Klass, pk=pk) if not perm_soft(request, ACTION_UPDATE, obj=obj): return HttpResponse(json.dumps({'error': 'You do not have appropriate' ' permissions.'})) # DNS specific. qd = request.POST.copy() if 'fqdn' in qd and obj_type != "ptr": fqdn = qd.pop('fqdn')[0] try: # Call prune tree later if error, else domain leak. label, domain = ensure_label_domain(fqdn) except ValidationError, e: return HttpResponse(json.dumps({'error': e.messages})) qd['label'], qd['domain'] = label, str(domain.pk)
def cydns_view(request, pk=None): """List, create, update view in one for a flatter heirarchy. """ # Infer obj_type from URL, saves trouble of having to specify # kwargs everywhere in the dispatchers. obj_type = request.path.split('/')[2] Klass, FormKlass = get_klasses(obj_type) obj = get_object_or_404(Klass, pk=pk) if pk else None if request.method == 'POST': page_obj = None form = FormKlass(request.POST, instance=obj) try: if perm(request, ACTION_CREATE, obj=obj, obj_class=Klass): obj = form.save() # If domain, add to current ctnr. if is_ajax_form(request): return HttpResponse(json.dumps({'success': True})) if (hasattr(obj, 'ctnr_set') and not obj.ctnr_set.exists()): obj.ctnr_set.add(request.session['ctnr']) return redirect(obj.get_list_url()) except (ValidationError, ValueError), e: if hasattr(e, 'messages'): e = e.messages if not form._errors: form._errors = ErrorDict() form._errors['__all__'] = ErrorList(e) if is_ajax_form(request): return HttpResponse(json.dumps({'errors': form.errors}))
def cy_delete(request): """DELETE. DELETE. DELETE.""" if not request.POST: return redirect(request.META.get('HTTP_REFERER', '')) obj_type = request.POST.get('obj_type', None) pk = request.POST.get('pk', None) Klass, _ = get_klasses(obj_type) obj = Klass.objects.filter(id=pk) if obj.exists(): obj = obj.get() else: return HttpResponse(json.dumps({'error': 'Object does not exist'})) try: if perm(request, ACTION_DELETE, obj=obj): if Klass.__name__ == 'Ctnr': request = ctnr_delete_session(request, obj) obj.delete() except ValidationError as e: return HttpResponse(json.dumps({'error': ', '.join(e.messages)})) referer = request.META.get('HTTP_REFERER', obj.get_list_url()) if referer.endswith('/'): referer = obj.get_list_url() # if the obj is an av do not redirect to av list view if 'av' in obj_type: referer = request.META.get( 'HTTP_REFERER', '') return HttpResponse(json.dumps({'msg': 'Object was successfully deleted', 'url': referer}))
def cy_view(request, template, pk=None, obj_type=None): """List, create, update view in one for a flatter heirarchy. """ # Infer obj_type from URL, saves trouble of having to specify # kwargs everywhere in the dispatchers. obj_type = obj_type or request.path.split('/')[2] Klass, FormKlass = get_klasses(obj_type) obj = get_object_or_404(Klass, pk=pk) if pk else None form = None if request.method == 'POST': object_table = None page_obj = None form = FormKlass(request.POST, instance=obj) if form.is_valid(): try: if perm(request, ACTION_CREATE, obj=obj, obj_class=Klass): obj = form.save() if Klass.__name__ == 'Ctnr': request = ctnr_update_session(request, obj) if (hasattr(obj, 'ctnr_set') and not obj.ctnr_set.exists()): obj.ctnr_set.add(request.session['ctnr']) object_table = tablefy([obj], request=request) return HttpResponse( json.dumps({'row': object_table})) except (ValidationError, ValueError) as e: if form.errors is None: form.errors = ErrorDict() form.errors.update(e.message_dict) return HttpResponse(json.dumps({'errors': form.errors})) except DatabaseError as e: # DatabaseError(number, description) if form.errors is None: form.errors = ErrorDict() form.errors.setdefault('__all__', []).append(e.args[1]) return HttpResponse(json.dumps({'errors': form.errors})) else: return HttpResponse(json.dumps({'errors': form.errors})) elif request.method == 'GET': object_list = _filter(request, Klass) form = FormKlass(instance=obj) page_obj = make_paginator(request, do_sort(request, object_list), 50) object_table = tablefy(page_obj, request=request) if isinstance(form, UsabilityFormMixin): form.make_usable(request) return cy_render(request, template, { 'form': form, 'obj': obj, 'page_obj': page_obj, 'object_table': object_table, 'obj_type': obj_type, 'pretty_obj_type': Klass.pretty_type, 'pk': pk, })
def cy_view(request, template, pk=None, obj_type=None): """List, create, update view in one for a flatter heirarchy. """ # Infer obj_type from URL, saves trouble of having to specify # kwargs everywhere in the dispatchers. obj_type = obj_type or request.path.split('/')[2] Klass, FormKlass = get_klasses(obj_type) obj = get_object_or_404(Klass, pk=pk) if pk else None form = None if request.method == 'POST': object_table = None page_obj = None form = FormKlass(request.POST, instance=obj) if form.is_valid(): try: if perm(request, ACTION_CREATE, obj=obj, obj_class=Klass): obj = form.save() if Klass.__name__ == 'Ctnr': request = ctnr_update_session(request, obj) if (hasattr(obj, 'ctnr_set') and not obj.ctnr_set.exists()): obj.ctnr_set.add(request.session['ctnr']) object_table = tablefy([obj], request=request) return HttpResponse(json.dumps({'row': object_table})) except (ValidationError, ValueError) as e: if form.errors is None: form.errors = ErrorDict() form.errors.update(e.message_dict) return HttpResponse(json.dumps({'errors': form.errors})) except DatabaseError as e: # DatabaseError(number, description) if form.errors is None: form.errors = ErrorDict() form.errors.setdefault('__all__', []).append(e.args[1]) return HttpResponse(json.dumps({'errors': form.errors})) else: return HttpResponse(json.dumps({'errors': form.errors})) elif request.method == 'GET': object_list = _filter(request, Klass) form = FormKlass(instance=obj) page_obj = make_paginator(request, do_sort(request, object_list), 50) object_table = tablefy(page_obj, request=request) if isinstance(form, UsabilityFormMixin): form.make_usable(request) return cy_render( request, template, { 'form': form, 'obj': obj, 'page_obj': page_obj, 'object_table': object_table, 'obj_type': obj_type, 'pretty_obj_type': Klass.pretty_type, 'pk': pk, })
def cydhcp_detail(request, pk): obj_type = request.path.split('/')[2] Klass, FormKlass = get_klasses(obj_type) obj = get_object_or_404(Klass, pk=pk) attr_getter = getattr(obj, "{0}av_set".format(obj_type)) return render(request, "{0}/{0}_detail.html".format(obj_type), { obj_type: obj, 'attrs': attr_getter.all() })
def cy_detail(request, Klass, template, obj_sets, pk=None, obj=None, **kwargs): """Show bunches of related tables. obj_sets -- string of foreign key attribute of the obj OR queryset relating to the obj Pass in either pk or already retrieved obj. """ # Get object if needed. obj_type = request.path.split('/')[2] if not obj and pk: obj = get_object_or_404(Klass, pk=pk) elif not obj and pk: raise Exception("pk or obj required.") # Build related tables and paginators. tables = [] for name, obj_set in obj_sets.items(): if isinstance(obj_set, str): obj_set = getattr(obj, obj_set).all() page_obj = make_paginator(request, obj_set, obj_type=name.lower().replace(' ', '')) if obj_type == 'user': table = tablefy(page_obj, request=request, update=False, related_object=obj) else: table = tablefy(page_obj, request=request, related_object=obj) tables.append({'name': name, 'page_obj': page_obj, 'table': table}) if obj_type == 'user': table = tablefy((obj, ), request=request, update=False, detail_view=True) else: table = tablefy((obj, ), request=request, detail_view=True) return cy_render( request, template, dict({ 'obj': obj, 'obj_table': table, 'obj_type': obj_type, 'pretty_obj_type': (django_pretty_type(obj_type) or get_klasses(obj_type)[0].pretty_type), 'tables': tables }.items() + kwargs.items()))
def search_obj(request): """ Returns a list of objects of 'obj_type' matching 'term'. """ obj_type = request.GET.get('obj_type', '') term = request.GET.get('term', '') if not (obj_type and term): raise Http404 Klass, FormKlass = get_klasses(obj_type) records = Klass.objects.filter(make_megafilter(Klass, term))[:15] records = [{'label': str(record), 'pk': record.pk} for record in records] return HttpResponse(json.dumps(records))
def cy_detail(request, Klass, template, obj_sets, pk=None, obj=None, **kwargs): """Show bunches of related tables. obj_sets -- string of foreign key attribute of the obj OR queryset relating to the obj Pass in either pk or already retrieved obj. """ # Get object if needed. obj_type = request.path.split('/')[2] if not obj and pk: obj = get_object_or_404(Klass, pk=pk) elif not obj and pk: raise Exception("pk or obj required.") # Build related tables and paginators. tables = [] for name, obj_set in obj_sets.items(): if isinstance(obj_set, str): obj_set = getattr(obj, obj_set).all() page_obj = make_paginator( request, obj_set, obj_type=name.lower().replace(' ', '')) if obj_type == 'user': table = tablefy(page_obj, request=request, update=False, related_object=obj) else: table = tablefy(page_obj, request=request, related_object=obj) tables.append({ 'name': name, 'page_obj': page_obj, 'table': table }) if obj_type == 'user': table = tablefy((obj,), request=request, update=False, detail_view=True) else: table = tablefy((obj,), request=request, detail_view=True) return cy_render(request, template, dict({ 'obj': obj, 'obj_table': table, 'obj_type': obj_type, 'pretty_obj_type': (django_pretty_type(obj_type) or get_klasses(obj_type)[0].pretty_type), 'tables': tables }.items() + kwargs.items()))
def objects_removed(ctnr, objects, objtype="domain"): for obj in objects: for klass, _ in get_klasses(): if klass is Domain or klass is Range: continue if ((hasattr(klass, objtype) or hasattr(klass, "%s_set" % objtype)) and (hasattr(klass, "ctnr") or hasattr(klass, "ctnr_set"))): results = klass.filter_by_ctnr(ctnr, objects=None) if issubclass(klass, BasePTR) and objtype == "range": results = [p for p in results.all() if p.range == obj] else: try: kwargs = {objtype: obj} except FieldError: continue results = results.filter(**kwargs) if results: raise ValidationError( "Cannot remove {0} because some {1} depends on" " this {0} and container.".format(objtype, klass.pretty_type))
def objects_removed(ctnr, objects, objtype="domain"): for obj in objects: for klass, _ in get_klasses(): if klass is Domain or klass is Range: continue if ((hasattr(klass, objtype) or hasattr(klass, "%s_set" % objtype)) and (hasattr(klass, "ctnr") or hasattr(klass, "ctnr_set"))): results = klass.filter_by_ctnr(ctnr, objects=None) if issubclass(klass, BasePTR) and objtype == "range": results = [p for p in results.all() if p.range == obj] else: try: kwargs = {objtype: obj} except FieldError: continue results = results.filter(**kwargs) if results: raise ValidationError( "Cannot remove {0} because some {1} depends on" " this {0} and container.".format( objtype, klass.pretty_type))
def prettify_obj_type(obj_type, *args, **kwargs): return get_klasses(obj_type)[0].pretty_type
def get_update_form(request): """ Update view called asynchronously from the list_create view Returns an http response including the form, form_title, submit_btn_label, and pk. """ obj_type = request.GET.get('obj_type', '') record_pk = request.GET.get('pk', '') related_type = request.GET.get('related_type', '') related_pk = request.GET.get('related_pk', '') kwargs = json.loads(request.GET.get('data', '{}').replace("'", "\"")) if kwargs: print kwargs if not obj_type: raise Http404 Klass, FormKlass = get_klasses(obj_type) form_title = 'Creating {0}'.format(Klass.pretty_type) submit_btn_label = 'Create {0}'.format(Klass.pretty_type) try: # Get the object if updating. if record_pk: record = Klass.objects.get(pk=record_pk) form_title = form_title.replace('Creating', 'Updating') submit_btn_label = submit_btn_label.replace('Create', 'Update') if perm(request, ACTION_UPDATE, obj=record): form = FormKlass(instance=record) else: # Get form to create a new object and prepopulate if related_type and related_pk: # This try-except is faster than # `'entity' in ...get_all_field_names()`. try: # test if the model has an 'entity' field FormKlass._meta.model._meta.get_field('entity') # autofill the 'entity' field kwargs['entity'] = related_pk except: # no 'entity' field pass initial = copy(kwargs) initial[related_type] = related_pk form = FormKlass(initial=initial) if related_type == 'range' and not obj_type.endswith('_av'): for field in ['vrf', 'site', 'next_ip']: form.fields[field].widget = forms.HiddenInput() form.fields['ip_str'].widget.attrs['readonly'] = True form.fields['ip_type'].widget.attrs['readonly'] = True ip_type = form.fields['ip_type'].initial form.fields['ip_type'].choices = [ (str(ip_type), "IPv{0}".format(ip_type))] if FormKlass.__name__ == 'RangeForm': Network = get_model('cyder', 'network') network = Network.objects.get(id=related_pk) network_str = network.network_str.split('/') initial = '.'.join( network_str[0].split('.')[:int(network_str[1])/8]) if int(network_str[1]) < 32: initial += '.' form = FormKlass(initial=dict( {'start_str': initial, 'end_str': initial, related_type: related_pk}.items() + kwargs.items())) else: form = FormKlass(initial=kwargs) except ObjectDoesNotExist: raise Http404 if related_type in form.fields: RelatedKlass, _ = get_klasses(related_type) form.fields[related_type] = ModelChoiceField( widget=HiddenInput, empty_label=None, queryset=RelatedKlass.objects.filter(pk=int(related_pk))) if isinstance(form, UsabilityFormMixin): form.make_usable(request) return HttpResponse( json.dumps({ 'form': form.as_p(), 'form_title': form_title, 'submit_btn_label': submit_btn_label, 'pk': record_pk }))
def get_update_form(request): """ Update view called asynchronously from the list_create view Returns an http response including the form, form_title, submit_btn_label, and pk. """ obj_type = request.GET.get('obj_type', '') record_pk = request.GET.get('pk', '') related_type = request.GET.get('related_type', '') related_pk = request.GET.get('related_pk', '') kwargs = json.loads(request.GET.get('data', '{}').replace("'", "\"")) if kwargs: print kwargs if not obj_type: raise Http404 Klass, FormKlass = get_klasses(obj_type) form_title = 'Creating {0}'.format(Klass.pretty_type) submit_btn_label = 'Create {0}'.format(Klass.pretty_type) try: # Get the object if updating. if record_pk: record = Klass.objects.get(pk=record_pk) form_title = form_title.replace('Creating', 'Updating') submit_btn_label = submit_btn_label.replace('Create', 'Update') if perm(request, ACTION_UPDATE, obj=record): form = FormKlass(instance=record) else: # Get form to create a new object and prepopulate if related_type and related_pk: # This try-except is faster than # `'entity' in ...get_all_field_names()`. try: # test if the model has an 'entity' field FormKlass._meta.model._meta.get_field('entity') # autofill the 'entity' field kwargs['entity'] = related_pk except: # no 'entity' field pass initial = copy(kwargs) initial[related_type] = related_pk if 'ctnr' in FormKlass.base_fields: initial['ctnr'] = request.session['ctnr'] form = FormKlass(initial=initial) if 'ctnr' in FormKlass.base_fields and \ request.session['ctnr'].name != 'global': form.fields['ctnr'].widget = forms.HiddenInput() if related_type == 'range' and not obj_type.endswith('_av'): for field in ['vrf', 'site', 'next_ip']: form.fields[field].widget = forms.HiddenInput() form.fields['ip_str'].widget.attrs['readonly'] = True form.fields['ip_type'].widget.attrs['readonly'] = True ip_type = form.fields['ip_type'].initial form.fields['ip_type'].choices = [ (str(ip_type), "IPv{0}".format(ip_type))] if FormKlass.__name__ == 'RangeForm': Network = get_model('cyder', 'network') network = Network.objects.get(id=related_pk) network_str = network.network_str.split('/') initial = '.'.join( network_str[0].split('.')[:int(network_str[1])/8]) if int(network_str[1]) < 32: initial += '.' form = FormKlass(initial=dict( {'start_str': initial, 'end_str': initial, related_type: related_pk}.items() + kwargs.items())) else: form = FormKlass(initial=kwargs) except ObjectDoesNotExist: raise Http404 if related_type in form.fields: RelatedKlass, _ = get_klasses(related_type) form.fields[related_type] = ModelChoiceField( widget=HiddenInput, empty_label=None, queryset=RelatedKlass.objects.filter(pk=int(related_pk))) if isinstance(form, UsabilityFormMixin): form.make_usable(request) return HttpResponse( json.dumps({ 'form': form.as_p(), 'form_title': form_title, 'submit_btn_label': submit_btn_label, 'pk': record_pk }))