コード例 #1
0
ファイル: tests.py プロジェクト: arnike/Wenix
 def test_dissert(self):
     objs = [
         {"accounts": {"actions": {"add": "", "delete": "", "edit": ""}}, "proftpd": {"ftp_client": {"access": "self", "type": {"write": {"access_change": ""}}}, "statistics": "self", "daemon": ""}},
         {"accounts": {"actions": {"add": "", "delete": "", "edit": ""}}},
         {"proftpd": {"ftp_client": {"access": "self", "type": {"write": {"access_change": ""}}}, "statistics": "self", "daemon": ""}},
         {"accounts": {"actions": {"add": "", "delete": "", "edit": ""}}, "proftpd": {"ftp_client": {"access": "self", "type": {"write": {"access_change": ""}}}, "statistics": "self", "daemon": ""}},
         {"proftpd": {"ftp_client": {"access": "self", "type": {"write": {"access_change": ""}}}, "statistics": "self", "daemon": ""}}
     ]
     
     dissect = [
         {"accounts": {"actions": {"add": "", "edit": ""}}, "proftpd": {"ftp_client": {"access": "self", "type": "read"}, "statistics": "self", "daemon": ""}},
         {"accounts": {"actions": {"add": ""}}, "proftpd": {"ftp_client": {"type": {"write": {"access_change": ""}}}}},
         {"proftpd": {"ftp_client": {"access": "self", "type": "read"}, "statistics": "self", "daemon": ""}},
         {"accounts": {"actions": {"add": "", "delete": "", "edit": ""}}},
         {"proftpd": {"ftp_client": {"access": "self", "type": {"write": {"access_change": ""}}}, "statistics": "self", "daemon": ""}},
     ]
     
     result = [
         {'proftpd': {'ftp_client': {'type': {"write": {"access_change": ""}}}}, 'accounts': {'actions': {'delete': ''}}},
         {"accounts": {"actions": {"delete": "", "edit": ""}}},
         {"proftpd": {"ftp_client": {"type": {"write": {"access_change": ""}}}}},
         {"proftpd": {"ftp_client": {"access": "self", "type": {"write": {"access_change": ""}}}, "statistics": "self", "daemon": ""}},
         {}
     ]
     
     i = 0
     for o in objs:
         perm_obj = Permission(o)
         perm_obj.dissect(dissect[i])
         self.assertTrue(perm_obj.permissions == result[i])
         i += 1
コード例 #2
0
ファイル: views.py プロジェクト: arnike/Wenix
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