@@ -9,45 +9,85 @@ use Exporter 'import';
99our $JSON_FORMAT = " json" ;
1010our @EXPORT = qw( $JSON_FORMAT) ;
1111
12- our $A_MEMBER_STATUS ; *A_MEMBER_STATUS = \' urn:perun:member:attribute-def:core:status' ;
12+ our $USER_ATTR_PREFIX = " urn:perun:user:" ;
13+ our $USER_FACILITY_ATTR_PREFIX = " urn:perun:user_facility:" ;
14+ our $MEMBER_ATTR_PREFIX = " urn:perun:member:" ;
15+ our $MEMBER_RESOURCE_ATTR_PREFIX = " urn:perun:member_resource:" ;
16+ our $RESOURCE_ATTR_PREFIX = " urn:perun:resource:" ;
17+ our $FACILITY_ATTR_PREFIX = " urn:perun:facility:" ;
1318
14- # Generate user and user_facility required attributes for each user into JSON file.
15- # Subroutine uses perunServicesInit which REQUIRE access to $::SERVICE_NAME and $::PROTOCOL_VERSION.
16- # This can be achieved by following lines in your main script: (for example)
17- # local $::SERVICE_NAME = "passwd";
18- # local $::PROTOCOL_VERSION = "3.0.0";
19- # If not valid VO members should be skipped, member status attribute needs to be set on service and set
20- # local $::SKIP_NON_VALID_MEMBERS = 1;
21- sub generateUsersDataInJSON {
22- perunServicesInit::init;
19+ our $A_MEMBER_STATUS ; *A_MEMBER_STATUS = \' urn:perun:member:attribute-def:core:status' ;
2320
24- my $DIRECTORY = perunServicesInit::getDirectory;
25- my $data = perunServicesInit::getHashedHierarchicalData;
26- my $agent = perunServicesInit-> getAgent;
27- my $attributesAgent = $agent -> getAttributesAgent;
28- my $servicesAgent = $agent -> getServicesAgent;
29- my $service = $servicesAgent -> getServiceByName( name => $: :SERVICE_NAME);
21+ # Returns attribute definitions related to specified entity (entities) type(s)
22+ sub getRequiredAttributesByType {
23+ my $requiredAttributesDefinitions = shift ;
24+ my $attributePrefix = shift ;
25+ my @requiredAttributes = ();
3026
31- my @requiredAttributesDefinitions = $attributesAgent -> getRequiredAttributesDefinition(service => $service -> getId);
32- my @userRequiredAttributes = ();
33- my @userFacilityRequiredAttributes = ();
34- foreach my $attrDef (@requiredAttributesDefinitions ) {
35- # if attribute's namespace starts with "urn:perun:user:"
36- my $o = index $attrDef -> getNamespace, " urn:perun:user:" ;
27+ foreach my $attrDef (@$requiredAttributesDefinitions ) {
28+ my $o = index $attrDef -> getNamespace, $attributePrefix ;
3729 if ($o == 0) {
38- push @userRequiredAttributes , $attrDef ;
30+ push @requiredAttributes , $attrDef ;
3931 next ;
4032 }
41- $o = index $attrDef -> getNamespace, " urn:perun:user_facility:" ;
42- if ($o == 0) {
43- push @userFacilityRequiredAttributes , $attrDef ;
33+ }
34+
35+ return @requiredAttributes ;
36+ }
37+
38+ sub prepareMembersData {
39+ my $data = shift ;
40+ my $userIds = shift ;
41+ my $resourceId = shift ;
42+ my $memberRequiredAttributes = shift ;
43+ my $memberResourceRequiredAttributes = shift ;
44+
45+ my @members = ();
46+ foreach my $memberId ($data -> getMemberIdsForResource(resource => $resourceId )) {
47+ my $memberData = {};
48+ my $perunUserId = $data -> getUserIdForMember(member => $memberId );
49+ if (! exists $userIds -> {$perunUserId }) {
50+ # user was skipped
4451 next ;
4552 }
53+ $memberData -> {" link_id" } = $userIds -> {$perunUserId };
54+
55+ foreach my $memberAttribute (@$memberRequiredAttributes ) {
56+ my $attrValue = $data -> getMemberAttributeValue(member => $memberId , attrName => $memberAttribute -> getName);
57+ # In case there is an undefined boolean attribute, we have to change it to false
58+ if ($memberAttribute -> getType eq " boolean" && !defined $attrValue ) {
59+ $memberData -> {$memberAttribute -> getName} = \0;
60+ } else {
61+ $memberData -> {$memberAttribute -> getName} = $attrValue ;
62+ }
63+ }
64+
65+ foreach my $memberResourceAttribute (@$memberResourceRequiredAttributes ) {
66+ my $attrValue = $data -> getMemberResourceAttributeValue(member => $memberId , resource => $resourceId , attrName => $memberResourceAttribute -> getName);
67+ # In case there is an undefined boolean attribute, we have to change it to false
68+ if ($memberResourceAttribute -> getType eq " boolean" && !defined $attrValue ) {
69+ $memberData -> {$memberResourceAttribute -> getName} = \0;
70+ } else {
71+ $memberData -> {$memberResourceAttribute -> getName} = $attrValue ;
72+ }
73+ }
74+
75+ push @members , $memberData ;
4676 }
47- my @users ;
77+ return \@members ;
78+ }
79+
80+ # Prepares structure of user attributes
81+ # If addLinkId is true, it will add "link_id" property which is returned in the usersIds structure as {"perunUserId": linkId}
82+ sub prepareUsersData {
83+ my $data = shift ;
84+ my $userRequiredAttributes = shift ;
85+ my $userFacilityRequiredAttributes = shift ;
86+ my $addLinkId = shift ;
4887
49- # ###### prepare data ######################
5088 my %usersIds = ();
89+ my $linkIdCounter = 0;
90+ my @users = ();
5191 foreach my $memberId ($data -> getMemberIdsForFacility()) {
5292
5393 if ($: :SKIP_NON_VALID_MEMBERS) {
@@ -58,11 +98,12 @@ sub generateUsersDataInJSON {
5898 if (exists ($usersIds {$userId })) {
5999 next ;
60100 } else {
61- $usersIds {$userId } = 0;
101+ $linkIdCounter ++;
102+ $usersIds {$userId } = $linkIdCounter ;
62103 }
63104 my $userData = {};
64105
65- foreach my $userAttribute (@userRequiredAttributes ) {
106+ foreach my $userAttribute (@$ userRequiredAttributes ) {
66107 my $attrValue = $data -> getUserAttributeValue(member => $memberId , attrName => $userAttribute -> getName);
67108 # In case there is an undefined boolean attribute, we have to change it to false
68109 if ($userAttribute -> getType eq " boolean" && !defined $attrValue ) {
@@ -72,7 +113,7 @@ sub generateUsersDataInJSON {
72113 }
73114 }
74115
75- foreach my $userFacilityAttribute (@userFacilityRequiredAttributes ) {
116+ foreach my $userFacilityAttribute (@$ userFacilityRequiredAttributes ) {
76117 my $attrValue = $data -> getUserFacilityAttributeValue(member => $memberId , attrName => $userFacilityAttribute -> getName);
77118 # In case there is an undefined boolean attribute, we have to change it to false
78119 if ($userFacilityAttribute -> getType eq " boolean" && !defined $attrValue ) {
@@ -81,13 +122,120 @@ sub generateUsersDataInJSON {
81122 $userData -> {$userFacilityAttribute -> getName} = $attrValue ;
82123 }
83124 }
125+
126+ if ($addLinkId ) {
127+ $userData -> {" link_id" } = $linkIdCounter ;
128+ }
84129 push @users , $userData ;
85130 }
86131
87- # ###### output file ######################
132+ return (\@users , \%usersIds );
133+ }
134+
135+ =c
136+ Generate user and user_facility required attributes for each user into JSON file.
137+ Subroutine uses perunServicesInit which REQUIRE access to $::SERVICE_NAME and $::PROTOCOL_VERSION.
138+ This can be achieved by following lines in your main script: (for example)
139+ local $::SERVICE_NAME = "passwd";
140+ local $::PROTOCOL_VERSION = "3.0.0";
141+ If not valid VO members should be skipped, member status attribute needs to be set on service and set
142+ local $::SKIP_NON_VALID_MEMBERS = 1;
143+ =cut
144+ sub generateUsersDataInJSON {
145+ perunServicesInit::init;
146+
147+ my $DIRECTORY = perunServicesInit::getDirectory;
148+ my $data = perunServicesInit::getHashedHierarchicalData;
149+ my $agent = perunServicesInit-> getAgent;
150+ my $attributesAgent = $agent -> getAttributesAgent;
151+ my $servicesAgent = $agent -> getServicesAgent;
152+ my $service = $servicesAgent -> getServiceByName( name => $: :SERVICE_NAME);
153+
154+ my @requiredAttributesDefinitions = $attributesAgent -> getRequiredAttributesDefinition(service => $service -> getId);
155+ my @userRequiredAttributes = getRequiredAttributesByType(\@requiredAttributesDefinitions , $USER_ATTR_PREFIX );
156+ my @userFacilityRequiredAttributes = getRequiredAttributesByType(\@requiredAttributesDefinitions , $USER_FACILITY_ATTR_PREFIX );
157+
158+ my ($users , $ids ) = prepareUsersData($data , \@userRequiredAttributes , \@userFacilityRequiredAttributes );
159+
160+ my $fileName = " $DIRECTORY /$: :SERVICE_NAME" ;
161+ open FILE, " >$fileName " or die " Cannot open $fileName : $! \n " ;
162+ print FILE JSON::XS-> new-> utf8-> pretty-> canonical-> encode($users );
163+ close FILE or die " Cannot close $fileName : $! \n " ;
164+
165+ perunServicesInit::finalize;
166+ }
167+
168+ =c
169+ Generate user, user_facility, member, member_resource, resource and facility required attributes into JSON file.
170+ The result structure is:
171+ {
172+ "facility_attribute_name": "facility_attribute_value",
173+ "users" => [{"user_attribute_name": "user_attribute_value",
174+ "link_id": id linking user to its members}]
175+ "groups" => [{"resource_attribute_name": "resource_attribute_value",
176+ "members": [{"member_attribute_name": "member_attribute_value",
177+ "link_id": id of user this member belongs to}]}]
178+ }
179+ Subroutine uses perunServicesInit which REQUIRE access to $::SERVICE_NAME and $::PROTOCOL_VERSION.
180+ This can be achieved by following lines in your main script: (for example)
181+ local $::SERVICE_NAME = "passwd";
182+ local $::PROTOCOL_VERSION = "3.0.0";
183+ If not valid VO members should be skipped, member status attribute needs to be set on service and set
184+ local $::SKIP_NON_VALID_MEMBERS = 1;
185+ =cut
186+ sub generateMemberUsersDataInJson {
187+ perunServicesInit::init;
188+
189+ my $DIRECTORY = perunServicesInit::getDirectory;
190+ my $data = perunServicesInit::getHashedHierarchicalData;
191+ my $agent = perunServicesInit-> getAgent;
192+ my $attributesAgent = $agent -> getAttributesAgent;
193+ my $servicesAgent = $agent -> getServicesAgent;
194+ my $service = $servicesAgent -> getServiceByName( name => $: :SERVICE_NAME);
195+
196+ my @requiredAttributesDefinitions = $attributesAgent -> getRequiredAttributesDefinition(service => $service -> getId);
197+
198+ my @userRequiredAttributes = getRequiredAttributesByType(\@requiredAttributesDefinitions , $USER_ATTR_PREFIX );
199+ my @userFacilityRequiredAttributes = getRequiredAttributesByType(\@requiredAttributesDefinitions , $USER_FACILITY_ATTR_PREFIX );
200+ my ($users , $userIds ) = prepareUsersData($data , \@userRequiredAttributes , \@userFacilityRequiredAttributes , 1);
201+
202+ my @facilityRequiredAttributes = getRequiredAttributesByType(\@requiredAttributesDefinitions , $FACILITY_ATTR_PREFIX );
203+ my @resourceRequiredAttributes = getRequiredAttributesByType(\@requiredAttributesDefinitions , $RESOURCE_ATTR_PREFIX );
204+ my @memberRequiredAttributes = getRequiredAttributesByType(\@requiredAttributesDefinitions , $MEMBER_ATTR_PREFIX );
205+ my @memberResourceRequiredAttributes = getRequiredAttributesByType(\@requiredAttributesDefinitions , $MEMBER_RESOURCE_ATTR_PREFIX );
206+
207+ my $result = {};
208+ $result -> {" users" } = $users ;
209+ $result -> {" groups" } = ();
210+
211+ foreach my $facilityAttribute (@facilityRequiredAttributes ) {
212+ my $attrValue = $data -> getFacilityAttributeValue(attrName => $facilityAttribute -> getName);
213+ # In case there is an undefined boolean attribute, we have to change it to false
214+ if ($facilityAttribute -> getType eq " boolean" && !defined $attrValue ) {
215+ $result -> {$facilityAttribute -> getName} = \0;
216+ } else {
217+ $result -> {$facilityAttribute -> getName} = $attrValue ;
218+ }
219+ }
220+
221+ foreach my $resourceId ($data -> getResourceIds()) {
222+ my $resource = {};
223+ foreach my $resourceAttribute (@resourceRequiredAttributes ) {
224+ my $attrValue = $data -> getResourceAttributeValue(resource => $resourceId , attrName => $resourceAttribute -> getName);
225+ # In case there is an undefined boolean attribute, we have to change it to false
226+ if ($resourceAttribute -> getType eq " boolean" && !defined $attrValue ) {
227+ $resource -> {$resourceAttribute -> getName} = \0;
228+ } else {
229+ $resource -> {$resourceAttribute -> getName} = $attrValue ;
230+ }
231+ }
232+ $resource -> {" members" } = prepareMembersData($data , $userIds , $resourceId , \@memberRequiredAttributes , \@memberResourceRequiredAttributes );
233+ push @{$result -> {" groups" }}, $resource ;
234+ }
235+
88236 my $fileName = " $DIRECTORY /$: :SERVICE_NAME" ;
89237 open FILE, " >$fileName " or die " Cannot open $fileName : $! \n " ;
90- print FILE JSON::XS-> new-> utf8-> pretty-> canonical-> encode(\ @users );
238+ print FILE JSON::XS-> new-> utf8-> pretty-> canonical-> encode($result );
91239 close FILE or die " Cannot close $fileName : $! \n " ;
92240
93241 perunServicesInit::finalize;
0 commit comments