1
0
mirror of https://github.com/django/django.git synced 2025-07-05 18:29:11 +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 @@
/** var add_row_level_permission = {
* @author clong init: function() {
*/ // Grab the elements well need.
//dojo.require("dojo.io.*"); add_row_level_permission.form = document.getElementById("addRLPForm");
//dojo.require("dojo.event.*"); add_row_level_permission.results_div = document.getElementById("rlpResults");
//dojo.require("dojo.lfx.*");
//dojo.require("dojo.widget.*");
//dojo.require("dojo.json");
function addButtonPressed(obj_ct, obj_id) // This is so we can fade it in later.
{ YAHOO.util.Dom.setStyle(add_row_level_permission.results_div, "opacity", 0);
return;
dojo.io.bind({ // Hijack the form.
url: "/rlp/add/"+obj_ct+"/"+obj_id+"/ajax/", YAHOO.util.Event.addListener(add_row_level_permission.form, "submit", add_row_level_permission.submit_func);
handler: addCallback, },
formNode: dojo.byId('addRLPForm')
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) failure: function(o) {
{ alert('An error has occurred');
if (type == 'error') for(var i=0; i<add_row_level_permission.form.elements.length; i++)
alert('Error when retrieving data from the server!'); add_row_level_permission.form.elements[i].disabled = false;
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();
}
} }
},
function applyButtonPressed(id) add_rlp_row: function(id, permission, hash) {
{ var emptyRow = document.getElementById('empty_editRLP');
return; var newRow = emptyRow.cloneNode(true);
strArray = id.split("/"); var form = YAHOO.util.Dom.getElementsByClassName('editRLPForm', 'form', newRow);
dojo.io.bind({ form=form[0];
url: "/rlp/change/"+id+'/ajax/', form.owner.options.selectedIndex = add_row_level_permission.form.owner.selectedIndex;
handler: editCallback, form.perm.options.selectedIndex = row_level_permission.find_in_select(form.perm, permission);
formNode: dojo.byId('editRLPForm-'+strArray[1]) form.negative.checked =add_row_level_permission.form.negative.checked;
}); form.id = "editRLPForm-"+id;
} newRow.id = "editRLP-"+id;
function editCallback(type, data, evt) var delete_link = YAHOO.util.Dom.getElementsByClassName('deleteLink', 'a', form);
{ delete_link = delete_link[0];
if (type == 'error') delete_link.href = "../../../auth/row_level_permission/"+hash+"/delete/";
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();
}
}
function deleteRLP(id) var copy_link = YAHOO.util.Dom.getElementsByClassName('copyToNewLink', 'a', newRow);
{ copy_link = copy_link[0];
return; 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?"); var confirm_ans = confirm("Are you sure?");
if(confirm_ans) if(confirm_ans)
{ var cObj = YAHOO.util.Connect.asyncRequest("POST",
dojo.io.bind({ url+"?ajax" ,
url: '/rlp/delete/'+id+'/ajax', row_level_permission.delete_callback);
handler: deleteCallback, return false;
mimetype: 'text/json' },
});
}
}
function deleteCallback(type, data, evt) delete_callback: {
success: function(o)
{ {
if (type == 'error') var response_obj = eval('(' + o.responseText + ')');
alert('Error when retrieving data from the server!'); // Set up the animation on the results div.
else var result_fade_out = null;
{ if(response_obj.result) {
dictData = dojo.json.evalJson(data); result_fade_out = row_level_permission.output_success(response_obj.text, document.getElementById("rlpResults"));
if(dictData.result == false) var row_fade_out = new YAHOO.util.Anim('editRLP-'+response_obj.id, {
{ opacity: { from:100, to: 0 }
//outputError(dictData.text); }, 1, YAHOO.util.Easing.easeOut);
dojo.lfx.html.highlight(dojo.byId("editRLP-"+dictData.id), [255, 0, 0], 1000).play(); row_fade_out.onComplete.subscribe(function() {
return; var row = document.getElementById('editRLP-'+response_obj.id);
} var table = row_level_permission.edit_table;
outputMessage(dictData.text); table.removeChild(row);
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);
}); });
dojo.lfx.html.highlight(row, [255, 0, 0], 500).play(1500); row_fade_out.animate();
fadeOut.play(); } else {
result_fade_out = row_level_permission.output_errort(response_obj.text,
row_level_permission.results_div);
} }
} result_fade_out.animate();
},
function copyToNew(id) failure: function(o)
{ {
var newForm = document.addRLPForm; alert('An error has occurred');
var form = dojo.byId("editRLPForm-"+id); }
},
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.owner.selectedIndex = form.owner.selectedIndex;
newForm.perm.selectedIndex = form.perm.selectedIndex; newForm.perm.selectedIndex = form.perm.selectedIndex;
newForm.negative.checked = form.negative.checked; 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> </form>
{% if new_rlp_form %} {% if new_rlp_form %}
<h1>{% trans "Row Level Permissions" %}</h1> <div id="row_level_perm_container">
<div>
{% include "admin/row_level_permission.html" %} {% include "admin/row_level_permission.html" %}
</div> </div>
{% endif %} {% endif %}

