Wednesday, January 18, 2012

How to hide buttons for unauthorized users

In SAP CRM, it sometimes occurs that buttons are visible and clickable, even while the current user is not authorized to execute the action. It seems to depend on the developer that has built the screen whether this has been properly taken care of or not.

Fortunately, we have the enhancement framework, so we can easily implement this by enhancement ourselves. Let's take a look at some different views in a CRM 7.0 EhP1 system.
First we take a look at the coding in component BP_HEAD_SEARCH view BP_HEAD_SEARCH/MainSearchResult controller method do_prepare_output.

Here, we see the following coding:

IF gt_button IS INITIAL.
*   here the name of the button and the event is determine
    ls_button-type     = cl_thtmlb_util=>gc_icon_new.
    ls_button-text     = cl_wd_utilities=>get_otr_text_by_alias( 'CRM_UIU_BP/CORPORATEACCOUNT' ). "#EC NOTEXT
    ls_button-on_click = 'CREATECORP'.                      "#EC NOTEXT
*   check if button should be enabled according to UIU_COMP authorization values
    IF cl_crm_uiu_bp_authority=>bp_check_authority_create( iv_object_type = if_crm_bupa_uiu_otype~gc_otyp_corp_account ) = abap_true.
      ls_button-enabled  = gc_x.
    ENDIF.
    APPEND ls_button TO gt_button.
    CLEAR ls_button.

This is standard SAP coding. I have marked the code where an authorisation check is done, and depending on the outcome, the button is either greyed out, or clickable.

So, now, let's take a look at for instance view BT126S_APPT/ApptSR. In this case, in the do_prepare_output, there is no authority check at all. So, what happens if an unauthorized user clicks the button?

Hopefully, an unauthorized user will get an error message telling that the user is not authorized. Of course, this is not the best option. My guess would be, from a usability perspective, that it would be better to check the authorization before placing the button on the screen, just like in the BP_HEAD_SEARCH/MainSearchResult.

So, we can enhance the view as described here.
Then, we redefine the do_prepare_output, and we check on authorization before appending the button, and if not authorized, we simply state 'ls_button-enabled = abap_false'. If authorization is ok, we state 'ls_button-enabled  = abap_true'. Easy as that.


So, how do we know which authorization to check on? This certainly depends on the function provided by the button, but you can easily find it by having an unauthorized user click the button while an authorization trace is running. If it is due to missing UIU_COMP authorization, it will probably not show up, as this is loaded when starting the webclient, so that will require some more analysis.


Now that we know which authorization object is causing the error, we can code the auth check easily using the following statements:
AUTHORITY-CHECK OBJECT {object}
ID {ID_1} FIELD {value_1}
ID {ID_2} FIELD {value_2}
ID ... FIELD ...
IF sy-subrc EQ 0 .
   ls_button-enabled  = abap_true.
ELSE.
   ls_button-enabled = abap_false .
ENDIF.
So, for instance we could check whether the user is authorized to delete activities before adding the delete-button. What a coincidence this is actually a good example, as deleting activities in many cases is not applied to users...

The same of course applies to the one-click-actions that are applied to many assignment blocks. It seems pretty logical to check authorization before adding a button there as well.

2 comments:

  1. If you need to disable a button you can also follow this:

    For instance assume you want to disable a button in the sales / quotation module

    1) The component is BT115QS_SLSQ (you can find this by F2 in IE)

    2) USE THE ENHANCEMENT SET

    3) Click Display
    4) Go to the view BT115QS_SLSQ/SlsQuotSR and enhance this view
    5) Click the folder “Request Processing”
    6) There is a method DO_PREPARE_OUTPUT that has been defined by SAP. You must right click this method and “Redefine”:


    7) In the code first call the super class.
    8) Then put in code to disable the button
    9) method DO_PREPARE_OUTPUT.

    *Description: To disable the NEW button in the sales quotation search results screen.

    *Call super method first as we are redefining this method
    CALL METHOD SUPER->DO_PREPARE_OUTPUT
    EXPORTING
    IV_FIRST_TIME = IV_FIRST_TIME
    .

    *Get reference to a button of the type CRMT_thtmlb_button
    DATA: ls_button TYPE crmt_thtmlb_button.

    *enabled='X' to enable and enabled='' to disable
    ls_button-enabled = ' '.

    *Modify control set of buttons (gt_button) where the name of the button is NEW.
    MODIFY gt_button FROM ls_button TRANSPORTING enabled WHERE on_click = 'NEW'.
    endmethod.

    ReplyDelete
  2. Hi Pieter,

    from a user perspective, shouldn't it be nice if the user is told why all the functions are currently disabled? Then he/she can actually make a printscreen for the authorization maintenance team and get the proper authorizations. I also understand that if you have users who can see the screen, but just can't use some functionalities because they're not allowed to do so, they don't want an authorization message. But I'm still not sure what's the most userfriendly solution is.

    But from a technical perspective, nice blog!

    Cheers,

    Sander

    ReplyDelete