Merge branch '4.0.0-wip' of github.com:webnotes/wnframework into 4.0.0-wip

This commit is contained in:
Nabin Hait 2014-01-23 15:36:05 +05:30
commit bfc27d9306
20 changed files with 248 additions and 163 deletions

View file

@ -105,6 +105,7 @@ def init(site, sites_path=None):
local.app_modules = None
local.user = None
local.restrictions = None
local.user_perms = {}
setup_module_map()
@ -214,6 +215,7 @@ def set_user(username):
local.session["user"] = username
local.user = webnotes.profile.Profile(username)
local.restrictions = None
local.user_perms = {}
def get_request_header(key, default=None):
return request.headers.get(key, default)

View file

@ -2,7 +2,7 @@
{
"creation": "2013-02-22 01:27:33",
"docstatus": 0,
"modified": "2014-01-20 17:48:11",
"modified": "2014-01-22 14:32:34",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -31,19 +31,10 @@
"name": "DocPerm"
},
{
"default": "0",
"doctype": "DocField",
"fieldname": "permlevel",
"fieldtype": "Int",
"hidden": 0,
"in_list_view": 1,
"label": "Level",
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"print_width": "40px",
"reqd": 0,
"search_index": 0,
"width": "40px"
"fieldname": "role_and_level",
"fieldtype": "Section Break",
"label": "Role and Level"
},
{
"doctype": "DocField",
@ -60,6 +51,32 @@
"search_index": 0,
"width": "150px"
},
{
"doctype": "DocField",
"fieldname": "column_break_2",
"fieldtype": "Column Break"
},
{
"default": "0",
"doctype": "DocField",
"fieldname": "permlevel",
"fieldtype": "Int",
"hidden": 0,
"in_list_view": 1,
"label": "Level",
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"print_width": "40px",
"reqd": 0,
"search_index": 0,
"width": "40px"
},
{
"doctype": "DocField",
"fieldname": "section_break_4",
"fieldtype": "Section Break",
"label": "Permissions"
},
{
"doctype": "DocField",
"fieldname": "read",
@ -74,6 +91,13 @@
"search_index": 0,
"width": "32px"
},
{
"description": "Only restricted users can access",
"doctype": "DocField",
"fieldname": "restricted",
"fieldtype": "Check",
"label": "Restricted"
},
{
"doctype": "DocField",
"fieldname": "write",
@ -109,6 +133,11 @@
"in_list_view": 1,
"label": "Delete"
},
{
"doctype": "DocField",
"fieldname": "column_break_8",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "submit",
@ -147,6 +176,12 @@
"print_width": "32px",
"width": "32px"
},
{
"doctype": "DocField",
"fieldname": "additional_permissions",
"fieldtype": "Section Break",
"label": "Additional Permissions"
},
{
"doctype": "DocField",
"fieldname": "report",
@ -167,6 +202,11 @@
"fieldtype": "Check",
"label": "Import"
},
{
"doctype": "DocField",
"fieldname": "column_break_19",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "print",
@ -180,21 +220,10 @@
"label": "Email"
},
{
"description": "This role can restrict users for accessing the record.",
"doctype": "DocField",
"fieldname": "restrict",
"fieldtype": "Check",
"label": "Restrict"
},
{
"doctype": "DocField",
"fieldname": "match",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Match",
"oldfieldname": "match",
"oldfieldtype": "Data",
"reqd": 0,
"search_index": 0
"label": "Can Restrict"
}
]

View file

