mpe_columnlevelsecurity.sas
Go to the documentation of this file.
1 /**
2  @file
3  @brief Filters a table with CLS rules
4  @details Implements CLS as per the rules described here:
5 
6  https://docs.datacontroller.io/column-level-security/
7 
8  Usage:
9 
10  %mpe_columnlevelsecurity(TGTLIB,TGTDS,work.inds
11  ,mode=VIEW
12  ,clsds=dc.mpe_cls
13  ,groupds=work.groups
14  ,outds=work.final
15  ,outmeta=work.cls_rules
16  )
17 
18 
19  @param [in] tgtlib The libref of the target table
20  @param [in] tgtds The dataset reference of the target table
21  @param [in] inds A two-level (lib.ds) reference to the WORK table to which to
22  apply the column filter rules
23  @param [in] mode= (VIEW) Either VIEW or EDIT to indicate whether the
24  resulting table is intended to be viewable or editable.
25  @param [in] groupds= (work.groups)A two-level (lib.ds) reference to a dataset
26  containing the list of groups of which the current user is a member. The
27  column containing the group name should be called `groupname`.
28  @param [in] clsds= (work.clsds) A two-level (lib.ds) reference to the
29  configuration table containing the CLS rules to apply.
30  @param [out] outds= (WORK.CLSVIEW) A two-level (lib.ds) reference to the WORK
31  dataset to create
32  @param [out] outmeta= (WORK.CLS_RULES)The rule metadata, with the following
33  structure:
34  |CLS_VARIABLE_NM:$32.|CLS_HIDE:best.|
35  |---|---|---|---|---|
36  |`SOME_VARIABLE`|`0 `|
37  |`VAR3`|`1 `|
38 
39 
40  <h4> SAS Macros </h4>
41 
42  @author 4GL Apps Ltd
43  @copyright 4GL Apps Ltd. This code may only be used within Data Controller
44  and may not be re-distributed or re-sold without the express permission of
45  4GL Apps Ltd.
46 **/
47 
48 %macro mpe_columnlevelsecurity(tgtlib,tgtds,inds
49  ,mode=VIEW
50  ,groupds=work.groups
51  ,clsds=work.clsview
52  ,outds=CLSVIEW
53  ,outmeta=work.cls_rules
54 );
55 
56 %local col_list is_admin;
57 /* filter for the appropriate rules */
58 proc sql;
59 create table &outmeta as
60  select CLS_VARIABLE_NM,
61  min(case when CLS_HIDE=1 then 1 else 0 end) as CLS_HIDE
62  from &clsds
63  where &dc_dttmtfmt. lt tx_to
64  and CLS_SCOPE in ("&mode",'ALL')
65  and CLS_ACTIVE=1
66  %if &mode=VIEW %then %do;
67  and CLS_HIDE ne 1
68  %end;
69  and upcase(CLS_GROUP) in (select upcase(groupname) from &groupds)
70  and CLS_LIBREF="%upcase(&tgtlib)"
71  and CLS_TABLE="%upcase(&tgtds)"
72  group by CLS_VARIABLE_NM;
73 
74 %let is_admin=0;
75 proc sql;
76 select count(*) into: is_admin from &groupds where groupname="&MPEADMINS";
77 %put &sysmacroname: &=is_admin;
78 %if %mf_nobs(work.cls_rules) = 0 or &is_admin>0 %then %do;
79  %put &sysmacroname: no CLS rules to apply;
80  %put &=is_admin;
81  /* copy using append for speed */
82  data &outds;
83  set &inds;
84  stop;
85  run;
86  proc append base=&outds data=&inds;
87  run;
88  /* ensure CLS_RULES is empty in case of admin */
89  data &outmeta;
90  set &outmeta;
91  stop;
92  run;
93  %return;
94 %end;
95 %else %if &mode=VIEW %then %do;
96  /* just send back the relevant columns */
97  %let col_list=0;
98  proc sql noprint;
99  select CLS_VARIABLE_NM into: col_list separated by ' ' from &outmeta
100  where CLS_HIDE=0;
101 
102  %if &col_list=0 %then %do;
103  /*
104  We have columns that are set to CLS_HIDE=1 but we do not have any to
105  explicitly show. Therefore we assume all columns are to be shown except
106  those that are explicitly hidden.
107  */
108  proc sql noprint;
109  select CLS_VARIABLE_NM into: col_list separated by ' ' from &outmeta
110  where CLS_HIDE=1;
111 
112  data &outds;
113  set &inds;
114  drop &col_list;
115  run;
116  %end;
117  %else %do;
118  data &outds;
119  set &inds;
120  keep &col_list;
121  run;
122  %end;
123 %end;
124 %else %if &mode=EDIT %then %do;
125  /*
126  In this case we pass all columns and the frontend will filter out the
127  ones that are not allowed to be edited.
128  */
129  data &outds;
130  set &inds;
131  stop;
132  run;
133  proc append base=&outds data=&inds;
134  run;
135 %end;
136 %else %do;
137  %put &sysmacroname: invalid mode - &mode!;
138  %abort;
139 %end;
140 
141 %mend mpe_columnlevelsecurity;