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")
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) """
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
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")
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")