@ -2,7 +2,7 @@
{
"creation": "2013-03-07 11:54:44",
"docstatus": 0,
"modified": "2014-01-20 17:49:02",
"modified": "2014-01-22 16:05:34",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -422,10 +422,10 @@
"delete": 0,
"doctype": "DocPerm",
"email": 1,
"match": "owner",
"permlevel": 0,
"print": 1,
"report": 1,
"restricted": 1,
"role": "All",
"submit": 0,
"write": 0

View file

@ -9,7 +9,7 @@ wn.pages['permission-manager'].onload = function(wrapper) {
<tr><td>\
<h4><i class='icon-question-sign'></i> "+wn._("Quick Help for Setting Permissions")+":</h4>\
<ol>\
<li>"+wn._("Permissions are set on Roles and Document Types (called DocTypes) by restricting read, edit, make new, delete, submit, cancel, amend, report, import, export, print, email and restrict rights.")+"</li>\
<li>"+wn._("Permissions are set on Roles and Document Types (called DocTypes) by setting read, edit, make new, delete, submit, cancel, amend, report, import, export, print, email and restrict rights.")+"</li>\
<li>"+wn._("Permissions translate to Users based on what Role they are assigned")+".</li>\
<li>"+wn._("To set user roles, just go to <a href='#List/Profile'>Setup > Users</a> and click on the user to assign roles.")+"</li>\
<li>"+wn._("The system provides pre-defined roles, but you can <a href='#List/Role'>add new roles</a> to set finer permissions")+".</li>\
@ -38,16 +38,13 @@ wn.pages['permission-manager'].onload = function(wrapper) {
</ol>\
</tr></td>\
<tr><td>\
<h4><i class='icon-user'></i> "+wn._("Restricting By User")+":</h4>\
<h4><i class='icon-cog'></i> "+wn._("Restricting Users")+":</h4>\
<ol>\
<li>"+wn._("To restrict a User of a particular Role to documents that are only self-created.")+
wn._("Click on button in the 'Condition' column and select the option 'User is the creator of the document'")+".</li></ol>\
</tr></td>\
<tr><td>\
<h4><i class='icon-cog'></i> "+wn._("Advanced Settings")+":</h4>\
<p>"+wn._("To further restrict permissions based on certain values, like Company or Territory in a document, please go to <a href='#user-properties'>User Restrictions</a>")+"</p>"+
"<p>"+wn._("Once you have set this, the users will only be able access documents where the link (e.g Company) exists.")+"</p>"+
"<p>"+wn._("Apart from System Manager, roles with Restrict permission can restrict other users for that Document Type")+"</p><hr>\
<li>"+wn._("To explictly give permissions to users to specific records, check the 'Restricted' permssion. To set which user has access to which record, go to <a href='#user-properties'>User Restrictions</a>")+"</li>"+
"<li>"+wn._("If 'Restricted' is not checked, you can still restrict permissions based on certain values, like Company or Territory in a document by setting <a href='#user-properties'>User Restrictions</a>. But unless any restriction is set, a user will have permissions based on the Role.")+"</li>"+
"<li>"+wn._("If 'Restricted' is checked, the owner is always allowed based on Role.")+"</li>"+
"<li>"+wn._("Once you have set this, the users will only be able access documents where the link (e.g Company) exists.")+"</li>"+
"<li>"+wn._("Apart from System Manager, roles with Restrict permission can restrict other users for that Document Type")+"</li></ol><hr>\
<p>"+wn._("If these instructions where not helpful, please add in your suggestions at <a href='https://github.com/webnotes/wnframework/issues'>GitHub Issues</a>")+"</p>\
</tr></td>\
</table>");
@ -208,13 +205,14 @@ wn.PermissionEngine = Class.extend({
.html(d[fieldname]);
};
var add_check = function(cell, d, fieldname) {
var add_check = function(cell, d, fieldname, label) {
if(!label) label = fieldname;
if(d.permlevel > 0 && ["read", "write"].indexOf(fieldname)==-1) {
return;
}
var checkbox = $("<div class='col-md-4'><div class='checkbox'>\
<label><input type='checkbox'>"+fieldname+"</input></label>\
<label><input type='checkbox'>"+label+"</input></label>\
</div></div>").appendTo(cell)
.attr("data-fieldname", fieldname)
.css("text-transform", "capitalize");
@ -241,6 +239,7 @@ wn.PermissionEngine = Class.extend({
var perm_cell = add_cell(row, d, "permissions").css("padding-top", 0);
var perm_container = $("<div class='row'></div>").appendTo(perm_cell);
add_check(perm_container, d, "read");
add_check(perm_container, d, "restricted");
add_check(perm_container, d, "write");
add_check(perm_container, d, "create");
add_check(perm_container, d, "delete");
@ -252,7 +251,7 @@ wn.PermissionEngine = Class.extend({
add_check(perm_container, d, "export");
add_check(perm_container, d, "print");
add_check(perm_container, d, "email");
add_check(perm_container, d, "restrict");
add_check(perm_container, d, "restrict", "Can Restrict");
// buttons
me.add_match_button(row, d);

View file

@ -28,9 +28,7 @@ def get_permissions(doctype=None, role=None):
@webnotes.whitelist()
def remove(doctype, name):
webnotes.only_for("System Manager")
match = webnotes.conn.get_value("DocPerm", name, "`match`")
webnotes.only_for("System Manager")
webnotes.conn.sql("""delete from tabDocPerm where name=%s""", name)
validate_and_reset(doctype, for_remove=True)
@ -56,14 +54,7 @@ def update(name, doctype, ptype, value=0):
webnotes.conn.sql("""update tabDocPerm set `%s`=%s where name=%s"""\
% (ptype, '%s', '%s'), (value, name))
validate_and_reset(doctype)
@webnotes.whitelist()
def update_match(name, doctype, match=""):
webnotes.only_for("System Manager")
webnotes.conn.sql("""update tabDocPerm set `match`=%s where name=%s""",
(match, name))
validate_and_reset(doctype)
def validate_and_reset(doctype, for_remove=False):
from webnotes.core.doctype.doctype.doctype import validate_permissions_for_doctype
validate_permissions_for_doctype(doctype, for_remove)

View file

@ -58,6 +58,9 @@ def remove(user, name, defkey, defvalue):
webnotes.defaults.clear_default(name=name)
def clear_restrictions(doctype):
webnotes.defaults.clear_default(parenttype="Restriction", key=doctype)
@webnotes.whitelist()
def add(user, defkey, defvalue):
if not webnotes.permissions.can_restrict_user(user, defkey, defvalue):

View file

@ -459,7 +459,7 @@ class Bean:
has_restricted_data = False
for d in self.doclist:
if not webnotes.permissions.has_only_permitted_data(webnotes.get_doctype(d.doctype), d):
if not webnotes.permissions.has_unrestricted_access(webnotes.get_doctype(d.doctype), d):
has_restricted_data = True
if has_restricted_data:

View file

@ -400,6 +400,12 @@ class DocTypeDocList(webnotes.model.doclist.DocList):
if self[0].name in restricted_types:
restricted_fields.append(webnotes._dict({"label":"Name", "fieldname":"name", "options": self[0].name}))
return restricted_fields
def get_permissions(self, user=None):
user_roles = webnotes.get_roles(user)
return [p for p in self.get({"doctype": "DocPerm"})
if cint(p.permlevel)==0 and (p.role=="All" or p.role in user_roles)]
def rename_field(doctype, old_fieldname, new_fieldname, lookup_field=None):
"""this function assumes that sync is NOT performed"""

View file

@ -5,4 +5,5 @@ execute:webnotes.reload_doc('core', 'doctype', 'page') #2013-13-26
execute:webnotes.reload_doc('core', 'doctype', 'report') #2013-13-26
webnotes.patches.4_0.remove_index_sitemap
webnotes.patches.4_0.add_delete_permission
webnotes.patches.4_0.add_delete_permission
webnotes.patches.4_0.move_match_to_restricted

View file

@ -7,6 +7,6 @@ def execute():
webnotes.conn.sql("""update tabDocPerm set `delete`=ifnull(`cancel`,0)""")
# can't cancel if can't submit
webnotes.conn.sql("""update tabDocPerm set `cancel`=0 where `submit`=0""")
webnotes.conn.sql("""update tabDocPerm set `cancel`=0 where ifnull(`submit`,0)=0""")
webnotes.clear_cache()

View file

@ -0,0 +1,9 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
import webnotes
def execute():
webnotes.reload_doc("core", "doctype", "docperm")
webnotes.conn.sql("""update `tabDocPerm` set restricted=1 where `match`='owner'""")

View file

@ -26,35 +26,57 @@ def has_permission(doctype, ptype="read", refdoc=None, verbose=True):
if webnotes.session.user=="Administrator":
return True
# get user permissions
perms = get_user_perms(meta, ptype)
if not perms:
if not get_user_perms(meta).get(ptype):
return False
elif refdoc:
if isinstance(refdoc, basestring):
refdoc = webnotes.doc(meta[0].name, refdoc)
if (has_only_permitted_data(meta, refdoc, verbose=verbose) and has_match(perms, refdoc)):
if has_unrestricted_access(meta, refdoc, verbose=verbose):
return True
else:
return False
else:
return True
def get_user_perms(meta, ptype, user=None):
user_roles = webnotes.get_roles(user)
return [p for p in meta.get({"doctype": "DocPerm"})
if cint(p.get(ptype))==1 and cint(p.permlevel)==0 and (p.role=="All" or p.role in user_roles)]
rights = ["read", "write", "create", "submit", "cancel", "amend",
"report", "import", "export", "print", "email", "restrict", "delete", "restricted"]
def has_only_permitted_data(meta, refdoc, verbose=True):
def get_user_perms(meta, user=None):
cache_key = (meta[0].name, user)
if not webnotes.local.user_perms.get(cache_key):
perms = webnotes._dict()
user_roles = webnotes.get_roles(user)
for p in meta.get({"doctype": "DocPerm"}):
if cint(p.permlevel)==0 and (p.role=="All" or p.role in user_roles):
for ptype in rights:
if ptype == "restricted":
perms[ptype] = perms.get(ptype, 1) and cint(p.get(ptype))
else:
perms[ptype] = perms.get(ptype, 0) or cint(p.get(ptype))
webnotes.local.user_perms[cache_key] = perms
return webnotes.local.user_perms[cache_key]
def has_unrestricted_access(meta, refdoc, verbose=True):
from webnotes.defaults import get_restrictions
restrictions = get_restrictions()
if not restrictions:
return True
if get_user_perms(meta).restricted:
if refdoc.owner == webnotes.session.user:
# owner is always allowed for restricted permissions
return True
elif not restrictions:
return False
else:
if not restrictions:
return True
# evaluate specific restrictions
fields_to_check = meta.get_restricted_fields(restrictions.keys())
has_restricted_data = False
@ -75,20 +97,6 @@ def has_only_permitted_data(meta, refdoc, verbose=True):
# check all restrictions before returning
return False if has_restricted_data else True
def has_match(perms, refdoc):
"""check owner match (if exists)"""
for p in perms:
if p.get("match")=="owner":
if refdoc.get("owner")==webnotes.local.session.user:
# owner matches :)
return True
else:
# found a permission without owner match :)
return True
# no match :(
return False
def can_restrict_user(user, doctype, docname=None):
if not can_restrict(doctype, docname):
@ -106,7 +114,6 @@ def can_restrict(doctype, docname=None):
# System Manager can always restrict
if "System Manager" in webnotes.get_roles():
return True
meta = webnotes.get_doctype(doctype)
# check if current user has read permission for docname
@ -120,8 +127,7 @@ def can_restrict(doctype, docname=None):
return True
def has_restrict_permission(meta=None, user=None):
return any((perm for perm in get_user_perms(meta, "read", user)
if cint(perm.restrict)==1))
return get_user_perms(meta, user).restrict==1
def has_only_non_restrict_role(meta, user):
# check if target user does not have restrict permission
@ -129,8 +135,7 @@ def has_only_non_restrict_role(meta, user):
return False
# and has non-restrict role
return any((perm for perm in get_user_perms(meta, "read", user)
if cint(perm.restrict)==0))
return get_user_perms(meta, user).restrict==0
def can_import(doctype, raise_exception=False):
if not ("System Manager" in webnotes.get_roles() or has_permission(doctype, "import")):

View file

@ -1699,7 +1699,7 @@ output {
border-radius: 4px;
}
.form-control:focus {
border-color: #000;
border-color: #66afe9;
outline: 0;
}
.form-control:-moz-placeholder {

View file

@ -465,7 +465,7 @@ wn.ui.form.ControlCheck = wn.ui.form.ControlData.extend({
<label>\
<span class="input-area"></span>\
<span class="disp-area" style="display:none;"></span>\
<span class="label-area small text-muted"></span>\
<span class="label-area small"></span>\
</label>\
<p class="help-box small text-muted"></p>\
</div>\

View file

@ -9,7 +9,7 @@ var SUBMIT = "submit", CANCEL = "cancel", AMEND = "amend";
$.extend(wn.perm, {
rights: ["read", "write", "create", "submit", "cancel", "amend",
"report", "import", "export", "print", "email", "restrict", "delete"],
"report", "import", "export", "print", "email", "restrict", "delete", "restricted"],
doctype_perm: {},
@ -55,7 +55,7 @@ $.extend(wn.perm, {
perm[0].read = 1;
}
if(docname && !wn.perm.has_only_permitted_data(doctype, docname)) {
if(docname && !wn.perm.has_unrestricted_access(doctype, docname, perm[0].restricted)) {
// if has restricted data, return not permitted
return perm;
}
@ -63,14 +63,17 @@ $.extend(wn.perm, {
var docperms = wn.model.get("DocPerm", {parent: doctype});
$.each(docperms, function(i, p) {
// if user has this role
if(user_roles.indexOf(p.role)!==-1 &&
(!docname || wn.perm.has_match(p, doctype, docname))) {
if(user_roles.indexOf(p.role)!==-1) {
var permlevel = cint(p.permlevel);
if(!perm[permlevel]) {
perm[permlevel] = {};
}
$.each(wn.perm.rights, function(i, key) {
perm[permlevel][key] = perm[permlevel][key] || (p[key] || 0);
if(key=="restricted") {
perm[permlevel][key] = (perm[permlevel][key] || 1) && (p[key] || 0);
} else {
perm[permlevel][key] = perm[permlevel][key] || (p[key] || 0);
}
});
}
});
@ -78,10 +81,19 @@ $.extend(wn.perm, {
return perm;
},
has_only_permitted_data: function(doctype, docname) {
has_unrestricted_access: function(doctype, docname, restricted) {
var restrictions = wn.defaults.get_restrictions();
if(!restrictions || $.isEmptyObject(restrictions)) {
return true;
var doc = wn.model.get_doc(doctype, docname);
if(restricted) {
if(doc.owner==user) return true;
if(!restrictions || $.isEmptyObject(restrictions)) {
return false;
}
} else {
if(!restrictions || $.isEmptyObject(restrictions)) {
return true;
}
}
// prepare restricted fields
@ -109,33 +121,10 @@ $.extend(wn.perm, {
}
return fields_to_check;
},
has_match: function(docperm, doctype, docname) {
if(!docperm.match) return true;
if(docperm.match==="owner") {
var doc = wn.model.get_doc(doctype, docname);
if(doc.owner===user) {
return true;
}
}
return false;
},
get_match_rules: function(doctype) {
var match_rules = {};
// Rule for owner match
var owner_match = false;
$.each(wn.model.get("DocPerm", {parent:doctype}), function(i, docperm) {
if(docperm.match==="owner") {
owner_match = true;
} else {
owner_match = false;
return false;
}
});
if(owner_match) match_rules["Created By"] = user;
// Rule for restrictions
var restrictions = wn.defaults.get_restrictions();
if(restrictions && !$.isEmptyObject(restrictions)) {

View file

@ -68,9 +68,6 @@ wn.request.call = function(opts) {
opts.success && opts.success(data, xhr.responseText);
}
},
fail: function(xhr, textStatus) {
opts.error && opts.error(xhr)
},
async: opts.async
};
@ -100,7 +97,14 @@ wn.request.call = function(opts) {
})
}
return $.ajax(ajax_args).always(function(data) {
return $.ajax(ajax_args)
.fail(function(xhr, textStatus) {
opts.error && opts.error(xhr)
})
.always(function(data) {
if(data.responseText) {
data = JSON.parse(data.responseText);
}
wn.request.cleanup(opts, data);
});
}

View file

@ -104,6 +104,8 @@ wn.views.DocListView = wn.ui.Listing.extend({
show_match_help: function() {
var me = this;
var match_rules = wn.perm.get_match_rules(this.doctype);
var perm = wn.perm.get_perm(doctype);
if(keys(match_rules).length) {
var match_text = []
$.each(match_rules, function(key, values) {
@ -113,6 +115,10 @@ wn.views.DocListView = wn.ui.Listing.extend({
match_text.push(wn._(key) + " = " + wn.utils.comma_or(values));
}
});
if(perm[0].restricted) {
match_text.push(wn._("Or Created By") + " = " + user);
}
wn.utils.set_footnote(this, this.$page.find(".layout-main-section"),
"<p>" + wn._("Showing only for") + ":</p><ul>"
+ $.map(match_text, function(txt) { return "<li>"+txt+"</li>" }).join("")) + "</ul>";

View file

@ -26,13 +26,15 @@ test_records = [
import webnotes
import webnotes.defaults
import unittest
from webnotes.core.page.user_properties.user_properties import add, remove, get_properties, clear_restrictions
test_dependencies = ["Profile"]
class TestBlogPost(unittest.TestCase):
def setUp(self):
webnotes.conn.sql("""update tabDocPerm set `match`='' where parent='Blog Post'
webnotes.conn.sql("""update tabDocPerm set `restricted`=0 where parent='Blog Post'
and ifnull(permlevel,0)=0""")
webnotes.conn.sql("""update `tabBlog Post` set owner='test1@example.com'
webnotes.conn.sql("""update `tabBlog Post` set owner='test2@example.com'
where name='_test-blog-post'""")
webnotes.clear_cache(doctype="Blog Post")
@ -47,7 +49,8 @@ class TestBlogPost(unittest.TestCase):
def tearDown(self):
webnotes.set_user("Administrator")
webnotes.defaults.clear_default(key="Blog Category", parenttype="Restriction")
clear_restrictions("Blog Category")
clear_restrictions("Blog Post")
def test_basic_permission(self):
post = webnotes.bean("Blog Post", "_test-blog-post")
@ -79,12 +82,17 @@ class TestBlogPost(unittest.TestCase):
doc = webnotes.new_doc("Blog Post")
self.assertEquals(doc.get("blog_category"), "_Test Blog Category 1")
def test_owner_match_bean(self):
webnotes.conn.sql("""update tabDocPerm set `match`='owner' where parent='Blog Post'
def add_restricted_on_blogger(self):
webnotes.conn.sql("""update tabDocPerm set `restricted`=1 where parent='Blog Post' and role='Blogger'
and ifnull(permlevel,0)=0""")
webnotes.clear_cache(doctype="Blog Post")
def test_owner_match_bean(self):
self.add_restricted_on_blogger()
webnotes.set_user("test2@example.com")
post = webnotes.bean("Blog Post", "_test-blog-post")
self.assertTrue(post.has_read_perm())
@ -92,28 +100,36 @@ class TestBlogPost(unittest.TestCase):
self.assertFalse(post1.has_read_perm())
def test_owner_match_report(self):
webnotes.conn.sql("""update tabDocPerm set `match`='owner' where parent='Blog Post'
webnotes.conn.sql("""update tabDocPerm set `restricted`=1 where parent='Blog Post'
and ifnull(permlevel,0)=0""")
webnotes.clear_cache(doctype="Blog Post")
webnotes.set_user("test2@example.com")
names = [d.name for d in webnotes.get_list("Blog Post", fields=["name", "owner"])]
self.assertTrue("_test-blog-post" in names)
self.assertFalse("_test-blog-post-1" in names)
def test_restrict(self):
from webnotes.core.page.user_properties.user_properties import add, remove, get_properties
# restrictor can add restriction
def add_restriction_to_user2(self):
webnotes.set_user("test1@example.com")
add("test2@example.com", "Blog Post", "_test-blog-post")
defname = get_properties("test2@example.com", "Blog Post", "_test-blog-post")[0].name
def test_add_restriction(self):
# restrictor can add restriction
self.add_restriction_to_user2()
def test_not_allowed_to_restrict(self):
webnotes.set_user("test2@example.com")
# this user can't add restriction
self.assertRaises(webnotes.PermissionError, add,
"test2@example.com", "Blog Post", "_test-blog-post")
def test_not_allowed_to_restrict(self):
self.add_restriction_to_user2()
webnotes.set_user("test2@example.com")
# user can only access restricted blog post
bean = webnotes.bean("Blog Post", "_test-blog-post")
self.assertTrue(bean.has_read_perm())
@ -121,12 +137,28 @@ class TestBlogPost(unittest.TestCase):
# and not this one
bean = webnotes.bean("Blog Post", "_test-blog-post-1")
self.assertFalse(bean.has_read_perm())
def test_not_allowed_to_remove_self(self):
self.add_restriction_to_user2()
defname = get_properties("test2@example.com", "Blog Post", "_test-blog-post")[0].name
webnotes.set_user("test2@example.com")
# user cannot remove their own restriction
self.assertRaises(webnotes.PermissionError, remove,
"test2@example.com", defname, "Blog Post", "_test-blog-post")
# but restrictor can
def test_allow_in_restriction(self):
self.add_restricted_on_blogger()
webnotes.set_user("test2@example.com")
bean = webnotes.bean("Blog Post", "_test-blog-post-1")
self.assertFalse(bean.has_read_perm())
webnotes.set_user("test1@example.com")
remove("test2@example.com", defname, "Blog Post", "_test-blog-post")
add("test2@example.com", "Blog Post", "_test-blog-post-1")
webnotes.set_user("test2@example.com")
bean = webnotes.bean("Blog Post", "_test-blog-post-1")
self.assertTrue(bean.has_read_perm())

View file

@ -120,9 +120,12 @@ def get_filtered_data(ref_doctype, columns, data):
matched_columns = get_matched_columns(linked_doctypes, match_filters)
for row in data:
match = True
for col, idx in matched_columns.items():
if row[idx] not in match_filters[col]:
match = False
if not ("owner" in match_filters and matched_columns.get("profile", None)==match_filters["owner"]):
for col, idx in matched_columns.items():
if row[idx] not in match_filters[col]:
match = False
break
if match:
result.append(row)

View file

@ -204,15 +204,24 @@ def build_match_conditions(doctype, fields=None, as_condition=True):
import webnotes.permissions
match_filters = {}
match_conditions = []
or_conditions = []
if not getattr(webnotes.local, "reportview_tables", None):
webnotes.local.reportview_tables = get_tables(doctype, fields)
load_doctypes()
# is restricted
restricted = webnotes.permissions.get_user_perms(webnotes.local.reportview_doctypes[doctype]).restricted
# get restrictions
restrictions = webnotes.defaults.get_restrictions()
if restricted:
or_conditions.append('`tab{doctype}`.`owner`="{user}"'.format(doctype=doctype,
user=webnotes.local.session.user))
match_filters["owner"] = webnotes.session.user
if restrictions:
fields_to_check = webnotes.local.reportview_doctypes[doctype].get_restricted_fields(restrictions.keys())
if doctype in restrictions:
@ -223,28 +232,25 @@ def build_match_conditions(doctype, fields=None, as_condition=True):
if as_condition:
match_conditions.append('`tab{doctype}`.{fieldname} in ({values})'.format(doctype=doctype,
fieldname=df.fieldname,
values=", ".join([('"'+v.replace('"', '\"')+'"') for v in restrictions[df.options]])))
values=", ".join([('"'+v.replace('"', '\"')+'"') \
for v in restrictions[df.options]])))
else:
match_filters.setdefault(df.fieldname, [])
match_filters[df.fieldname]= restrictions[df.options]
# add owner match
owner_match = True
for p in webnotes.permissions.get_user_perms(webnotes.local.reportview_doctypes[doctype], "read"):
if not (p.match and p.match=="owner"):
owner_match = False
break
if owner_match:
match_conditions.append('`tab{doctype}`.`owner`="{user}"'.format(doctype=doctype,
user=webnotes.local.session.user))
match_filters["owner"] = [webnotes.local.session.user]
if as_condition:
conditions = " and ".join(match_conditions)
doctype_conditions = get_doctype_conditions(doctype)
if doctype_conditions:
conditions += ' and ' + doctype_conditions if conditions else doctype_conditions
if or_conditions:
if conditions:
conditions = '({conditions}) or {or_conditions}'.format(conditions=conditions,
or_conditions = ' or '.join(or_conditions))
else:
conditions = " or ".join(or_conditions)
return conditions
else:
return match_filters