@@ -1,7 +1,7 @@ | |||
{ | |||
"allow_copy": 0, | |||
"autoname": "PERM.#####", | |||
"creation": "2013-02-22 01:27:33.000000", | |||
"creation": "2013-02-22 01:27:33", | |||
"docstatus": 0, | |||
"doctype": "DocType", | |||
"fields": [ | |||
@@ -70,7 +70,7 @@ | |||
"description": "Only restricted users can access", | |||
"fieldname": "restricted", | |||
"fieldtype": "Check", | |||
"label": "Restricted", | |||
"label": "Only Restricted Documents", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
@@ -207,10 +207,11 @@ | |||
"idx": 1, | |||
"issingle": 0, | |||
"istable": 1, | |||
"modified": "2014-01-22 14:32:34.000000", | |||
"modified": "2014-04-30 00:31:21.598463", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "DocPerm", | |||
"owner": "Administrator", | |||
"permissions": [], | |||
"read_only": 0 | |||
} |
@@ -6,6 +6,10 @@ | |||
table.user-perm { | |||
border-collapse: collapse; | |||
width: 100%; | |||
overflow-x: scroll; | |||
-webkit-overflow-scrolling: touch; | |||
-ms-overflow-style: -ms-autohiding-scrollbar; | |||
} | |||
table.user-perm td, table.user-perm th { | |||
@@ -218,15 +218,28 @@ frappe.RoleEditor = Class.extend({ | |||
args: {role: role}, | |||
callback: function(r) { | |||
var $body = $(me.perm_dialog.body); | |||
$body.append('<table class="user-perm"><tbody><tr>\ | |||
<th style="text-align: left">Document Type</th>\ | |||
<th>Level</th>\ | |||
<th>Read</th>\ | |||
<th>Write</th>\ | |||
<th>Submit</th>\ | |||
<th>Cancel</th>\ | |||
<th>Amend</th></tr></tbody></table>'); | |||
for(var i in r.message) { | |||
// TODO fix the overflow issue and also display perms like report, import, etc. | |||
$body.append('<table class="user-perm"><thead><tr>' | |||
+ '<th style="text-align: left">' + __('Document Type') + '</th>' | |||
+ '<th>' + __('Level') + '</th>' | |||
+ '<th>' + __('Read') + '</th>' | |||
+ '<th>' + __('Only Restricted Documents') + '</th>' | |||
+ '<th>' + __('Write') + '</th>' | |||
+ '<th>' + __('Create') + '</th>' | |||
+ '<th>' + __('Delete') + '</th>' | |||
+ '<th>' + __('Submit') + '</th>' | |||
+ '<th>' + __('Cancel') + '</th>' | |||
+ '<th>' + __('Amend') + '</th>' | |||
// + '<th>' + __('Report') + '</th>' | |||
// + '<th>' + __('Import') + '</th>' | |||
// + '<th>' + __('Export') + '</th>' | |||
// + '<th>' + __('Print') + '</th>' | |||
// + '<th>' + __('Email') + '</th>' | |||
+ '<th>' + __('Can Restrict') + '</th>' | |||
+ '</tr></thead><tbody></tbody></table>'); | |||
for(var i=0, l=r.message.length; i<l; i++) { | |||
var perm = r.message[i]; | |||
// if permission -> icon | |||
@@ -244,10 +257,19 @@ frappe.RoleEditor = Class.extend({ | |||
<td style="text-align: left">%(parent)s</td>\ | |||
<td>%(permlevel)s</td>\ | |||
<td>%(read)s</td>\ | |||
<td>%(restricted)s</td>\ | |||
<td>%(write)s</td>\ | |||
<td>%(create)s</td>\ | |||
<td>%(delete)s</td>\ | |||
<td>%(submit)s</td>\ | |||
<td>%(cancel)s</td>\ | |||
<td>%(amend)s</td>\ | |||
<td>%(amend)s</td>' | |||
// + '<td>%(report)s</td>\ | |||
// <td>%(import)s</td>\ | |||
// <td>%(export)s</td>\ | |||
// <td>%(print)s</td>\ | |||
// <td>%(email)s</td>' | |||
+ '<td>%(restrict)s</td>\ | |||
</tr>', perm)) | |||
} | |||
@@ -259,7 +281,7 @@ frappe.RoleEditor = Class.extend({ | |||
make_perm_dialog: function() { | |||
this.perm_dialog = new frappe.ui.Dialog({ | |||
title:'Role Permissions', | |||
width: 500 | |||
width: "800px" | |||
}); | |||
} | |||
}); |
@@ -6,6 +6,7 @@ import frappe | |||
from frappe.utils import cint, now | |||
from frappe import throw, msgprint, _ | |||
from frappe.auth import _update_password | |||
import frappe.permissions | |||
STANDARD_USERS = ("Guest", "Administrator") | |||
@@ -270,9 +271,8 @@ def get_user_roles(arg=None): | |||
@frappe.whitelist() | |||
def get_perm_info(arg=None): | |||
"""get permission info""" | |||
return frappe.db.sql("""select parent, permlevel, `read`, `write`, submit, | |||
cancel, amend from tabDocPerm where role=%s | |||
and docstatus<2 order by parent, permlevel""", | |||
return frappe.db.sql("""select parent, permlevel, `{}` from tabDocPerm where role=%s | |||
and docstatus<2 order by parent, permlevel""".format("`, `".join(frappe.permissions.rights)), | |||
(frappe.form_dict['role'],), as_dict=1) | |||
@frappe.whitelist(allow_guest=True) | |||
@@ -7,8 +7,9 @@ | |||
from __future__ import unicode_literals | |||
import MySQLdb | |||
import warnings | |||
import frappe | |||
import datetime | |||
import frappe | |||
import frappe.model.meta | |||
from frappe.utils import now, get_datetime | |||
from frappe import _ | |||
@@ -327,6 +328,9 @@ class Database: | |||
return self.get_values_from_single(fields, filters, doctype, as_dict, debug, update) | |||
def get_values_from_single(self, fields, filters, doctype, as_dict=False, debug=False, update=None): | |||
if not frappe.model.meta.is_single(doctype): | |||
raise frappe.DoesNotExistError("DocType", doctype) | |||
if fields=="*" or isinstance(filters, dict): | |||
# check if single doc matches with filters | |||
values = self.get_singles_dict(doctype) | |||
@@ -6,8 +6,8 @@ import frappe | |||
from frappe import _, msgprint | |||
from frappe.utils import cint | |||
rights = ["read", "write", "create", "submit", "cancel", "amend", | |||
"report", "import", "export", "print", "email", "restrict", "delete", "restricted"] | |||
rights = ("read", "write", "create", "submit", "cancel", "amend", | |||
"report", "import", "export", "print", "email", "restrict", "delete", "restricted") | |||
def check_admin_or_system_manager(): | |||
if ("System Manager" not in frappe.get_roles()) and \ | |||
@@ -209,34 +209,48 @@ frappe.ui.form.Toolbar = Class.extend({ | |||
this.appframe.clear_primary_action(); | |||
if(this.can_submit()) { | |||
status = "Submit"; | |||
} else if(this.can_save()) { | |||
if(!this.frm.save_disabled) { | |||
status = "Save"; | |||
} | |||
} else if(this.can_update()) { | |||
status = "Update"; | |||
} else if(this.can_cancel()) { | |||
status = "Cancel"; | |||
} else if(this.can_amend()) { | |||
status = "Amend"; | |||
} | |||
if (this.can_submit()) { | |||
status = "Submit"; | |||
} else if (this.can_save()) { | |||
if (!this.frm.save_disabled) { | |||
status = "Save"; | |||
} | |||
} else if (this.can_update()) { | |||
status = "Update"; | |||
} else if (this.can_cancel()) { | |||
status = "Cancel"; | |||
} else if (this.can_amend()) { | |||
status = "Amend"; | |||
} | |||
if (status) { | |||
if (status !== current) { | |||
var perm_to_check = this.frm.action_perm_type_map[status]; | |||
if(!this.frm.perm[0][perm_to_check]) { | |||
return; | |||
} | |||
if(status) { | |||
if(status!==current) { | |||
this.appframe.set_title_right(__(status), { | |||
"Save": function() { me.frm.save('Save', null, this); }, | |||
"Submit": function() { me.frm.savesubmit(this); }, | |||
"Update": function() { me.frm.save('Update', null, this); }, | |||
"Cancel": function() { me.frm.savecancel(this); }, | |||
"Amend": function() { me.frm.amend_doc(); } | |||
}[status], null, status==="Cancel" ? "btn-default" : "btn-primary"); | |||
this.appframe.set_title_right(__(status), { | |||
"Save": function() { | |||
me.frm.save('Save', null, this); | |||
}, | |||
"Submit": function() { | |||
me.frm.savesubmit(this); | |||
}, | |||
"Update": function() { | |||
me.frm.save('Update', null, this); | |||
}, | |||
"Cancel": function() { | |||
me.frm.savecancel(this); | |||
}, | |||
"Amend": function() { | |||
me.frm.amend_doc(); | |||
} | |||
}[status], null, status === "Cancel" ? "btn-default" : "btn-primary"); | |||
} | |||
} else { | |||
} else { | |||
this.appframe.set_title_right(); | |||
} | |||
}, | |||
make_cancel_amend_button: function() { | |||
var me = this; | |||
@@ -1,5 +1,5 @@ | |||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
// MIT License. See license.txt | |||
// MIT License. See license.txt | |||
frappe.provide('frappe.ui'); | |||
@@ -30,13 +30,15 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({ | |||
}, | |||
make: function() { | |||
this.$wrapper = frappe.get_modal("", ""); | |||
this.wrapper = this.$wrapper.find('.modal-dialog').get(0); | |||
this.wrapper = this.$wrapper.find('.modal-dialog') | |||
.css("width", this.width) | |||
.get(0); | |||
this.make_head(); | |||
this.body = this.$wrapper.find(".modal-body").get(0); | |||
// make fields (if any) | |||
this._super(); | |||
var me = this; | |||
this.$wrapper | |||
.on("hide.bs.modal", function() { | |||
@@ -65,8 +67,8 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({ | |||
} | |||
me.onshow && me.onshow(); | |||
}) | |||
}, | |||
make_head: function() { | |||
var me = this; | |||
@@ -94,4 +96,4 @@ $(document).bind('keydown', function(e) { | |||
if(cur_dialog && !cur_dialog.no_cancel_flag && e.which==27) { | |||
cur_dialog.hide(); | |||
} | |||
}); | |||
}); |
@@ -99,6 +99,9 @@ function msgprint(msg, title) { | |||
if(msg_dialog.msg_area.html()) msg_dialog.msg_area.append("<hr>"); | |||
msg_dialog.msg_area.append(msg); | |||
// make msgprint always appear on top | |||
msg_dialog.$wrapper.css("z-index", 2000); | |||
msg_dialog.show(); | |||
return msg_dialog; | |||
@@ -570,11 +570,7 @@ _f.Frm.prototype.runscript = function(scriptname, callingfield, onrefresh) { | |||
} | |||
_f.Frm.prototype.copy_doc = function(onload, from_amend) { | |||
if(!this.perm[0].create) { | |||
msgprint(__('You are not allowed to create {0}', [this.meta.name])); | |||
return; | |||
} | |||
this.validate_form_action("Create"); | |||
var newdoc = frappe.model.copy_doc(this.doc, from_amend); | |||
newdoc.idx = null; | |||
@@ -609,6 +605,8 @@ _f.Frm.prototype.save = function(save_action, callback, btn, on_error) { | |||
_f.Frm.prototype._save = function(save_action, callback, btn, on_error) { | |||
var me = this; | |||
if(!save_action) save_action = "Save"; | |||
this.validate_form_action(save_action); | |||
if((!this.meta.in_dialog || this.in_form) && !this.meta.istable) | |||
scroll(0, 0); | |||
@@ -641,12 +639,13 @@ _f.Frm.prototype._save = function(save_action, callback, btn, on_error) { | |||
} | |||
} | |||
frappe.ui.form.save(me, save_action || "Save", after_save, btn); | |||
frappe.ui.form.save(me, save_action, after_save, btn); | |||
} | |||
_f.Frm.prototype.savesubmit = function(btn, on_error) { | |||
var me = this; | |||
this.validate_form_action("Submit"); | |||
frappe.confirm(__("Permanently Submit {0}?", [this.docname]), function() { | |||
validated = true; | |||
me.script_manager.trigger("before_submit"); | |||
@@ -662,10 +661,11 @@ _f.Frm.prototype.savesubmit = function(btn, on_error) { | |||
} | |||
}, btn, on_error); | |||
}); | |||
} | |||
}; | |||
_f.Frm.prototype.savecancel = function(btn, on_error) { | |||
var me = this; | |||
this.validate_form_action('Cancel'); | |||
frappe.confirm(__("Permanently Cancel {0}?", [this.docname]), function() { | |||
validated = true; | |||
me.script_manager.trigger("before_cancel"); | |||
@@ -689,6 +689,7 @@ _f.Frm.prototype.savecancel = function(btn, on_error) { | |||
// delete the record | |||
_f.Frm.prototype.savetrash = function() { | |||
this.validate_form_action("Delete"); | |||
frappe.model.delete_doc(this.doctype, this.docname, function(r) { | |||
window.history.back(); | |||
}) | |||
@@ -699,6 +700,7 @@ _f.Frm.prototype.amend_doc = function() { | |||
alert('"amended_from" field must be present to do an amendment.'); | |||
return; | |||
} | |||
this.validate_form_action("Amend"); | |||
var me = this; | |||
var fn = function(newdoc) { | |||
newdoc.amended_from = me.docname; | |||
@@ -770,3 +772,21 @@ _f.Frm.prototype.add_fetch = function(link_field, src_field, tar_field) { | |||
_f.Frm.prototype.set_print_heading = function(txt) { | |||
this.pformat[cur_frm.docname] = txt; | |||
} | |||
_f.Frm.prototype.action_perm_type_map = { | |||
"Create": "create", | |||
"Save": "write", | |||
"Submit": "submit", | |||
"Update": "submit", | |||
"Cancel": "cancel", | |||
"Amend": "amend", | |||
"Delete": "delete" | |||
}; | |||
_f.Frm.prototype.validate_form_action = function(action) { | |||
var perm_to_check = this.action_perm_type_map[action]; | |||
if (!this.perm[0][perm_to_check]) { | |||
frappe.throw (__("No permission to '{0}' {1}", [__(action), __(this.doc.doctype)])); | |||
} | |||
}; |
@@ -30,7 +30,7 @@ def getdoc(doctype, name, user=None): | |||
doc.run_method("onload") | |||
if not doc.has_permission("read"): | |||
raise frappe.PermissionError | |||
raise frappe.PermissionError, "read" | |||
# add file list | |||
get_docinfo(doctype, name) | |||