Page tree
Skip to end of metadata
Go to start of metadata

The following ABAP report is an initial version of report for analyzing roles using various metrics such as number of manually added authorization objects to security role. The algorithm for calculating role toxicity can be easily modified in routine calculate_toxicity. More information about motivation can be found in in thread on SDN forum.

Report
*&---------------------------------------------------------------------*
*& Report  ZBC_ROLE_ANALYSIS
*&---------------------------------------------------------------------*
REPORT  zbc_role_analysis.

TABLES: agr_define.
TYPE-POOLS slis.

TYPES: BEGIN OF ts_role,
      agr_name TYPE agr_define-agr_name,
      parent_agr TYPE agr_define-parent_agr,
      rtype TYPE c LENGTH 1,
      toxicity TYPE i,
      no_menu TYPE i,
      no_auth TYPE i,
      no_maut TYPE i,
      no_sobj TYPE i,
      no_morg TYPE i,
      no_moau TYPE i,
      no_wild TYPE i,
      no_user TYPE i,
      no_cdoc TYPE i,
      no_cdus TYPE i,
       END OF ts_role,
       tt_role TYPE STANDARD TABLE OF ts_role.

SELECT-OPTIONS: s_name FOR agr_define-agr_name.
PARAMETERS: p_chdoc TYPE c AS CHECKBOX.

START-OF-SELECTION.
  PERFORM run.

*&---------------------------------------------------------------------*
*&      Form  DISPLAY_ALV
*&---------------------------------------------------------------------*
FORM display_alv USING ut_data TYPE tt_role.

  DATA: lt_fc TYPE slis_t_fieldcat_alv,
        ls_fc TYPE slis_fieldcat_alv.

  ls_fc-fieldname = 'AGR_NAME'.
  ls_fc-ref_tabname = 'AGR_DEFINE'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'RTYPE'.
  ls_fc-seltext_l = 'Type'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'NO_USER'.
  ls_fc-seltext_l = '# of Users'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'TOXICITY'.
  ls_fc-seltext_l = 'Toxicity'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'NO_AUTH'.
  ls_fc-seltext_l = '# of Auth.'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'NO_MAUT'.
  ls_fc-seltext_l = '# of Man.Auth.'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'NO_MENU'.
  ls_fc-seltext_l = '# of MItems'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'NO_SOBJ'.
  ls_fc-seltext_l = '# of S_*'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'NO_MORG'.
  ls_fc-seltext_l = '# of Mod. Org.'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'NO_MOAU'.
  ls_fc-seltext_l = '# of Mod. Auth.'.
  APPEND ls_fc TO lt_fc.

  CLEAR ls_fc.
  ls_fc-fieldname = 'NO_WILD'.
  ls_fc-seltext_l = '# of Wildcards'.
  APPEND ls_fc TO lt_fc.

  IF p_chdoc EQ 'X'.
    CLEAR ls_fc.
    ls_fc-fieldname = 'NO_CDOC'.
    ls_fc-seltext_l = '# of Change Docs'.
    ls_fc-emphasize = 'C400'.
    APPEND ls_fc TO lt_fc.

    CLEAR ls_fc.
    ls_fc-fieldname = 'NO_CDUS'.
    ls_fc-seltext_l = 'Changed by # users'.
    ls_fc-emphasize = 'C400'.
    APPEND ls_fc TO lt_fc.
  ENDIF.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program      = sy-repid
      i_callback_user_command = 'UC'
      i_grid_title            = 'Roles'
      it_fieldcat             = lt_fc
    TABLES
      t_outtab                = ut_data
    EXCEPTIONS
      OTHERS                  = 0.

ENDFORM.                    " DISPLAY_ALV
*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
FORM get_data CHANGING ct_data TYPE tt_role.

  FIELD-SYMBOLS: <row> TYPE ts_role,
                 <hier> TYPE agr_hier,
                 <usorg> TYPE usorg,
                 <1250> TYPE agr_1250,
                 <1251> TYPE agr_1251,
                 <flag> TYPE agr_flags.
  DATA: lt_hier TYPE STANDARD TABLE OF agr_hier,
        lt_1250 TYPE STANDARD TABLE OF agr_1250,
        lt_1251 TYPE STANDARD TABLE OF agr_1251,
        lt_usorg TYPE STANDARD TABLE OF usorg,
        lt_flags TYPE STANDARD TABLE OF agr_flags.

  SELECT agr_name parent_agr
    INTO CORRESPONDING FIELDS OF TABLE ct_data
    FROM agr_define
    WHERE agr_name IN s_name.
  SORT ct_data BY agr_name.
  CHECK NOT ct_data IS INITIAL.

