1
0
mirror of https://github.com/django/django.git synced 2025-07-05 10:19:20 +00:00

[per-object-permissions] AJAX interface is now working most of the time. A fair amount of work has to be done still and some tidying up of the interface. Uses YUI toolkit. Currently comes w/ the full toolkit, once debugged and working will keep only the needed js files.

git-svn-id: http://code.djangoproject.com/svn/django/branches/per-object-permissions@3540 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Christopher Long 2006-08-09 01:22:35 +00:00
parent 759f426f24
commit 2176184dc3
6 changed files with 359 additions and 191 deletions

View File

@ -1,160 +1,245 @@
/**
* @author clong
*/
//dojo.require("dojo.io.*");
//dojo.require("dojo.event.*");
//dojo.require("dojo.lfx.*");
//dojo.require("dojo.widget.*");
//dojo.require("dojo.json");
var add_row_level_permission = {
init: function() {
// Grab the elements well need.
add_row_level_permission.form = document.getElementById("addRLPForm");
add_row_level_permission.results_div = document.getElementById("rlpResults");
function addButtonPressed(obj_ct, obj_id)
{
return;
dojo.io.bind({
url: "/rlp/add/"+obj_ct+"/"+obj_id+"/ajax/",
handler: addCallback,
formNode: dojo.byId('addRLPForm')
// This is so we can fade it in later.
YAHOO.util.Dom.setStyle(add_row_level_permission.results_div, "opacity", 0);
// Hijack the form.
YAHOO.util.Event.addListener(add_row_level_permission.form, "submit", add_row_level_permission.submit_func);
},
submit_func: function(e) {
YAHOO.util.Event.preventDefault(e);
//TODO: Remove any error messages here
YAHOO.util.Connect.setForm(add_row_level_permission.form);
//Temporarily disable the form.
for(var i=0; i<add_row_level_permission.form.elements.length; i++) {
add_row_level_permission.form.elements[i].disabled = true;
}
var cObj = YAHOO.util.Connect.asyncRequest("POST",
add_row_level_permission.form.action+"?ajax" ,
add_row_level_permission.ajax_callback);
},
ajax_callback: {
success: function(o) {
var response_obj = eval('(' + o.responseText + ')');
// Set up the animation on the results div.
var result_fade_out = null;
if(response_obj.result) {
result_fade_out = row_level_permission.output_success(response_obj.text, add_row_level_permission.results_div);
var results=response_obj.results
var new_rows = [];
var table = row_level_permission.edit_table;
for(var i=0; i<results.length; i++) {
row = add_row_level_permission.add_rlp_row(results[i].id, results[i].permission, results[i].hash);
var row_fade_in = new YAHOO.util.Anim(row, {
opacity: { from: 0, to: 100 }
}, 1, YAHOO.util.Easing.easeOut);
row_fade_in.onStart.subscribe(function() {
table.appendChild(row);
});
row_fade_in.animate();
}
} else {
result_fade_out = row_level_permission.output_error(response_obj.text,
add_row_level_permission.results_div);
}
for(var i=0; i<add_row_level_permission.form.elements.length; i++)
add_row_level_permission.form.elements[i].disabled = false;
result_fade_out.animate();
},
function addCallback(type, data, evt)
{
if (type == 'error')
alert('Error when retrieving data from the server!');
else
{
dictData = dojo.json.evalJson(data);
if(dictData.result == false)
{
//outputError(dictData.text);
return;
}
alert("Success!");
//outputMsg(dictData.text);
//dojo.lfx.html.highlight(dojo.byId("editRLP-"+dictData.id), [184, 204, 228], 1000).play();
}
failure: function(o) {
alert('An error has occurred');
for(var i=0; i<add_row_level_permission.form.elements.length; i++)
add_row_level_permission.form.elements[i].disabled = false;
}
},
function applyButtonPressed(id)
{
return;
strArray = id.split("/");
dojo.io.bind({
url: "/rlp/change/"+id+'/ajax/',
handler: editCallback,
formNode: dojo.byId('editRLPForm-'+strArray[1])
});
}
add_rlp_row: function(id, permission, hash) {
var emptyRow = document.getElementById('empty_editRLP');
var newRow = emptyRow.cloneNode(true);
var form = YAHOO.util.Dom.getElementsByClassName('editRLPForm', 'form', newRow);
form=form[0];
form.owner.options.selectedIndex = add_row_level_permission.form.owner.selectedIndex;
form.perm.options.selectedIndex = row_level_permission.find_in_select(form.perm, permission);
form.negative.checked =add_row_level_permission.form.negative.checked;
form.id = "editRLPForm-"+id;
newRow.id = "editRLP-"+id;
function editCallback(type, data, evt)
{
if (type == 'error')
alert('Error when retrieving data from the server!');
else
{
dictData = dojo.json.evalJson(data);
if(dictData.result == false)
{
outputError(dictData.text);
dojo.lfx.html.highlight(dojo.byId("editRLP-"+dictData.id), [255, 0, 0], 1000).play();
alert("Error");
return;
}
outputMessage(dictData.text);
dojo.lfx.html.highlight(dojo.byId("editRLP-"+dictData.id), [184, 204, 228], 1000).play();
}
}
var delete_link = YAHOO.util.Dom.getElementsByClassName('deleteLink', 'a', form);
delete_link = delete_link[0];
delete_link.href = "../../../auth/row_level_permission/"+hash+"/delete/";
function deleteRLP(id)
{
return;
var copy_link = YAHOO.util.Dom.getElementsByClassName('copyToNewLink', 'a', newRow);
copy_link = copy_link[0];
copy_link.href = "javascript:row_level_permission.copyToNew("+id+")";
form.action = "../../../auth/row_level_permission/"+hash+"/change/"
row_level_permission.add_delete_listener(delete_link);
row_level_permission.add_apply_listener(form);
return newRow;
},
};
var row_level_permission = {
init: function() {
row_level_permission.results_div = document.getElementById("rlpResults");
row_level_permission.edit_table = document.getElementById('current-rlpTable');
},
find_in_select: function(select,val) {
options = select.options;
for(var i=0; i<options.length; i++) {
if(options[i].value==val) {
return i
}
}
return -1;
},
add_apply_listener: function(el) {
YAHOO.util.Event.addListener(
el,
'submit',
function(e) {
YAHOO.util.Event.preventDefault(e);
row_level_permission.applyRLP(this.action, this);
}
);
},
add_delete_listener: function(el) {
YAHOO.util.Event.addListener(
el,
'click',
function(e) {
YAHOO.util.Event.preventDefault(e);
row_level_permission.deleteRLP(this.href);
}
);
},
deleteRLP: function(url) {
var confirm_ans = confirm("Are you sure?");
if(confirm_ans)
{
dojo.io.bind({
url: '/rlp/delete/'+id+'/ajax',
handler: deleteCallback,
mimetype: 'text/json'
});
}
}
var cObj = YAHOO.util.Connect.asyncRequest("POST",
url+"?ajax" ,
row_level_permission.delete_callback);
return false;
},
function deleteCallback(type, data, evt)
delete_callback: {
success: function(o)
{
if (type == 'error')
alert('Error when retrieving data from the server!');
else
{
dictData = dojo.json.evalJson(data);
if(dictData.result == false)
{
//outputError(dictData.text);
dojo.lfx.html.highlight(dojo.byId("editRLP-"+dictData.id), [255, 0, 0], 1000).play();
return;
}
outputMessage(dictData.text);
var row = dojo.byId('editRLP-'+dictData.id);
var fadeOut = dojo.lfx.fadeOut(row, 1000, null, function(n) {
var table = dojo.byId('rlpTable');
table.deleteRow(row.rowIndex);
var response_obj = eval('(' + o.responseText + ')');
// Set up the animation on the results div.
var result_fade_out = null;
if(response_obj.result) {
result_fade_out = row_level_permission.output_success(response_obj.text, document.getElementById("rlpResults"));
var row_fade_out = new YAHOO.util.Anim('editRLP-'+response_obj.id, {
opacity: { from:100, to: 0 }
}, 1, YAHOO.util.Easing.easeOut);
row_fade_out.onComplete.subscribe(function() {
var row = document.getElementById('editRLP-'+response_obj.id);
var table = row_level_permission.edit_table;
table.removeChild(row);
});
dojo.lfx.html.highlight(row, [255, 0, 0], 500).play(1500);
fadeOut.play();
row_fade_out.animate();
} else {
result_fade_out = row_level_permission.output_errort(response_obj.text,
row_level_permission.results_div);
}
}
function copyToNew(id)
result_fade_out.animate();
},
failure: function(o)
{
var newForm = document.addRLPForm;
var form = dojo.byId("editRLPForm-"+id);
alert('An error has occurred');
}
},
output_error: function(text, div){
YAHOO.util.Dom.replaceClass(div, "system-message", "errornote");
return row_level_permission.output_text(text, div);
},
output_success: function(text, div){
YAHOO.util.Dom.replaceClass(div, "errornote", "system-message");
return row_level_permission.output_text(text, div);
},
output_text: function (text, div) {
var result_fade_out = new YAHOO.util.Anim(div, {
opacity: { to: 0 }
}, 0.25, YAHOO.util.Easing.easeOut);
var success_message = document.createElement('p');
success_message.innerHTML = text;
YAHOO.util.Dom.setStyle(div, 'display', 'block');
var result_fade_in = new YAHOO.util.Anim(div, {
opacity: { to: 1 }
}, 0.25, YAHOO.util.Easing.easeIn);
result_fade_out.onComplete.subscribe(function() {
div.innerHTML = '';
div.appendChild(success_message);
result_fade_in.animate();
});
return result_fade_out;
},
applyRLP: function(url, form) {
YAHOO.util.Connect.setForm(form);
var cObj = YAHOO.util.Connect.asyncRequest("POST",
url+"?ajax" ,
row_level_permission.apply_callback);
return false;
},
apply_callback: {
success: function(o)
{
var response_obj = eval('(' + o.responseText + ')');
// Set up the animation on the results div.
var result_fade_out = null;
if(response_obj.result) {
result_fade_out = row_level_permission.output_success(response_obj.text, document.getElementById("rlpResults"));
var row_highlight_on = new YAHOO.util.ColorAnim('editRLP-'+response_obj.id, {
backgroundColor: { to: 'rgb(255, 255, 204)' }
}, 1);
var row_highlight_off = new YAHOO.util.ColorAnim('editRLP-'+response_obj.id, {
backgroundColor: { to: 'rgb(255, 255, 255)' }
}, 1);
row_highlight_on.onComplete.subscribe(function() {
row_highlight_off.animate();
});
row_highlight_on.animate();
} else {
result_fade_out = row_level_permission.output_errort(response_obj.text,
row_level_permission.results_div);
}
result_fade_out.animate();
},
failure: function(o)
{
alert('An error has occurred');
}
},
copyToNew: function (id)
{
var newForm = add_row_level_permission.form;
var form = document.getElementById("editRLPForm-"+id);
newForm.owner.selectedIndex = form.owner.selectedIndex;
newForm.perm.selectedIndex = form.perm.selectedIndex;
newForm.negative.checked = form.negative.checked;
}
function outputErrors(errs)
{
var output = genOutput('errors', errs);
dojo.lfx.html.highlight(output, [240, 0, 0], 3000).play();
}
function outputMessage(messages)
{
var output = genOutput('messages', messages);
dojo.lfx.html.highlight(output, [184, 204, 228], 3000).play();
}
function genOutput(id, str)
{
var list = document.createElement("ul");
list.id = id;
var txt = document.createTextNode(str);
var ele = document.createElement("li");
ele.appendChild(txt);
list.appendChild(ele);
var output = dojo.byId('output');
removeChildrenFromNode(output);
output.appendChild(list);
return output;
}
function removeChildrenFromNode(node)
{
while (node.hasChildNodes())
{
node.removeChild(node.firstChild);
}
}
function init()
{
for(var i=0; i<document.forms.length; i++)
{
document.forms[i].reset();
}
}
//dojo.addOnLoad(init);

View File

@ -67,8 +67,7 @@
</form>
{% if new_rlp_form %}
<h1>{% trans "Row Level Permissions" %}</h1>
<div>
<div id="row_level_perm_container">
{% include "admin/row_level_permission.html" %}
</div>
{% endif %}

View File

@ -1,8 +1,38 @@
{% load i18n admin_modify %}
{% include_admin_script "js/ajax/prototype.js" %}
{% include_admin_script "js/ajax/scriptaculous.js" %}
{% include_admin_script "js/lib/YahooUI/yahoo/yahoo-debug.js" %}
{% include_admin_script "js/lib/YahooUI/event/event-debug.js" %}
{% include_admin_script "js/lib/YahooUI/connection/connection-debug.js" %}
{% include_admin_script "js/lib/YahooUI/dom/dom-debug.js" %}
{% include_admin_script "js/lib/YahooUI/animation/animation-debug.js" %}
{% include_admin_script "js/lib/YahooUI/logger/logger-debug.js" %}
{% include_admin_script "js/row_level_permission.js" %}
<table id="rlpTable">
<link rel="stylesheet" type="text/css" href="/media/js/lib/YahooUI/logger/logger.css" />
<script type="text/javascript">
function init() {
add_row_level_permission.init();
row_level_permission.init();
forms = document.forms;
for(var i=0; i<forms.length; i++) {
forms[i].reset;
}
row_level_permission.add_delete_listener(YAHOO.util.Dom.getElementsByClassName( "deleteLink", 'a'));
row_level_permission.add_apply_listener(YAHOO.util.Dom.getElementsByClassName( "editRLPForm", 'form'));
}
YAHOO.util.Event.addListener(window, 'load', init);
</script>
<h1>{% trans "Row Level Permissions" %}</h1>
<div id="rlpResults">
</div>
<h2>{% trans "Add Permissions" %}</h2>
<form id="addRLPForm" method="POST" name="addRLPForm" action="../../../auth/row_level_permission/add/{{ content_type_id }}/{{ object_id }}/">
<table id="add-rlpTable">
<tr class="header">
<th>
{% trans "Owner" %}
@ -17,12 +47,6 @@
{% trans "Options" %}
</th>
</tr>
<form id="addRLPForm" method="POST" name="addRLPForm" action="../../../auth/row_level_permission/add/{{ content_type_id }}/{{ object_id }}/" onSubmit="addButtonPressed({{ content_type_id }}, {{ object_id }}); return false;">
<tr>
<th colspan=4>
{% trans "Add Permissions" %}
</th>
</tr>
<TBODY>
<tr>
<td>
@ -44,17 +68,34 @@
<input id="addButton" type="submit" value="{% trans 'Add' %}" />
</td>
</tr>
</table>
</form>
<tr>
<th colspan=4>
{% trans "Current Permissions" %}
<h2>{% trans "Current Permissions" %}</h2>
<table id="current-rlpTable">
<tr class="header">
<th>
{% trans "Owner" %}
</th>
<th>
{% trans "Permission" %}
</th>
<th>
{% trans "Negative" %}
</th>
<th>
{% trans "Options" %}
</th>
</tr>
<TBODY>
{% if rlp_form_list %}
{% load row_level_permission %}
{% for o in rlp_form_list %}
<tr id="editRLP-{{ o.rlp.id }}">
<form id="editRLPForm-{{ o.rlp.id }}" method="POST" name="editRLPForm-{{ rlp.id }}" action="../../../auth/row_level_permission/{% objref o.rlp %}/change/" onSubmit="applyButtonPressed('{% objref o.rlp %}'); return false;">
<td colspan="4">
<form id="editRLPForm-{{ o.rlp.id }}" class="editRLPForm" method="POST" name="editRLPForm-{{ rlp.id }}" action="../../../auth/row_level_permission/{% objref o.rlp %}/change/">
<table>
<tr>
<td>
{{ o.form.owner }}
</td>
@ -68,10 +109,14 @@
<input id="applyButton-{{ o.rlp.id }}" type="submit" value="{% trans 'Apply' %}" />
<input id="cancelButton-{{ o.rlp.id }}" type="reset" value="{% trans 'Reset' %}"/>
<br/>
<a href="../../../auth/row_level_permission/{% objref o.rlp %}/delete/" onClick="deleteRLP('{% objref o.rlp %}'); return false;" class="deleteLink">{% trans 'Delete' %}</a> |
<a href="" onClick="copyToNew({{ o.rlp.id }}); return false;" class="copyToNewLink">{% trans 'Copy to New' %}</a>
<!--<a href="../../../auth/row_level_permission/{% objref o.rlp %}/delete/" class="deleteLink" onclick="row_level_permission.deleteRLP('{% objref o.rlp %}'); return false;">{% trans 'Delete' %}</a> |-->
<a href="../../../auth/row_level_permission/{% objref o.rlp %}/delete/" class="deleteLink">{% trans 'Delete' %}</a> |
<a href="javascript:row_level_permission.copyToNew({{ o.rlp.id }})" class="copyToNewLink">{% trans 'Copy to New' %}</a>
</td>
</tr>
</table>
</form>
</td>
</tr>
{% endfor %}
{% else %}
@ -79,3 +124,32 @@
{% endif %}
</TBODY>
</table>
<table style="display: none">
<tr id="empty_editRLP">
<td colspan="4">
<form id="empty_editRLPForm" method="POST" class="editRLPForm" name="empty-editRLPForm">
<table>
<tr>
<td>
{{ empty_rlp_form.owner }}
</td>
<td>
{{ empty_rlp_form.perm }}
</td>
<td>
{{ empty_rlp_form.negative }}
</td>
<td>
<input id="applyButton" type="submit" value="{% trans 'Apply' %}" />
<input id="cancelButton" type="reset" value="{% trans 'Reset' %}"/>
<br/>
<a class="deleteLink" >{% trans 'Delete' %}</a> |
<a class="copyToNewLink">{% trans 'Copy to New' %}</a>
</td>
</tr>
</table>
</form>
</td>
</tr>
</table>

View File

@ -103,11 +103,19 @@ if docutils_is_available:
#Based off work by Ian Holsman
#http://svn.zyons.python-hosting.com/trunk/zilbo/common/utils/misc.py
def verify_objref_hash( content_type_id, object_id, hash ):
import sha
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
def verify_objref_hash( content_type_id, object_id, hash ):
hash_match = sha.new("%s/%s" % (content_type_id, object_id) + settings.SECRET_KEY).hexdigest()
if hash == hash_match:
return True
else:
return False
def create_objref(object):
content_type_id = ContentType.objects.get_for_model( object ).id
object_id = object.id
return "%s/%d/%s" % ( content_type_id, object_id, sha.new("%s/%d" % (content_type_id, object_id) + settings.SECRET_KEY).hexdigest())

View File

@ -402,12 +402,13 @@ def change_stage(request, app_label, model_name, object_id):
add_rlp_manip = AddRLPManipulator(model_instance, model_ct)
edit_rlp_manip = ChangeRLPManipulator(model_ct)
new_rlp_form = forms.FormWrapper(add_rlp_manip, rlp_new_data, rlp_errors)
empty_rlp_form = forms.FormWrapper(edit_rlp_manip, rlp_new_data, rlp_errors)
rlp_form_list = []
for r in rlp_list:
owner_val = str(r.owner_ct)+"-"+str(r.owner_id)
data = {'id':r.id, 'owner':owner_val, 'perm':r.permission.id, 'negative':r.negative}
rlp_form_list.append({'form':forms.FormWrapper(edit_rlp_manip, data, rlp_errors), 'rlp':r})
rlp_context = {'new_rlp_form':new_rlp_form, 'rlp_form_list':rlp_form_list,}
rlp_context = {'new_rlp_form':new_rlp_form, 'rlp_form_list':rlp_form_list, 'empty_rlp_form':empty_rlp_form}
c.update(rlp_context)
return render_change_form(model, manipulator, c, change=True)

View File

@ -41,7 +41,6 @@ def add_row_level_permission(request, ct_id, obj_id):
ct = get_object_or_404(ContentType, pk=ct_id)
obj = get_object_or_404(ct.model_class(), pk=obj_id)
if not request.user.has_perm(obj._meta.app_label + '.' + obj._meta.get_change_permission()):
raise PermissionDenied
@ -51,6 +50,7 @@ def add_row_level_permission(request, ct_id, obj_id):
manip = AddRLPManipulator(obj, ct)
new_data = request.POST.copy()
manip.do_html2python(new_data)
rlp_list = []
@ -71,7 +71,8 @@ def add_row_level_permission(request, ct_id, obj_id):
resp_list = []
for rlp in rlp_list:
resp_list.append({"id":rlp.id, "permission":rlp.permission.id})
hash = utils.create_objref(rlp)
resp_list.append({"id":rlp.id, "permission":rlp.permission.id, "hash":hash})
msg["results"]=resp_list
return HttpResponse(simplejson.dumps(msg), 'text/javascript')