diff --git a/webnotes/__init__.py b/webnotes/__init__.py
index a172654527..8c17e4c92d 100644
--- a/webnotes/__init__.py
+++ b/webnotes/__init__.py
@@ -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)
diff --git a/webnotes/core/doctype/docperm/docperm.txt b/webnotes/core/doctype/docperm/docperm.txt
index 6e85511458..f03bba0ba8 100644
--- a/webnotes/core/doctype/docperm/docperm.txt
+++ b/webnotes/core/doctype/docperm/docperm.txt
@@ -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"
}
]
\ No newline at end of file
diff --git a/webnotes/core/doctype/profile/profile.txt b/webnotes/core/doctype/profile/profile.txt
index 4101113bb8..d6cb31a1e5 100644
--- a/webnotes/core/doctype/profile/profile.txt
+++ b/webnotes/core/doctype/profile/profile.txt
@@ -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
diff --git a/webnotes/core/page/permission_manager/permission_manager.js b/webnotes/core/page/permission_manager/permission_manager.js
index fc563d4096..7c7e96d124 100644
--- a/webnotes/core/page/permission_manager/permission_manager.js
+++ b/webnotes/core/page/permission_manager/permission_manager.js
@@ -9,7 +9,7 @@ wn.pages['permission-manager'].onload = function(wrapper) {
\
"+wn._("Quick Help for Setting Permissions")+": \
\
- "+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.")+" \
+ "+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.")+" \
"+wn._("Permissions translate to Users based on what Role they are assigned")+". \
"+wn._("To set user roles, just go to Setup > Users and click on the user to assign roles.")+" \
"+wn._("The system provides pre-defined roles, but you can add new roles to set finer permissions")+". \
@@ -38,16 +38,13 @@ wn.pages['permission-manager'].onload = function(wrapper) {
\
\
\
- "+wn._("Restricting By User")+": \
+ "+wn._("Restricting Users")+": \
\
- "+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'")+". \
- \
- \
- "+wn._("Advanced Settings")+": \
- "+wn._("To further restrict permissions based on certain values, like Company or Territory in a document, please go to User Restrictions ")+"
"+
- ""+wn._("Once you have set this, the users will only be able access documents where the link (e.g Company) exists.")+"
"+
- ""+wn._("Apart from System Manager, roles with Restrict permission can restrict other users for that Document Type")+"
\
+ "+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 User Restrictions ")+" "+
+ ""+wn._("If 'Restricted' is not checked, you can still restrict permissions based on certain values, like Company or Territory in a document by setting User Restrictions . But unless any restriction is set, a user will have permissions based on the Role.")+" "+
+ ""+wn._("If 'Restricted' is checked, the owner is always allowed based on Role.")+" "+
+ ""+wn._("Once you have set this, the users will only be able access documents where the link (e.g Company) exists.")+" "+
+ ""+wn._("Apart from System Manager, roles with Restrict permission can restrict other users for that Document Type")+" \
"+wn._("If these instructions where not helpful, please add in your suggestions at GitHub Issues ")+"
\
\
");
@@ -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 = $("").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 = $("
").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);
diff --git a/webnotes/core/page/permission_manager/permission_manager.py b/webnotes/core/page/permission_manager/permission_manager.py
index 4aed3da6ae..a9d14fe0dd 100644
--- a/webnotes/core/page/permission_manager/permission_manager.py
+++ b/webnotes/core/page/permission_manager/permission_manager.py
@@ -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)
diff --git a/webnotes/core/page/user_properties/user_properties.py b/webnotes/core/page/user_properties/user_properties.py
index 235c8080f0..45ef74382b 100644
--- a/webnotes/core/page/user_properties/user_properties.py
+++ b/webnotes/core/page/user_properties/user_properties.py
@@ -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):
diff --git a/webnotes/model/bean.py b/webnotes/model/bean.py
index cb3d3e1a14..ff013d8cc9 100644
--- a/webnotes/model/bean.py
+++ b/webnotes/model/bean.py
@@ -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:
diff --git a/webnotes/model/doctype.py b/webnotes/model/doctype.py
index b13e672a2b..d695f3389a 100644
--- a/webnotes/model/doctype.py
+++ b/webnotes/model/doctype.py
@@ -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"""
diff --git a/webnotes/patches.txt b/webnotes/patches.txt
index fde7f98815..cac72e1cbb 100644
--- a/webnotes/patches.txt
+++ b/webnotes/patches.txt
@@ -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
\ No newline at end of file
+webnotes.patches.4_0.add_delete_permission
+webnotes.patches.4_0.move_match_to_restricted
\ No newline at end of file
diff --git a/webnotes/patches/4_0/add_delete_permission.py b/webnotes/patches/4_0/add_delete_permission.py
index 6ba3cd2eb1..61f19b89ab 100644
--- a/webnotes/patches/4_0/add_delete_permission.py
+++ b/webnotes/patches/4_0/add_delete_permission.py
@@ -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()
\ No newline at end of file
diff --git a/webnotes/patches/4_0/move_match_to_restricted.py b/webnotes/patches/4_0/move_match_to_restricted.py
new file mode 100644
index 0000000000..ecb2f77c0e
--- /dev/null
+++ b/webnotes/patches/4_0/move_match_to_restricted.py
@@ -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'""")
\ No newline at end of file
diff --git a/webnotes/permissions.py b/webnotes/permissions.py
index ac04413426..9faa9ad4ea 100644
--- a/webnotes/permissions.py
+++ b/webnotes/permissions.py
@@ -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")):
diff --git a/webnotes/public/css/bootstrap.css b/webnotes/public/css/bootstrap.css
index dd226f000e..5ad2417d8f 100644
--- a/webnotes/public/css/bootstrap.css
+++ b/webnotes/public/css/bootstrap.css
@@ -1699,7 +1699,7 @@ output {
border-radius: 4px;
}
.form-control:focus {
- border-color: #000;
+ border-color: #66afe9;
outline: 0;
}
.form-control:-moz-placeholder {
diff --git a/webnotes/public/js/wn/form/control.js b/webnotes/public/js/wn/form/control.js
index 547efdd03e..f3f5e7339e 100644
--- a/webnotes/public/js/wn/form/control.js
+++ b/webnotes/public/js/wn/form/control.js
@@ -465,7 +465,7 @@ wn.ui.form.ControlCheck = wn.ui.form.ControlData.extend({
\
\
\
- \
+ \
\
\
\
diff --git a/webnotes/public/js/wn/model/perm.js b/webnotes/public/js/wn/model/perm.js
index 207829a4a5..034bbb2a3d 100644
--- a/webnotes/public/js/wn/model/perm.js
+++ b/webnotes/public/js/wn/model/perm.js
@@ -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)) {
diff --git a/webnotes/public/js/wn/request.js b/webnotes/public/js/wn/request.js
index 8d87eb4890..5aed5ca3db 100644
--- a/webnotes/public/js/wn/request.js
+++ b/webnotes/public/js/wn/request.js
@@ -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);
});
}
diff --git a/webnotes/public/js/wn/views/doclistview.js b/webnotes/public/js/wn/views/doclistview.js
index e685fe03b3..f553339082 100644
--- a/webnotes/public/js/wn/views/doclistview.js
+++ b/webnotes/public/js/wn/views/doclistview.js
@@ -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"),
"" + wn._("Showing only for") + ":
"
+ $.map(match_text, function(txt) { return ""+txt+" " }).join("")) + " ";
diff --git a/webnotes/website/doctype/blog_post/test_blog_post.py b/webnotes/website/doctype/blog_post/test_blog_post.py
index 474b2da74f..48723a7071 100644
--- a/webnotes/website/doctype/blog_post/test_blog_post.py
+++ b/webnotes/website/doctype/blog_post/test_blog_post.py
@@ -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")
-
\ No newline at end of file
+ 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())
diff --git a/webnotes/widgets/query_report.py b/webnotes/widgets/query_report.py
index ef4ae0ecfe..21d8b5f629 100644
--- a/webnotes/widgets/query_report.py
+++ b/webnotes/widgets/query_report.py
@@ -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)
diff --git a/webnotes/widgets/reportview.py b/webnotes/widgets/reportview.py
index 3ce0e26684..d87e535522 100644
--- a/webnotes/widgets/reportview.py
+++ b/webnotes/widgets/reportview.py
@@ -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