* Determine role type: S - single, C - composite, D - derived
  SELECT * INTO TABLE lt_flags FROM agr_flags
    FOR ALL ENTRIES IN ct_data
    WHERE agr_name EQ ct_data-agr_name AND
          flag_type EQ 'COLL_AGR'.

  LOOP AT ct_data ASSIGNING <row>.
    READ TABLE lt_flags ASSIGNING <flag>
      WITH KEY agr_name = <row>-agr_name flag_type = 'COLL_AGR'.
    CHECK sy-subrc EQ 0.
    IF <flag>-flag_value EQ space.
      IF <row>-parent_agr EQ space.
        <row>-rtype = 'S'.
      ELSE.
        <row>-rtype = 'D'.
      ENDIF.
    ELSE.
      <row>-rtype = 'C'.
    ENDIF.
  ENDLOOP.

* Get # of menu items
  SELECT * INTO TABLE lt_hier FROM agr_hier
    FOR ALL ENTRIES IN ct_data
    WHERE agr_name EQ ct_data-agr_name.

  LOOP AT lt_hier ASSIGNING <hier> WHERE folder EQ space.
    IF NOT <row> IS ASSIGNED OR <row>-agr_name NE <hier>-agr_name.
      READ TABLE ct_data ASSIGNING <row>
        WITH KEY agr_name = <hier>-agr_name BINARY SEARCH.
      CHECK sy-subrc EQ 0.
    ENDIF.
    ADD 1 TO <row>-no_menu.
  ENDLOOP.

* Get # of auth. objects
  SELECT * INTO TABLE lt_1250 FROM agr_1250
    FOR ALL ENTRIES IN ct_data
    WHERE agr_name EQ ct_data-agr_name.

  LOOP AT lt_1250 ASSIGNING <1250> WHERE deleted EQ space.
    IF NOT <row> IS ASSIGNED OR <row>-agr_name NE <1250>-agr_name.
      READ TABLE ct_data ASSIGNING <row>
        WITH KEY agr_name = <1250>-agr_name BINARY SEARCH.
      CHECK sy-subrc EQ 0.
    ENDIF.
    ADD 1 TO <row>-no_auth.
    IF <1250>-modified EQ 'U'.
      ADD 1 TO <row>-no_maut.
    ENDIF.
    IF <1250>-modified EQ 'M'.
      ADD 1 TO <row>-no_moau.
    ENDIF.
    IF <1250>-object(2) EQ 'S_' AND
       <1250>-object NE 'S_TCODE'.
      ADD 1 TO <row>-no_sobj.
    ENDIF.
  ENDLOOP.

* Get auth. values
  SELECT * INTO TABLE lt_1251 FROM agr_1251
    FOR ALL ENTRIES IN ct_data
    WHERE agr_name EQ ct_data-agr_name.

* Get all modified org. values
  SELECT * INTO TABLE lt_usorg FROM usorg.
  LOOP AT lt_usorg ASSIGNING <usorg>.
    LOOP AT lt_1251 ASSIGNING <1251>
      WHERE field EQ <usorg>-field AND low NE <usorg>-varbl.
      READ TABLE ct_data ASSIGNING <row>
        WITH KEY agr_name = <1251>-agr_name BINARY SEARCH.
      CHECK sy-subrc EQ 0.
      ADD 1 TO <row>-no_morg.
    ENDLOOP.
  ENDLOOP.

  LOOP AT lt_1251 ASSIGNING <1251> WHERE low EQ '*'.
    READ TABLE ct_data ASSIGNING <row>
        WITH KEY agr_name = <1251>-agr_name BINARY SEARCH.
    CHECK sy-subrc EQ 0.
    ADD 1 TO <row>-no_wild.
  ENDLOOP.

  PERFORM get_user_assignments CHANGING ct_data.
  IF p_chdoc EQ 'X'.
    PERFORM get_change_docs CHANGING ct_data.
  ENDIF.

  LOOP AT ct_data ASSIGNING <row>.
    PERFORM calculate_toxicity CHANGING <row>.
  ENDLOOP.

ENDFORM.                    " GET_DATA
*&---------------------------------------------------------------------*
*&      Form  CALCULATE_TOXICITY
*&---------------------------------------------------------------------*
FORM calculate_toxicity CHANGING c_row TYPE ts_role.
  ADD c_row-no_maut TO c_row-toxicity.
  ADD c_row-no_morg TO c_row-toxicity.
  ADD c_row-no_moau TO c_row-toxicity.
* XXX - name compliance
ENDFORM.                    " CALCULATE_TOXICITY
*&---------------------------------------------------------------------*
*&      Form  UC
*&---------------------------------------------------------------------*
FORM uc USING u_ucomm LIKE sy-ucomm                         "#EC CALLED
              us_selfield TYPE slis_selfield.

  DATA role TYPE agr_define-agr_name.
  IF u_ucomm EQ '&IC1' AND us_selfield-fieldname EQ 'AGR_NAME'.
    AUTHORITY-CHECK OBJECT 'S_TCODE'
             ID 'TCD' FIELD 'PFCG'.
    IF sy-subrc = 0.
      role = us_selfield-value.
      CALL FUNCTION 'PRGN_SHOW_EDIT_AGR'
        EXPORTING
          agr_name      = role
        EXCEPTIONS
          agr_not_found = 0
          OTHERS        = 0.                                "#EC FB_RC
    ELSE.
      MESSAGE e861(01).
    ENDIF.
  ENDIF.
