Пример #1
0
def passwd_change(request):
    if request.method == "GET":
        return render_to_response("wenix_auth/passwd_change.django.html", {"form": UserPassChange()})
    else:   #request.method == "POST":
        data_str = request.POST.get("data", "")
        try:
            data = json.loads(data_str)
        except: # Damn... returng BadRequest
            #print "Error during data deserialization"
            return HttpResponseBadRequest()
        else:   # Great Success!
            form = UserPassChange(data)
            if form.is_valid():
                user = request.user
                user.set_password(data["password"])
                user.save()
                WenixUser.objects.on_edit(user, data)
                return HttpResponse(json.dumps({"ok": 1, "message": _("Your password has been changed")}), mimetype="application/json")
            else:
                return HttpResponse(json.dumps({"ok": 0, "errors": get_errors(form, data)}), mimetype="application/json")
Пример #2
0
def record(request, mode, zone_name, action):
   
    data = json.loads(request.REQUEST.get('data', "{}"))
    
    form = BindForm.get_form(zone_name)
    if form is None:
        # add operation for a slave zone requested
        return HttpResponseBadRequest()
    
    if request.method == 'GET':
        # requesting the form
        if action == "add":
            return render_to_response("bind/add_form_rr_%s.django.html" % form.TYPE,
                                     {"form": form(), "zone_name": zone_name})
        elif action == "edit":
            # requesting the form
            record_name = request.GET.get('rrkey', None)
            rrtype = request.GET.get('rrtype', None)
            
            bind_daemon = Bind()
            zone_config = bind_daemon.zone_config(zone_name)
            records = zone_config.config.names[record_name].records(rrtype).get_items()
            
            return render_to_response("bind/edit_form_rr.django.html",
                                     {
                                        "records": records,
                                        "type": rrtype,
                                        "record": record_name,
                                        "zone_name": zone_name})
        else:
            if action != "delete":
                # delete actions are GET requests
                return HttpResponseBadRequest()
        
    if form.TYPE == BindForm.ZONE_STRAIGHT or form.TYPE == BindForm.ZONE_REVERSE:
        if action == "add":
            data["zone_name"] = zone_name
            
            # submitting the form
            form = form(data)
            if not form.is_valid():
                return HttpResponse(json.dumps({"ok": 0, "errors": get_errors(form, data)}), mimetype="application/json")
            
            bind_daemon = Bind()
            
            # making shortcuts for key data
            rrkey = form.cleaned_data['rrkey']          # name
            rrtype = form.cleaned_data['rrtype']        # type
            rrvalue = form.cleaned_data['rrvalue']      # resolve
            
            zone_config = bind_daemon.zone_config(zone_name)
            zone_config.config.add_name(rrkey)
            zone_config.config.names[rrkey].records(rrtype, create=True).add(str(rrvalue))
            zone_config.config.save(autoserial=True)
            
            # Checking whether we need to create a reversed record for straight A-records
            if data["rrtype"] == "A" and request.POST.get('create_reversed', False):
                reverse_form = BindReverse({"rrvalue": rrkey,
                                            "rrkey": rrvalue,
                                            "zone_name": "in-addr.arpa"})
                if reverse_form.is_valid():
                    rrkey = reverse_form.cleaned_data['rrkey']
                    rrvalue = reverse_form.cleaned_data['rrvalue']
                    rrtype = form.cleaned_data['rrtype']
                    zone_name_reverse = bind_daemon.get_zone_name_by_ip(rrvalue)
                    
                    zone_config = bind_daemon.zone_config(zone_name_reverse)
                    zone_config.config.add_name(rrkey)
                    zone_config.config.names[rrkey].records(rrtypem,create=True).add(str(rrvalue))
                    zone_zonfig.config.save(autoserial=True)
                else:
                    # Automatic PTR writing has failed
                    log(2, "bind_app - record add", \
                    "Failed to write a reverse record. Data are: name='%s',resolve='%s'" % (rrkey, rrvalue))
            
            return HttpResponse(json.dumps({"ok": 1, "errors": ""}), mimetype="application/json")
        
        data["rrkey"] = request.REQUEST.get('rrkey', None)
        data["rrtype"] = request.REQUEST.get('rrtype', None)
            
        if action == "edit":
            _data = {'rrtype': data['rrtype'],
                     'rrkey': data['rrkey'],
                     'zone_name': zone_name}
            
            errors = {}
            clean_data = []
            for rrvalue_key in data:
                re_index = re.search("rrvalue_(\d+)", rrvalue_key)
                if not re_index:
                    continue
                
                index = re_index.group(1)
                _data["rrvalue"] = data[rrvalue_key]
                _data['priority'] = data.get("priority_%s" % index, None)
            
                _form = form(_data)
                if _form.is_valid():
                    clean_data.append(_form.cleaned_data["rrvalue"])
                else:
                    _errors = get_errors(_form, _data)
                    for e in _errors:
                        errors["%s_%s" % (e, index)] = _errors[e]
            
            if errors:
                return HttpResponse(json.dumps({"ok": 0, "errors": errors}), mimetype="application/json")
            
            if len(clean_data) != 0:
                bind_daemon = Bind()
                zone_config = bind_daemon.zone_config(zone_name)
                records = zone_config.config.names[data['rrkey']].records(data['rrtype'])
                for item in records.get_items():
                    records.delete(item)
                
                for rrvalue in clean_data:
                    records.add(str(rrvalue))
                
                zone_config.config.save(autoserial=True)
                error = _("The zone '%(zone_name)s' has been changed") % {"zone_name": zone_name}
                    
                return HttpResponse(json.dumps({"ok": 1, "error": error}),
                                    mimetype="application/json")
            else:
                # data is empty. meaning delete the record
                errors = {"general": _("At least on value is required for the record '%(rrkey)s'") % {"rrkey": data['rrkey']}}
                return HttpResponse(json.dumps({"ok": 0, "errors": errors}),
                                    mimetype="application/json")
        
        if action == "delete":
            
            if request.GET.get("flag", None) == "info":
                msg = _('Are you sure you want to delete the %(type)s-record "%(name)s"?' % {"name": data["rrkey"],"type": data["rrtype"]})
                return HttpResponse(json.dumps({"confirm": msg}), mimetype="application/json")
            
            bind_daemon = Bind()
            zone_config = bind_daemon.zone_config(zone_name)
            names = zone_config.config.get_names()
            if data["rrkey"] in names:
                zone_config.config.delete_name(data["rrkey"])
            
            zone_config.config.save(autoserial=True)
          
            return HttpResponse(json.dumps({"ok": 1,
                                            "error": _("The zone '%(zone_name)s' has been changed") % {"zone_name": zone_name}}),
                                mimetype="application/json")
    elif form.TYPE == BindForm.FORWARD or form.TYPE == BindForm.HINT:
        # submitting the form
        
        if action == "add":
            form = form(data)
            if not form.is_valid():
                return HttpResponse(json.dumps({"ok": 0, "errors": get_errors(form, data)}), mimetype="application/json")
 
            
            # making shortcuts for key data
            ipaddress = form.cleaned_data['ipaddress']
            priority = int(form.cleaned_data['priority'])
            
            bind_daemon = Bind()
            named_zone = bind_daemon.get_zone(zone_name)
            forwarders = named_zone.get("forwarders", SortedDict())
            
            # sorting the forwarders according to the priority
            i = 0
            for forwarder in forwarders:
                i += 1
                forwarders[forwarder] = i
            
            forwarders[ipaddress] = priority - 0.5
            
            new_forwarders = SortedDict(sorted(forwarders.items(), key=lambda x:x[1]))
            
            # transforming to an appropriate format
            for forwarder in new_forwarders:
                new_forwarders[forwarder] = True
            
            named_zone["forwarders"] = new_forwarders
            bind_daemon.set_zone(zone_name, named_zone)
            bind_daemon.config.save()
            return HttpResponse(json.dumps({"ok": 1, "errors": ""}), mimetype="application/json")
        elif action == "type":
            # Changing zone type
            
            bind_daemon = Bind()
            named_zone = bind_daemon.get_zone(zone_name)
            
            if data["zone_type"] == "hint":
                named_zone["type"] = "hint"
                named_zone["file"] = BindConfig.ROOT_ZONE_PATH
                if "forwarders" in named_zone:
                    del named_zone["forwarders"]
                    
                if "forward" in named_zone:
                    del named_zone["forward"]
            elif data["zone_type"] == "forward":
                # type == "forward"
                if "file" in named_zone:
                    del named_zone["file"]
                
                named_zone["type"] = "forward"
                named_zone["forward"] = "only"
                if not "forwarders" in named_zone:
                    named_zone["forwarders"] = {}
            else:
                return HttpResponse(json.dumps({"ok": 1, "errors": _("Not implemented")}), mimetype="application/json")
            
            bind_daemon.set_zone(zone_name, named_zone)
            bind_daemon.config.save()
            return HttpResponse(json.dumps({"ok": 1, "errors": ""}), mimetype="application/json")
        elif action == "delete":
            if request.GET.get("flag", None) == "info":
                msg = _('Are you sure you want to delete the forward server "%(name)s"?' % {"name": request.REQUEST.get("rrkey", "")})
                return HttpResponse(json.dumps({"confirm": msg}), mimetype="application/json")
            
            bind_daemon = Bind()
            named_zone = bind_daemon.get_zone(zone_name)
            forwarders = named_zone.get("forwarders", SortedDict())
            forwarder = request.REQUEST.get('rrkey', None)
            if forwarder in forwarders:
                del forwarders[forwarder]
            
            named_zone["forwarders"] = forwarders
            bind_daemon.set_zone(zone_name, named_zone)
            bind_daemon.config.save()
            
            return HttpResponse(json.dumps({"ok": 1,
                                            "error": _("The zone '%(zone_name)s' has been changed") % {"zone_name": zone_name}}),
                                mimetype="application/json")
    else:
        # unrecognized request
        return HttpResponseBadRequest()

    
    #bind_daemon = Bind()
    #zone_config = bind_daemon.zone_config(zone_name)
    #include_file = bind_daemon.check_includefile(ZONE_INCLUDE_FILE % zone_name)
    
    """
Пример #3
0
def manage(request, mode, action):
    data_str = request.POST.get("data", None)
    formset_id = request.COOKIES.get("formset_id", None)
    instance_id = request.POST.get("id",  request.GET.get("id", None))
    data = None
    
    # If in the "edit" mode, account_obj contains either a user or a group object
    # Otherwise the object is None
    account_obj = None
    """
    If data is send, write this data in cache and follow the following steps
    accordingly. Otherwise, if it's a step back return the cached data. In any
    other case it should be the first request in a formset, so return an empty
    form.
    """
    if data_str:
        # The user is submitting the form. Trying to deserialize data first.
        try:
            data = json.loads(data_str)
        except: # Damn... returng a bad request error
            log(6, "accounts_app - account add", "Failed to serialize data string: %s" % data_str)
            return HttpResponseBadRequest()
    
    # Let's dig out the previously recorded data from the cache.
    formset = cache.get(formset_id)
    
    # If the request uses POST method, apperently the user is submiting the form
    if request.method == "POST":
        if formset:
            step = formset["step"]
            object = formset["object"]
            
            # Fetching an object from the DB
            if instance_id and action == "edit":
                if object == "user":
                    class_obj = WenixUser
                else:
                    class_obj = WenixGroup
                
                account_obj = class_obj.objects.get(pk=instance_id)
            
            if data:
                # Get the form and check wether the submitted data valid or not.
                form = get_form(object.title(), action, step)(data)
                if not form.is_valid():
                    print data
                    print form
                    return HttpResponse(json.dumps({"ok": 0,"errors": get_errors(form, data)}),
                                        mimetype="application/json")
                
                # Update formset. All data in the following lines could be reached
                # only with the formset.
                formset["data"].update(data)
                
                """
                If it's the last step in a formset we don't need to return the next
                step, but rather we return the result of the user/group creation.
                """
                if object == "user" and step == 3:
                    u_perm_obj = Permission(formset["data"]["permissions"])
                    perm_obj = Permission(request.user.merged_permissions())
                    groups = WenixGroup.objects.in_bulk(formset["data"]["groups"]).values()
                    
                    g_perm_obj = Permission()
                    for group in groups:
                        g_perm_obj.merge(group.permissions)
                    
                    if u_perm_obj >= g_perm_obj and u_perm_obj <= perm_obj:
                        """
                        Priviliges check has passed. We have nothing to do but to
                        create or change the user.
                        We don't want redundancy, therefore the common attributes
                        will be fetched here.
                        """
                        # User permissions first
                        permissions = u_perm_obj.dissect(g_perm_obj.permissions)
                        if action == "add":
                            new_user = WenixUser.objects.create(username=formset["data"]["username"])
                            
                            # Saving general information about the user
                            for key in ("first_name", "last_name", "email", "permissions"):
                                setattr(new_user, key, formset["data"][key])
                            
                            # Changing the user's membership
                            new_user.groups = groups
                            
                            # We need to store a clean user password in order for
                            # other modules to be aware of it
                            new_user.password = formset["data"]["password"]
                            
                            # Invoking a method to notify all modules about the new user
                            WenixUser.objects.on_create(new_user)
                            
                            # Setting crypted password and saving the user
                            new_user.set_password(formset["data"]['password'])
                            new_user.save()
                            
                            message = _("A new user '%(username)s' has been created") % {"username": new_user.username}
                        else: # action == "edit"
                            account_obj.save()
                            
                            # Saving general information about the user
                            for key in ("first_name", "last_name", "email", "permissions"):
                                setattr(account_obj, key, formset["data"][key])
                            
                            # Resetting the user's password if needed
                            if formset["data"]['password']:
                                account_obj.set_password(formset["data"]['password'])
                            
                            # Changing the user's membership
                            account_obj.groups = groups
                            account_obj.save()
                            
                            # Invoking a method to notify all modules about the change
                            WenixUser.objects.on_edit(account_obj, formset["data"])
                            
                            message = _("The user '%(username)s' has been changed") % {"username": account_obj.username}
                            
                        response = HttpResponse(json.dumps({"ok": 1,"message": message}))
                        response.delete_cookie("formset_id")
                        return response
                    else:
                        """
                        It turns out as if the user created another user with higher
                        priviliges. That breaks the rules, therefore access should be
                        denied.
                        """
                        log(5, "accounts_app - account add", "Permission denied for user '%s' creating another user" % request.user.username)
                        return HttpResponse(json.dumps({"ok": 1, "message": _("Access denied")}))
                
                elif object == "group" and step == 2:
                    g_perm_obj = Permission(formset["data"]["permissions"])
                    perm_obj = Permission(request.user.merged_permissions())
                    
                    if g_perm_obj <= perm_obj:
                        
                        # Fetching users to be included in the group
                        users = WenixUser.objects.in_bulk(formset["data"]["users"] or []).values()
                        
                        """
                        Priviliges check has passed. We have nothing to do but to
                        create or change the group.
                        """
                        if action == "add":
                            # We are going to create a new group.
                            group = WenixGroup.objects.create(name=formset["data"]["name"],
                                                              permissions=g_perm_obj.permissions)
                            
                            # The new members of the group should have their priviliges updated
                            [user.groups.add(group) for user in users]
                            WenixGroup.objects.on_create(group)
                            message = _("A new group '%(name)s' has been created") % {"name": formset["data"]["name"]}
                        else: # action == "edit"
                            # We are going to change a group.
                            group = account_obj
                            
                            # Reseting users's permissions so they can form again
                            # At the same time if a user was in the MultipleChoice
                            # field remove his membership from the group
                            choice_ids = dict(id_and_name_to_dict(request.user, mode, "user")).keys()
                            old_group_users = WenixUser.objects.filter(groups__name=group.name)
                            for u in old_group_users:
                                #cache.delete(CACHE_KEY_UGRPERM % u.username)
                                #cache.delete(CACHE_KEY_USERPERM % u.username)
                                if str(u.id) in choice_ids:
                                    u.groups.remove(group)
                            
                            # Contructing a new dictionary with old_dat to pass with "on_edit" method
                            old_data = {"permissions": group.permissions,
                                        "users": old_group_users}
                            
                            group.permissions = g_perm_obj.permissions
                            group.save()
                            
                            # We're going to add users to the group
                            for user in users:
                                user.groups.add(group)
                                #if not user in old_group_users:
                                #    cache.delete(CACHE_KEY_UGRPERM % user.username)
                                #    cache.delete(CACHE_KEY_USERPERM % user.username)
                            
                            # On edit method has three arguments: user, object_being_changed and new_data
                            WenixGroup.objects.on_edit(request.user, group, old_data)
                            message = _("The priviliges for the group '%(name)s' have been saved") % {"name": group.name}
                        
                        response = HttpResponse(json.dumps({"ok": 1,"message": message}))
                        response.delete_cookie("formset_id")
                        return response
                    else:
                        """
                        It turns out as if the user created another group with higher
                        priviliges. That breaks the rules, therefore access should be
                        denied.
                        """
                        log(6, "accounts_app - account add", "Permission denied for user '%s' creating another group" % request.user.username)
                        return HttpResponse(json.dumps({"ok": 1,"message": _("Access denied")}))
                
                formset["step"] += 1
            else:
                if formset["step"] > 1:
                    formset["step"] -= 1
                else:
                    formset["step"] = 1
            
            step = formset["step"]
            form = get_form(object.title(), action, step)
            
            # Generating the next form according to the step
            if object == "user":
                if step == 1:
                    new_form = form(initial=formset["data"])
                elif step == 2:
                    """
                    We need to initialize group list here. At the same time we can't
                    list groups the user is not a memeber of if she's in the "group"
                    mode. That's why we use "id_and_name_to_dict" function to generate
                    the list.
                    """
                    new_form = form(initial=formset['data'])
                    new_form["groups"].field.choices = id_and_name_to_dict(request.user, mode, "group")
                elif step == 3:
                    # Generating permissions
                    groups = WenixGroup.objects.in_bulk(data["groups"])
                    perm_obj = Permission(request.user.merged_permissions())
                    g_perm_obj = Permission()
                    for g in groups:
                        g_perm_obj.merge(groups[g].permissions)
                    
                    if action == "add":
                        new_form = {"permissions": perm_obj.render(g_perm_obj.permissions)}
                    else: # action == "edit"
                        u_perm_obj = Permission(account_obj.permissions)
                        u_perm_obj.merge(g_perm_obj.permissions)
                        new_form = {"permissions": perm_obj.render(g_perm_obj.permissions, u_perm_obj.permissions)}
                else:
                    # Unrecognised step
                    log(6, "accounts_app - account add", "Unknown step: %s" % step)
                    return HttpResponseBadRequest()
            
            elif object == "group":
                if step == 1:
                    new_form = form(initial=formset["data"])
                    new_form["users"].field.choices = id_and_name_to_dict(request.user, mode, "user")
                elif step == 2:
                    # Generating permissions
                    perm_obj = Permission(request.user.merged_permissions())
                    
                    if action == "add":
                        new_form = {"permissions": perm_obj.render()}
                    else: # action == "edit"
                        g_perm_obj = Permission(WenixGroup.objects.get(pk=instance_id).permissions)
                        new_form = {"permissions": perm_obj.render({}, g_perm_obj.permissions)}
                else:
                    # Unrecognised step
                    log(6, "accounts_app - account add", "Unknown step: %s" % step)
                    return HttpResponseBadRequest()
                
            template = get_template(TEMPLATE_FORM_PATH % object)
            cache.set(formset_id, formset)
            context = Context({"form": new_form, "step": formset["step"], "action": action, "object": account_obj})
            return HttpResponse(json.dumps({"ok": 1, "html": template.render(context)}),
                                mimetype="application/json")
    
    # No formset is found. Therefore, we conclude this is the first step.
    object = request.POST.get("object", request.GET.get("object", ""))
    if not object in ("user", "group"):
        log(3, "accounts_app - account add", "An alien object type '%s' has been spotted" % object)
        return HttpResponseBadRequest()
    
    # Create a new formset
    cache.delete(formset_id)
    formset_id = gen_formset_id(CACHE_FORMSET[action], object)
    form_obj = get_form(object, action, 1)
    
    if action == "add":
        data = {}
        form = form_obj()
    else: # action == "edit"
        if object == "user":
            account_obj = WenixUser.objects.get(pk=instance_id)
            data = {"groups": map(lambda x: str(int(x)), account_obj.groups.all().values_list("id", flat=True))}
            form = form_obj(instance=account_obj)
        else: # object == "group"
            account_obj = WenixGroup.objects.get(pk=instance_id)
            data = {"users": map(lambda x: str(int(x)), WenixUser.objects.filter(groups__name=account_obj.name).values_list("id", flat=True))}
            form = form_obj(initial=data)
    
    # An ugly way to initialize users list
    if object == "group":
        form["users"].field.choices = id_and_name_to_dict(request.user, mode, "user")
    
    cache.set(formset_id, {"object": object, "step": 1, "data": data})
    response = render_to_response(TEMPLATE_FORM_PATH % object, {"form": form, "step": 1, "action": action, "object": account_obj})
    response.set_cookie("formset_id", formset_id, FORMSET_ID_MAXAGE)
    return response
Пример #4
0
def hosts_edit(request, mode):
    action = request.REQUEST.get("action", None)
    
    if request.method == 'GET':
        if action == "add":
            return render_to_response("vmware/host_form.django.html",
                                     {"form": VMwareHostForm(),
                                      "action": "add"})
        elif action == "edit":
            host = request.GET.get("host", None)
            if host is None:
                return HttpResponseBadRequest()
            
            try:
                account = VMWareAccounts.objects.get(host=host)
            except:
                return HttpResponseBadRequest()
            else:
                account.password = ""
                return render_to_response("vmware/host_form.django.html",
                                          {"form": VMwareHostForm(instance=account),
                                           "instance": account,
                                           "action": "edit"})
        elif action == "delete":
            if request.GET.get("flag", "") == "info":
                msg = _('Are you sure you want to delete the host "%s"?' % request.GET.get("host", ""))
                return HttpResponse(json.dumps({"confirm": msg}), mimetype="application/json")
            else:
                hostname = request.GET.get("host", "")
                try:
                    account = VMWareAccounts.objects.get(host=hostname)
                except VMWareAccounts.DoesNotExist:
                    return HttpResponse(json.dumps({"ok": 1,
                                                    "message": _("Host '%s' does not exist" % hostname)}),
                                        mimetype="application/json")
                else:
                    account.delete()
                    return HttpResponse(json.dumps({"ok": 1,
                                                "message": _("Host '%s' has been deleted." % hostname)}),
                                        mimetype="application/json")
    else: # POST
        data = json.loads(request.POST.get("data", "{}"))
        
        try:
            account = VMWareAccounts.objects.get(pk=int(request.POST.get("id", 0)))
        except VMWareAccounts.DoesNotExist:
            account = None
        
        form = VMwareHostForm(data, instance=account)
        if form.is_valid():
            if action == "add":
                VMWareAccounts.objects.create(host=form.cleaned_data["host"],
                                              username=form.cleaned_data["username"],
                                              password=form.cleaned_data["password"])
            elif action == "edit":
                account.host = form.cleaned_data["host"]
                account.username = form.cleaned_data["username"]
                account.password = form.cleaned_data["password"]
                account.save()
            else:
                return HttpResponse(json.dumps({"ok": 0,
                                                "message": _("Unknown action '%s'" % action)}),
                                        mimetype="application/json")
            
            return HttpResponse(json.dumps({"ok": 1,
                                            "message": _("Host '%s' has been saved" % form.cleaned_data["host"])}),
                                        mimetype="application/json")
        else:
            return HttpResponse(json.dumps({"ok": 0,
                                            "errors": get_errors(form, data)}),
                                mimetype="application/json")
    
    return HttpResponse(json.dumps({"ok": 1,
                                    "message": _("Unrecognized request")}),
                                mimetype="application/json")
Пример #5
0
def links_edit(request, mode):
    action = request.REQUEST.get("action", None)
    
    if request.method == 'GET':
        if action == "add":
            return render_to_response("external/link_form.django.html",
                                     {"form": LinksForm(),
                                      "action": "add"})
        elif action == "edit":
            link_id = request.GET.get("link_id", None)
            if link_id is None:
                return HttpResponseBadRequest()
            
            try:
                instance = Links.objects.get(pk=link_id)
            except:
                return HttpResponseBadRequest()
            else:
                return render_to_response("external/link_form.django.html",
                                          {"form": LinksForm(instance=instance),
                                           "instance": instance,
                                           "action": "edit"})
        elif action == "delete":
            if request.GET.get("flag", "") == "info":
                try:
                    title = Links.objects.get(pk=int(request.GET.get("link_id", 0))).title
                except Links.DoesNotExist:
                    return HttpResponseBadRequest()
                
                msg = _('Are you sure you want to delete this link "%s"?' % title)
                return HttpResponse(json.dumps({"confirm": msg}), mimetype="application/json")
            else:
                link_id = request.GET.get("link_id", "")
                try:
                    link = Links.objects.get(pk=link_id)
                except Links.DoesNotExist:
                    return HttpResponse(json.dumps({"ok": 1,
                                                    "message": _("Link '%s' does not exist" % link.title)}),
                                        mimetype="application/json")
                else:
                    link.delete()
                    return HttpResponse(json.dumps({"ok": 1,
                                                "message": _("Link '%s' has been deleted." % link.title)}),
                                        mimetype="application/json")
        elif action == "order":
            order = json.loads(request.GET.get("order", "{}"))
            for link_id in order:
                try:
                    link = Links.objects.get(pk=link_id)
                except Links.DoesNotExist:
                    pass
                else:
                    link.priority = order[link_id]
                    link.save()
            
            return HttpResponse(json.dumps({"ok": 1,
                                            "message": _("Link priorities have been updated")}),
                                        mimetype="application/json")
    else: # POST
        data = json.loads(request.POST.get("data", "{}"))
        
        try:
            instance = Links.objects.get(pk=int(request.POST.get("link_id", 0)))
        except Links.DoesNotExist:
            instance = None
        
        form = LinksForm(data, instance=instance)
        if form.is_valid():
            count = Links.objects.count()
            if action == "add":
                Links.objects.create(title=form.cleaned_data["title"],
                                     url=form.cleaned_data["url"],
                                     priority=(count + 1))
            elif action == "edit":
                instance.title = form.cleaned_data["title"]
                instance.url = form.cleaned_data["url"]
                instance.priority = form.cleaned_data["priority"]
                instance.save()
            else:
                return HttpResponse(json.dumps({"ok": 0,
                                                "message": _("Unknown action '%s'" % action)}),
                                        mimetype="application/json")
            
            return HttpResponse(json.dumps({"ok": 1,
                                            "message": _("Link '%s' has been saved" % form.cleaned_data["title"])}),
                                        mimetype="application/json")
        else:
            print form.errors
            return HttpResponse(json.dumps({"ok": 0,
                                            "errors": get_errors(form, data)}),
                                mimetype="application/json")
    
    return HttpResponse(json.dumps({"ok": 1,
                                    "message": _("Unrecognized request")}),
                                mimetype="application/json")