I have a set of codes that I want to run, only after I have authenticated the user's &sysuserid whether it is granted access in a SAS logical path /Shared Data/yy/zz. To do this, I have to acquire the user's logical group permission that is tagged to zz folder whether it is granted Read and ReadMetadata. I have split my task into 2 parts -
A : get the users assigned groups, in my case 1 user will only have 1 group assigned
B : get the logical tree's object and find out what groups and permission (read & readmetadata) is assigned to it
For part A, I done this by acquiring the information from Person, Logins, Domain and IdentityGroups of the user via metadata_getnobj, metadata_getnasn and metadata_getattr.
For part B, I am stuck at Tree > AccessControls
Attached are the functions I macroed for easy retrieval
Preparing Macros
%macro custom_getnobj(table=, namespace=, outuri=);
data &table;
length &outuri $ 256;
n1=1;
rc1=metadata_getnobj("omsobj:&namespace?@Id contains '.'",n1,&outuri);
do while (rc1>0);
output;
n1+1;
rc1=metadata_getnobj("omsobj:&namespace?@Id contains '.'",n1,&outuri);
end;
drop n1 rc1;
run;
%mend custom_getnobj;
%macro custom_getnasn(intbl=, outtbl=, namespace=, lkpuri=, outuri=);
data &outtbl;
set &intbl;
length &outuri $ 256;
n1=1;
rc1=metadata_getnasn(&lkpuri,"&namespace",n1,&outuri);
do while (rc1>0);
output;
n1+1;
rc1=metadata_getnasn(&lkpuri,"&namespace",n1,&outuri);
end;
drop n1 rc1;
run;
%mend custom_getnasn;
%macro custom_getattr(intbl=, outtbl=, lkpuri=, attrmetaname=, attrcolname=, attrcollen=);
data &outtbl;
set &intbl;
length &attrcolname &attrcollen;
rc=metadata_getattr(&lkpuri,"&attrmetaname",&attrcolname);
drop rc;
run;
%mend custom_getattr;
Calling Macros Part A
/* Get Person Info */
%custom_getnobj(table=metadata_person, namespace=Person, outuri=person_uri);
%custom_getattr(intbl=metadata_person, outtbl=metadata_person, lkpuri=person_uri, attrmetaname=Name, attrcolname=person_name, attrcollen=$60);
%custom_getnasn(intbl=metadata_person, outtbl=metadata_person, namespace=Logins, lkpuri=person_uri, outuri=login_uri);
%custom_getattr(intbl=metadata_person, outtbl=metadata_person, lkpuri=login_uri, attrmetaname=UserId, attrcolname=login_userid, attrcollen=$128);
%custom_getnasn(intbl=metadata_person, outtbl=metadata_person, namespace=Domain, lkpuri=login_uri, outuri=domain_uri);
%custom_getattr(intbl=metadata_person, outtbl=metadata_person, lkpuri=domain_uri, attrmetaname=Name, attrcolname=domain_authname, attrcollen=$60);
%custom_getnasn(intbl=metadata_person, outtbl=metadata_person, namespace=IdentityGroups, lkpuri=person_uri, outuri=idgrp_uri);
%custom_getattr(intbl=metadata_person, outtbl=metadata_person, lkpuri=idgrp_uri, attrmetaname=Name, attrcolname=idgrp_name, attrcollen=$60);
/* Select defaultauth for LAN access and only applicable for group with GRM - */
data metadata_person1;
set metadata_person;
if domain_authname = 'DefaultAuth';
if substr(idgrp_name, 1, length("GRM - ")) = "GRM - ";
run;
Calling Macros Part B
%custom_getnobj(table=metadata_tree, namespace=Tree, outuri=tree_uri);
%custom_getattr(intbl=metadata_tree, outtbl=metadata_tree, lkpuri=tree_uri, attrmetaname=Name, attrcolname=tree_name, attrcollen=$60);
%custom_getnasn(intbl=metadata_tree, outtbl=metadata_tree, namespace=AccessControls, lkpuri=tree_uri, outuri=ace_uri);
%custom_getnasn(intbl=metadata_tree, outtbl=test, namespace=Permissions, lkpuri=ace_uri, outuri=idgrp_uri);
I have figured out the Tree for Part B. It should branch from Tree > AccessControls > Identities > Permissions
Part B
/* Get Tree Info */
%custom_getnobj(table=metadata_tree, namespace=Tree, outuri=tree_uri);
%custom_getattr(intbl=metadata_tree, outtbl=metadata_tree, lkpuri=tree_uri, attrmetaname=Name, attrcolname=tree_name, attrcollen=$60);
%custom_getnasn(intbl=metadata_tree, outtbl=metadata_tree, namespace=AccessControls, lkpuri=tree_uri, outuri=ace_uri);
%custom_getnasn(intbl=metadata_tree, outtbl=metadata_tree, namespace=Identities, lkpuri=ace_uri, outuri=idgrp_uri);
%custom_getattr(intbl=metadata_tree, outtbl=metadata_tree, lkpuri=idgrp_uri, attrmetaname=Name, attrcolname=idgrp_name, attrcollen=$60);
%custom_getnasn(intbl=metadata_tree, outtbl=metadata_tree, namespace=Permissions, lkpuri=ace_uri, outuri=perm_uri);
%custom_getattr(intbl=metadata_tree, outtbl=metadata_tree, lkpuri=perm_uri, attrmetaname=Name, attrcolname=perm_name, attrcollen=$60);
%custom_getattr(intbl=metadata_tree, outtbl=metadata_tree, lkpuri=perm_uri, attrmetaname=Type, attrcolname=perm_type, attrcollen=$100);
%let path = /Shared Data/xx/yy/zz;
%macro filter_tree;
%let folder_cnt = %sysfunc(countw(&path, /));
proc sql;
create table metadata_tree_1 as
select *
from metadata_tree
where 1=1
and perm_name in ( 'Read' 'ReadMetadata' )
and tree_name in
(
/* Only require folders listed in &path */
%do i = 1 %to &folder_cnt;
%let cur_folder = %sysfunc(scan(&path, &i, /));
%put &cur_folder;
"&cur_folder"
%end;
)
order by
idgrp_name,
case
/* Order by from root to sub folder / by inheritance*/
%do i = 1 %to &folder_cnt;
%let cur_folder = %sysfunc(scan(&path, &i, /));
%put &cur_folder;
when tree_name = "&cur_folder" then &i
%end;
else 999
end;
quit;
%mend filter_tree;
%filter_tree;
PART C
/* get the group for this user */
data metadata_person2;
set metadata_person1 (where=(login_userid = "&sysuserid"));
call symput("idgrp_name", idgrp_name);
run;
/* get the tree info for this group once identified */
data metadata_tree_2;
set metadata_tree_1 (where=(idgrp_name = "&idgrp_name"));
run;
/* check the inherited Read and ReadMetadata access */
data metadata_tree_3;
set metadata_tree_2;
call symput(perm_name, perm_type);
run;
/* if both &Read and &ReadMetadata are GRANT GRANT then proceed */
%put &Read;
%put &ReadMetadata;
I have figured out the Tree for Part B. It should branch from Tree > AccessControls > Identities > Permissions
Part B
/* Get Tree Info */
%custom_getnobj(table=metadata_tree, namespace=Tree, outuri=tree_uri);
%custom_getattr(intbl=metadata_tree, outtbl=metadata_tree, lkpuri=tree_uri, attrmetaname=Name, attrcolname=tree_name, attrcollen=$60);
%custom_getnasn(intbl=metadata_tree, outtbl=metadata_tree, namespace=AccessControls, lkpuri=tree_uri, outuri=ace_uri);
%custom_getnasn(intbl=metadata_tree, outtbl=metadata_tree, namespace=Identities, lkpuri=ace_uri, outuri=idgrp_uri);
%custom_getattr(intbl=metadata_tree, outtbl=metadata_tree, lkpuri=idgrp_uri, attrmetaname=Name, attrcolname=idgrp_name, attrcollen=$60);
%custom_getnasn(intbl=metadata_tree, outtbl=metadata_tree, namespace=Permissions, lkpuri=ace_uri, outuri=perm_uri);
%custom_getattr(intbl=metadata_tree, outtbl=metadata_tree, lkpuri=perm_uri, attrmetaname=Name, attrcolname=perm_name, attrcollen=$60);
%custom_getattr(intbl=metadata_tree, outtbl=metadata_tree, lkpuri=perm_uri, attrmetaname=Type, attrcolname=perm_type, attrcollen=$100);
%let path = /Shared Data/xx/yy/zz;
%macro filter_tree;
%let folder_cnt = %sysfunc(countw(&path, /));
proc sql;
create table metadata_tree_1 as
select *
from metadata_tree
where 1=1
and perm_name in ( 'Read' 'ReadMetadata' )
and tree_name in
(
/* Only require folders listed in &path */
%do i = 1 %to &folder_cnt;
%let cur_folder = %sysfunc(scan(&path, &i, /));
%put &cur_folder;
"&cur_folder"
%end;
)
order by
idgrp_name,
case
/* Order by from root to sub folder / by inheritance*/
%do i = 1 %to &folder_cnt;
%let cur_folder = %sysfunc(scan(&path, &i, /));
%put &cur_folder;
when tree_name = "&cur_folder" then &i
%end;
else 999
end;
quit;
%mend filter_tree;
%filter_tree;
PART C
/* get the group for this user */
data metadata_person2;
set metadata_person1 (where=(login_userid = "&sysuserid"));
call symput("idgrp_name", idgrp_name);
run;
/* get the tree info for this group once identified */
data metadata_tree_2;
set metadata_tree_1 (where=(idgrp_name = "&idgrp_name"));
run;
/* check the inherited Read and ReadMetadata access */
data metadata_tree_3;
set metadata_tree_2;
call symput(perm_name, perm_type);
run;
/* if both &Read and &ReadMetadata are GRANT GRANT then proceed */
%put &Read;
%put &ReadMetadata;
Thanks for sharing code!
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.