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.
 
 
 
 
 
 

195 line
5.4 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", "restricted"],
  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_unrestricted_access(doctype, docname, perm[0].restricted)) {
  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. var permlevel = cint(p.permlevel);
  54. if(!perm[permlevel]) {
  55. perm[permlevel] = {};
  56. }
  57. $.each(wn.perm.rights, function(i, key) {
  58. if(key=="restricted") {
  59. perm[permlevel][key] = (perm[permlevel][key] || 1) && (p[key] || 0);
  60. } else {
  61. perm[permlevel][key] = perm[permlevel][key] || (p[key] || 0);
  62. }
  63. });
  64. }
  65. });
  66. return perm;
  67. },
  68. has_unrestricted_access: function(doctype, docname, restricted) {
  69. var restrictions = wn.defaults.get_restrictions();
  70. var doc = wn.model.get_doc(doctype, docname);
  71. if(restricted) {
  72. if(doc.owner==user) return true;
  73. if(!restrictions || $.isEmptyObject(restrictions)) {
  74. return false;
  75. }
  76. } else {
  77. if(!restrictions || $.isEmptyObject(restrictions)) {
  78. return true;
  79. }
  80. }
  81. // prepare restricted fields
  82. var fields_to_check = wn.perm.get_restricted_fields(doctype, docname, restrictions);
  83. // loop and find if has restricted data
  84. var has_restricted_data = false;
  85. var doc = wn.model.get_doc(doctype, docname);
  86. $.each(fields_to_check, function(i, df) {
  87. if(doc[df.fieldname] && restrictions[df.options].indexOf(doc[df.fieldname])===-1) {
  88. has_restricted_data = true;
  89. return false;
  90. }
  91. });
  92. return !has_restricted_data;
  93. },
  94. get_restricted_fields: function(doctype, docname, restrictions) {
  95. var fields_to_check = wn.meta.get_restricted_fields(doctype, docname,
  96. Object.keys(restrictions));
  97. if(Object.keys(restrictions).indexOf(doctype)!==-1) {
  98. fields_to_check = fields_to_check.concat(
  99. {label: "Name", fieldname: name, options: doctype});
  100. }
  101. return fields_to_check;
  102. },
  103. get_match_rules: function(doctype) {
  104. var match_rules = {};
  105. // Rule for restrictions
  106. var restrictions = wn.defaults.get_restrictions();
  107. if(restrictions && !$.isEmptyObject(restrictions)) {
  108. $.each(wn.perm.get_restricted_fields(doctype, null, restrictions), function(i, df) {
  109. match_rules[df.label] = restrictions[df.options];
  110. });
  111. }
  112. return match_rules;
  113. },
  114. get_field_display_status: function(df, doc, perm, explain) {
  115. if(!doc) return "Write";
  116. perm = perm || wn.perm.get_perm(doc.doctype, doc.name);
  117. if(!df.permlevel) df.permlevel = 0;
  118. var p = perm[df.permlevel];
  119. var status = "None";
  120. // permission
  121. if(p) {
  122. if(p.write && !df.disabled) {
  123. status = "Write";
  124. } else if(p.read) {
  125. status = "Read";
  126. }
  127. }
  128. if(explain) console.log("By Permission:" + status);
  129. // hidden
  130. if(cint(df.hidden)) status = "None";
  131. if(explain) console.log("By Hidden:" + status);
  132. // hidden due to dependency
  133. if(cint(df.hidden_due_to_dependency)) status = "None";
  134. if(explain) console.log("By Hidden Due To Dependency:" + status);
  135. // submit
  136. if(status==="Write" && cint(doc.docstatus) > 0) status = "Read";
  137. if(explain) console.log("By Submit:" + status);
  138. // allow on submit
  139. var allow_on_submit = df.fieldtype==="Table" ? 0 : cint(df.allow_on_submit);
  140. if(status==="Read" && allow_on_submit && cint(doc.docstatus)===1 && p.write) {
  141. status = "Write";
  142. }
  143. if(explain) console.log("By Allow on Submit:" + status);
  144. // workflow state
  145. if(status==="Read" && cur_frm && cur_frm.state_fieldname) {
  146. // fields updated by workflow must be read-only
  147. if(cint(cur_frm.read_only) ||
  148. in_list(cur_frm.states.update_fields, df.fieldname) ||
  149. df.fieldname==cur_frm.state_fieldname) {
  150. status = "Read";
  151. }
  152. }
  153. if(explain) console.log("By Workflow:" + status);
  154. // read only field is checked
  155. if(status==="Write" && cint(df.read_only)) {
  156. status = "Read";
  157. }
  158. if(explain) console.log("By Read Only:" + status);
  159. return status;
  160. },
  161. });