ENDFORM.                    "UC
*&---------------------------------------------------------------------*
*&      Form  RUN
*&---------------------------------------------------------------------*
FORM run.
  DATA lt_data TYPE tt_role.
  PERFORM get_data CHANGING lt_data.
  PERFORM display_alv USING lt_data.
ENDFORM.                    " RUN
*&---------------------------------------------------------------------*
*&      Form  GET_USER_ASSIGNMENTS
*&---------------------------------------------------------------------*
FORM get_user_assignments  CHANGING ct_data TYPE tt_role.

  FIELD-SYMBOLS: <agr_users> TYPE agr_users,
                 <row> TYPE ts_role.
  DATA lt_agr_users TYPE STANDARD TABLE OF agr_users.

  CHECK NOT ct_data IS INITIAL.

* Calculate # of users for each role
  SELECT * INTO TABLE lt_agr_users FROM agr_users
    FOR ALL ENTRIES IN ct_data
    WHERE agr_name EQ ct_data-agr_name AND
          from_dat LE sy-datum AND
          to_dat GE sy-datum.

  LOOP AT lt_agr_users ASSIGNING <agr_users>.
    READ TABLE ct_data ASSIGNING <row>
        WITH KEY agr_name = <agr_users>-agr_name BINARY SEARCH.
    CHECK sy-subrc EQ 0.
    ADD 1 TO <row>-no_user.
  ENDLOOP.

ENDFORM.                    " GET_USER_ASSIGNMENTS
*&---------------------------------------------------------------------*
*&      Form  GET_CHANGE_DOCS
*&---------------------------------------------------------------------*
FORM get_change_docs  CHANGING ct_data TYPE tt_role.

  FIELD-SYMBOLS: <role> TYPE ts_role,
                 <cdoc> TYPE cdhdr.
  DATA: lt_cdhdr TYPE STANDARD TABLE OF cdhdr,
        lt_cdpos TYPE STANDARD TABLE OF cdpos,
        lt_tmp TYPE STANDARD TABLE OF cdhdr,
        lt_id TYPE RANGE OF cdhdr-objectid,
        ls_id LIKE LINE OF lt_id.

  CHECK ct_data IS NOT INITIAL.

  ls_id-sign = 'I'.
  ls_id-option = 'EQ'.
  LOOP AT ct_data ASSIGNING <role>.
    ls_id-low = <role>-agr_name.
    APPEND ls_id TO lt_id.
  ENDLOOP.

  SELECT * INTO TABLE lt_cdhdr FROM cdhdr
    WHERE objectclas EQ 'PFCG' AND
          objectid IN lt_id.
  CHECK lt_cdhdr IS NOT INITIAL.

* Do not include change docs for user assignment
  SELECT * INTO TABLE lt_cdpos FROM cdpos
    FOR ALL ENTRIES IN lt_cdhdr
    WHERE objectclas = lt_cdhdr-objectclas AND
          objectid = lt_cdhdr-objectid AND
          changenr = lt_cdhdr-changenr AND
          tabname NE 'AGR_USERS'.

  LOOP AT ct_data ASSIGNING <role>.
    REFRESH lt_tmp.
    LOOP AT lt_cdhdr ASSIGNING <cdoc> WHERE objectid EQ <role>-agr_name.
* Check if change doc is not user assignment
      READ TABLE lt_cdpos TRANSPORTING NO FIELDS
        WITH KEY objectclas = <cdoc>-objectclas
                 objectid = <cdoc>-objectid
                 changenr = <cdoc>-changenr.
      CHECK sy-subrc EQ 0.
      ADD 1 TO <role>-no_cdoc.
      APPEND <cdoc> TO lt_tmp.
    ENDLOOP.
    SORT lt_tmp BY username.
    DELETE ADJACENT DUPLICATES FROM lt_tmp COMPARING username.
    DESCRIBE TABLE lt_tmp LINES <role>-no_cdus.
  ENDLOOP.

ENDFORM.                    " GET_CHANGE_DOCS

2 Comments

  1. Unknown User (qw2d3hp)

    Hi,

    I am getting the below error:

    Syntax Error in program, Line 36 and 37
    Type "SLIS_T_FIELDCAT_ALV" is unknown
    Field "SLIS_T_FIELDCAT_ALV" is unknown. It is neither in one of the specified tables nor defined by a "DATA" statement. 
    Syntax Error in program, Line 36 and 37

    Type "SLIS_T_FIELDCAT_ALV" is unknown

    Field "SLIS_T_FIELDCAT_ALV" is unknown. It is neither in one of the specified tables nor defined by a "DATA" statement. 

    Regards,

    Raghu

  2. Hi,

    I am not an ABAPer but 5 minutes with Google and adding the statement:

    TYPE-POOLS slis.

    after the line:  REPORT zbc_role_analysis.
    solved the problem for me.

    Regards

    Jörg