I got a requirement to adjust the visibility of the "Edit" button on Knowledge articles

Arindam Ghosh
Mega Guru

Detail requirement is as below:

The "Edit" button in a knowledge article should only be available to those users, who:

a. Are the author of the respective Knowledge article, OR

b. Are part of the Assignment Group of the Configuration Item used for creating the Knowledge article

----------------------------------------------------------------------------------

While analyzing this I found that in "kb_view_common_header_toolbar" UI Macro the below condition is coded for 'Edit' button.

<j:if test="${showUpdateAction}">

<button id="editArticle" title="${gs.getMessage('Edit content')}" class="btn btn-default navbar-btn snc-article-header-toolbar-button">${gs.getMessage("Edit")}</button>

</j:if>

Here variable showUpdateAction is being set in another UI Macro "kb_view_common"

After that I am lost. Not exactly able to understand how and where the conditions are written and how can I modify to implement my requirements.

Any help is greatly appreciated. Thanks in advance.

1 ACCEPTED SOLUTION

Your question got me to rethink my answer.



I tought instead of doing all these scripts override which are global and override OOTB stuff, you can simply create a scripted user criteria and apply it as the only user criteria for the required knowledge bases. However, these user criteria are somehow cached in the user session, so for example: a user is the author of an article, he changes the author to someone else so that he should no longer have write access, however he keeps the write access because of a weird caching with user criteria. I conclude that user criteria should not be used to be dynamic with the record.



However, your point about the canContribute method is good, you could in fact make this simpler by overriding the canContribute method that is defined in KBCommon. And remove the previous overriding I proposed:



var KBCommon = Class.create();


KBCommon.prototype = Object.extendsObject(KBCommonSNC, {


      initialize: function(){


              this._knowledgeHelper = new SNC.KnowledgeHelper();


              this._knowledgeHelper.canContribute = function(knowledgeGR){


                      var defaultContribute = new SNC.KnowledgeHelper().canContribute(knowledgeGR);


                      if(!defaultContribute){


                              return false;


                      }


                     


                      var isAdmin = gs.hasRole('admin');


                      if(isAdmin){


                              return true;


                      }


                     


                      var isKnowledgeBase = knowledgeGR.getRecordClassName() == 'kb_knowledge_base';


                      if(isKnowledgeBase){


                              return true;


                      }


                     


                      var isAuthor = knowledgeGR.author == gs.getUserID();


                      if(isAuthor){


                              return true;


                      }


                     


                      var isMemberOfCIGroup = gs.getUser().isMemberOf(knowledgeGR.cmdb_ci.support_group);


                      if(isMemberOfCIGroup){


                              return true;


                      }


                     


                      return false;


              };


      },


     


      type: 'KBCommon'


});


View solution in original post

25 REPLIES 25

You can override modify the KBKnowledge script include which is used to override the script handling the security in KMv3.



What I would do is override the canWrite method (you might also need to override the canDelete method):


var KBKnowledge = Class.create();



KBKnowledge.prototype = Object.extendsObject(KBKnowledgeSNC, {


      _old_canWrite: new KBKnowledgeSNC().canWrite,


     


      canWrite: function(knowledgeGR) {


              var isAuthor = knowledgeGR.author == gs.getUserID();


              var isMemberOfCIGroup = gs.getUser().isMemberOf(knowledgeGR.cmdb_ci.support_group);


              var isAdmin = gs.hasRole('admin');


             


              return this._old_canWrite(knowledgeGR) && (isAuthor || isMemberOfCIGroup || isAdmin);


      },



      type: "KBKnowledge"


});



This does the ACL part, however, the OOTB script include used for the Edit button does not correctly evaluate the ACL, so again you need to extend it to make the button available based on the ACL:


var KBViewModel = Class.create();



KBViewModel.prototype =   Object.extendsObject(KBViewModelSNC, {


      _old_populateAdditionalInformation: new KBViewModelSNC()._populateAdditionalInformation,


     


      _populateAdditionalInformation: function(){


              this._old_populateAdditionalInformation();


              this.isEditable = this.knowledgeRecord.canWrite();


      },


     


      type: "KBViewModel"


});



I consider theses extended function as minor as we still call the OOTB ones and only add to them, however this could require maintenance in the future (these scripts are changed with the knowledge versioning coming in Jakarta, but I'm pretty sure it will still be OK as we only add to the existing functions).


Hi Laurent,



Overriding the canWrite method is working fine (First script you provided). So Only the expected users able to modify the article. For all others it became grayed out. But the second script where we are trying to hide the button is not working.



Can we override canContribute method to make it work as based on the canContribute method we are displaying the Edit button.



Thanks,


Arindam


Your question got me to rethink my answer.



I tought instead of doing all these scripts override which are global and override OOTB stuff, you can simply create a scripted user criteria and apply it as the only user criteria for the required knowledge bases. However, these user criteria are somehow cached in the user session, so for example: a user is the author of an article, he changes the author to someone else so that he should no longer have write access, however he keeps the write access because of a weird caching with user criteria. I conclude that user criteria should not be used to be dynamic with the record.



However, your point about the canContribute method is good, you could in fact make this simpler by overriding the canContribute method that is defined in KBCommon. And remove the previous overriding I proposed:



var KBCommon = Class.create();


KBCommon.prototype = Object.extendsObject(KBCommonSNC, {


      initialize: function(){


              this._knowledgeHelper = new SNC.KnowledgeHelper();


              this._knowledgeHelper.canContribute = function(knowledgeGR){


                      var defaultContribute = new SNC.KnowledgeHelper().canContribute(knowledgeGR);


                      if(!defaultContribute){


                              return false;


                      }


                     


                      var isAdmin = gs.hasRole('admin');


                      if(isAdmin){


                              return true;


                      }


                     


                      var isKnowledgeBase = knowledgeGR.getRecordClassName() == 'kb_knowledge_base';


                      if(isKnowledgeBase){


                              return true;


                      }


                     


                      var isAuthor = knowledgeGR.author == gs.getUserID();


                      if(isAuthor){


                              return true;


                      }


                     


                      var isMemberOfCIGroup = gs.getUser().isMemberOf(knowledgeGR.cmdb_ci.support_group);


                      if(isMemberOfCIGroup){


                              return true;


                      }


                     


                      return false;


              };


      },


     


      type: 'KBCommon'


});


I tried this, but no luck. Didn't work for me


Hmm, exact same script?



Are your users having too much access (write access while they should not) or not enough (cannot write while they should).



On which version are you?