You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

206 lines
5.6 KiB

  1. // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. // MIT License. See license.txt
  3. wn.provide("wn.perm");
  4. // backward compatibilty
  5. var READ = "read", WRITE = "write", CREATE = "create", DELETE = "delete";
  6. var SUBMIT = "submit", CANCEL = "cancel", AMEND = "amend";
  7. $.extend(wn.perm, {
  8. rights: ["read", "write", "create", "submit", "cancel", "amend",
  9. "report", "import", "export", "print", "email", "restrict", "delete"],
  10. doctype_perm: {},
  11. has_perm: function(doctype, permlevel, ptype, docname) {
  12. if(!permlevel) permlevel = 0;
  13. if(docname) {
  14. var perms = wn.perm.get_perm(doctype, docname);
  15. } else {
  16. if(!wn.perm.doctype_perm[doctype]) {
  17. wn.perm.doctype_perm[doctype] = wn.perm.get_perm(doctype);
  18. }
  19. var perms = wn.perm.doctype_perm[doctype];
  20. }
  21. if(!perms)
  22. return false;
  23. if(!perms[permlevel])
  24. return false;
  25. return !!perms[permlevel][ptype];
  26. },
  27. get_perm: function(doctype, docname) {
  28. var perm = [{read: 0}];
  29. var meta = wn.model.get_doc("DocType", doctype);
  30. if(!meta) {
  31. return perm;
  32. } else if(meta.istable) {
  33. // if a child table, use permissions of parent form
  34. var parent_df = wn.model.get("DocField", {fieldtype: "Table", options: doctype});
  35. if(parent_df.length) {
  36. if(docname) {
  37. docname = wn.model.get_doc(doctype, docname).parent;
  38. }
  39. doctype = parent_df[0].parent;
  40. }
  41. }
  42. if(user==="Administrator" || user_roles.indexOf("Administrator")!==-1) {
  43. perm[0].read = 1;
  44. }
  45. if(docname && !wn.perm.has_only_permitted_data(doctype, docname)) {
  46. // if has restricted data, return not permitted
  47. return perm;
  48. }
  49. var docperms = wn.model.get("DocPerm", {parent: doctype});
  50. $.each(docperms, function(i, p) {
  51. // if user has this role
  52. if(user_roles.indexOf(p.role)!==-1 &&
  53. (!docname || wn.perm.has_match(p, doctype, docname))) {
  54. var permlevel = cint(p.permlevel);
  55. if(!perm[permlevel]) {
  56. perm[permlevel] = {};
  57. }
  58. $.each(wn.perm.rights, function(i, key) {
  59. perm[permlevel][key] = perm[permlevel][key] || (p[key] || 0);
  60. });
  61. }
  62. });
  63. return perm;
  64. },
  65. has_only_permitted_data: function(doctype, docname) {
  66. var restrictions = wn.defaults.get_restrictions();
  67. if(!restrictions || $.isEmptyObject(restrictions)) {
  68. return true;
  69. }
  70. // prepare restricted fields
  71. var fields_to_check = wn.perm.get_restricted_fields(doctype, docname, restrictions);
  72. // loop and find if has restricted data
  73. var has_restricted_data = false;
  74. var doc = wn.model.get_doc(doctype, docname);
  75. $.each(fields_to_check, function(i, df) {
  76. if(doc[df.fieldname] && restrictions[df.options].indexOf(doc[df.fieldname])===-1) {
  77. has_restricted_data = true;
  78. return false;
  79. }
  80. });
  81. return !has_restricted_data;
  82. },
  83. get_restricted_fields: function(doctype, docname, restrictions) {
  84. var fields_to_check = wn.meta.get_restricted_fields(doctype, docname,
  85. Object.keys(restrictions));
  86. if(Object.keys(restrictions).indexOf(doctype)!==-1) {
  87. fields_to_check = fields_to_check.concat(
  88. {label: "Name", fieldname: name, options: doctype});
  89. }
  90. return fields_to_check;
  91. },
  92. has_match: function(docperm, doctype, docname) {
  93. if(!docperm.match) return true;
  94. if(docperm.match==="owner") {
  95. var doc = wn.model.get_doc(doctype, docname);
  96. if(doc.owner===user) {
  97. return true;
  98. }
  99. }
  100. return false;
  101. },
  102. get_match_rules: function(doctype) {
  103. var match_rules = {};
  104. // Rule for owner match
  105. var owner_match = false;
  106. $.each(wn.model.get("DocPerm", {parent:doctype}), function(i, docperm) {
  107. if(docperm.match==="owner") {
  108. owner_match = true;
  109. } else {
  110. owner_match = false;
  111. return false;
  112. }
  113. });
  114. if(owner_match) match_rules["Created By"] = user;
  115. // Rule for restrictions
  116. var restrictions = wn.defaults.get_restrictions();
  117. if(restrictions && !$.isEmptyObject(restrictions)) {
  118. $.each(wn.perm.get_restricted_fields(doctype, null, restrictions), function(i, df) {
  119. match_rules[df.label] = restrictions[df.options];
  120. });
  121. }
  122. return match_rules;
  123. },
  124. get_field_display_status: function(df, doc, perm, explain) {
  125. if(!doc) return "Write";
  126. perm = perm || wn.perm.get_perm(doc.doctype, doc.name);
  127. if(!df.permlevel) df.permlevel = 0;
  128. var p = perm[df.permlevel];
  129. var status = "None";
  130. // permission
  131. if(p) {
  132. if(p.write && !df.disabled) {
  133. status = "Write";
  134. } else if(p.read) {
  135. status = "Read";
  136. }
  137. }
  138. if(explain) console.log("By Permission:" + status);
  139. // hidden
  140. if(cint(df.hidden)) status = "None";
  141. if(explain) console.log("By Hidden:" + status);
  142. // hidden due to dependency
  143. if(cint(df.hidden_due_to_dependency)) status = "None";
  144. if(explain) console.log("By Hidden Due To Dependency:" + status);
  145. // submit
  146. if(status==="Write" && cint(doc.docstatus) > 0) status = "Read";
  147. if(explain) console.log("By Submit:" + status);
  148. // allow on submit
  149. var allow_on_submit = df.fieldtype==="Table" ? 0 : cint(df.allow_on_submit);
  150. if(status==="Read" && allow_on_submit && cint(doc.docstatus)===1 && p.write) {
  151. status = "Write";
  152. }
  153. if(explain) console.log("By Allow on Submit:" + status);
  154. // workflow state
  155. if(status==="Read" && cur_frm && cur_frm.state_fieldname) {
  156. // fields updated by workflow must be read-only
  157. if(cint(cur_frm.read_only) ||
  158. in_list(cur_frm.states.update_fields, df.fieldname) ||
  159. df.fieldname==cur_frm.state_fieldname) {
  160. status = "Read";
  161. }
  162. }
  163. if(explain) console.log("By Workflow:" + status);
  164. // read only field is checked
  165. if(status==="Write" && cint(df.read_only)) {
  166. status = "Read";
  167. }
  168. if(explain) console.log("By Read Only:" + status);
  169. return status;
  170. },
  171. });