View File

@ -1,8 +1,38 @@
{% load i18n admin_modify %} {% load i18n admin_modify %}
{% include_admin_script "js/ajax/prototype.js" %} {% include_admin_script "js/lib/YahooUI/yahoo/yahoo-debug.js" %}
{% include_admin_script "js/ajax/scriptaculous.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" %} {% 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"> <tr class="header">
<th> <th>
{% trans "Owner" %} {% trans "Owner" %}
@ -17,12 +47,6 @@
{% trans "Options" %} {% trans "Options" %}
</th> </th>
</tr> </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> <TBODY>
<tr> <tr>
<td> <td>
@ -44,17 +68,34 @@
<input id="addButton" type="submit" value="{% trans 'Add' %}" /> <input id="addButton" type="submit" value="{% trans 'Add' %}" />
</td> </td>
</tr> </tr>
</table>
</form> </form>
<tr>
<th colspan=4> <h2>{% trans "Current Permissions" %}</h2>
{% trans "Current Permissions" %} <table id="current-rlpTable">
<tr class="header">
<th>
{% trans "Owner" %}
</th>
<th>
{% trans "Permission" %}
</th>
<th>
{% trans "Negative" %}
</th>
<th>
{% trans "Options" %}
</th> </th>
</tr> </tr>
<TBODY>
{% if rlp_form_list %} {% if rlp_form_list %}
{% load row_level_permission %} {% load row_level_permission %}
{% for o in rlp_form_list %} {% for o in rlp_form_list %}
<tr id="editRLP-{{ o.rlp.id }}"> <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> <td>
{{ o.form.owner }} {{ o.form.owner }}
</td> </td>
@ -68,10 +109,14 @@
<input id="applyButton-{{ o.rlp.id }}" type="submit" value="{% trans 'Apply' %}" /> <input id="applyButton-{{ o.rlp.id }}" type="submit" value="{% trans 'Apply' %}" />
<input id="cancelButton-{{ o.rlp.id }}" type="reset" value="{% trans 'Reset' %}"/> <input id="cancelButton-{{ o.rlp.id }}" type="reset" value="{% trans 'Reset' %}"/>
<br/> <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="../../../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="" 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">{% trans 'Delete' %}</a> |
<a href="javascript:row_level_permission.copyToNew({{ o.rlp.id }})" class="copyToNewLink">{% trans 'Copy to New' %}</a>
</td> </td>
</tr>
</table>
</form> </form>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
{% else %} {% else %}
@ -79,3 +124,32 @@
{% endif %} {% endif %}
</TBODY> </TBODY>
</table> </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 #Based off work by Ian Holsman
#http://svn.zyons.python-hosting.com/trunk/zilbo/common/utils/misc.py #http://svn.zyons.python-hosting.com/trunk/zilbo/common/utils/misc.py
def verify_objref_hash( content_type_id, object_id, hash ):
import sha import sha
from django.conf import settings 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() hash_match = sha.new("%s/%s" % (content_type_id, object_id) + settings.SECRET_KEY).hexdigest()
if hash == hash_match: if hash == hash_match:
return True return True
else: else:
return False 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) add_rlp_manip = AddRLPManipulator(model_instance, model_ct)
edit_rlp_manip = ChangeRLPManipulator(model_ct) edit_rlp_manip = ChangeRLPManipulator(model_ct)
new_rlp_form = forms.FormWrapper(add_rlp_manip, rlp_new_data, rlp_errors) 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 = [] rlp_form_list = []
for r in rlp_list: for r in rlp_list:
owner_val = str(r.owner_ct)+"-"+str(r.owner_id) owner_val = str(r.owner_ct)+"-"+str(r.owner_id)
data = {'id':r.id, 'owner':owner_val, 'perm':r.permission.id, 'negative':r.negative} 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_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) c.update(rlp_context)
return render_change_form(model, manipulator, c, change=True) 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) ct = get_object_or_404(ContentType, pk=ct_id)
obj = get_object_or_404(ct.model_class(), pk=obj_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()): if not request.user.has_perm(obj._meta.app_label + '.' + obj._meta.get_change_permission()):
raise PermissionDenied raise PermissionDenied
@ -51,6 +50,7 @@ def add_row_level_permission(request, ct_id, obj_id):
manip = AddRLPManipulator(obj, ct) manip = AddRLPManipulator(obj, ct)
new_data = request.POST.copy() new_data = request.POST.copy()
manip.do_html2python(new_data) manip.do_html2python(new_data)
rlp_list = [] rlp_list = []
@ -71,7 +71,8 @@ def add_row_level_permission(request, ct_id, obj_id):
resp_list = [] resp_list = []
for rlp in rlp_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 msg["results"]=resp_list
return HttpResponse(simplejson.dumps(msg), 'text/javascript') return HttpResponse(simplejson.dumps(msg), 'text/javascript')