From 33fcc88aabf0aa6c3b86996e1fb67df3bfbe5989 Mon Sep 17 00:00:00 2001 From: Michal Prochazka <michalp@ics.muni.cz> Date: Thu, 15 Jun 2017 13:56:59 +0200 Subject: [PATCH] New SCIM service SCIM sends information about users and group and memberships. --- gen/scim | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 gen/scim diff --git a/gen/scim b/gen/scim new file mode 100644 index 00000000..1b5978c7 --- /dev/null +++ b/gen/scim @@ -0,0 +1,175 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use perunServicesInit; +use perunServicesUtils; +use Perun::Agent; +use Perun::GroupsAgent; +use open qw/:std :utf8/; +use JSON::XS; +use utf8; + +local $::SERVICE_NAME = "scim"; +local $::PROTOCOL_VERSION = "1.0.0"; +my $SCRIPT_VERSION = "1.0.0"; + +perunServicesInit::init; +my $DIRECTORY = perunServicesInit::getDirectory; +my $data = perunServicesInit::getDataWithGroups; + +#forward declaration +sub processUsers; +sub processGroups; +sub processMemberships; + +#Constants +our $A_USER_ID; *A_USER_ID = \'urn:perun:user:attribute-def:core:id'; +our $A_USER_STATUS; *A_USER_STATUS = \'urn:perun:member:attribute-def:core:status'; +our $A_USER_EMAIL; *A_USER_EMAIL = \'urn:perun:user:attribute-def:def:preferredMail'; +our $A_USER_LOGIN; *A_USER_LOGIN = \'urn:perun:user_facility:attribute-def:virt:login'; +our $A_USER_D_NAME; *A_USER_D_NAME = \'urn:perun:user:attribute-def:core:displayName'; +our $A_GROUP_ID; *A_GROUP_ID = \'urn:perun:group:attribute-def:core:id'; +our $A_GROUP_NAME; *A_GROUP_NAME = \'urn:perun:group:attribute-def:core:name'; +our $A_GROUP_PAR_ID; *A_GROUP_PAR_ID = \'urn:perun:group:attribute-def:core:parentGroupId'; + +our $STATUS_VALID; *STATUS_VALID = \'VALID'; +our $STATUS_EXPIRED; *STATUS_EXPIRED = \'EXPIRED'; +our $STATUS_SUSPENDED; *STATUS_SUSPENDED = \'SUSPENDED'; + +my $userStruc = {}; +my $groupStruc = {}; +my $membershipStruc = {}; + +my $userStatus = {}; +my $userEmail = {}; +my $userDisplayName = {}; +my $userLogin = {}; + +my $groupName = {}; +my $groupParentId = {}; + +my $fileUsers = $DIRECTORY . "/users.scim"; +my $fileGroups = $DIRECTORY . "/groups.scim"; + +my $agent = perunServicesInit->getAgent; + +foreach my $resourceData ($data->getChildElements) { + foreach my $groupData (($resourceData->getChildElements)[0]->getChildElements) { + my $groupMembersLogins = processGroups $groupData; + } +} + +# PREPARE USERSDATA TO JSON +my @users; +foreach my $uid (sort keys %$userStruc) { + my $user = {}; + $user->{"id"} = $uid; + $user->{"displayName"} = $userStruc->{$uid}->{$userDisplayName}; + $user->{"status"} = $userStruc->{$uid}->{$userStatus}; + $user->{"mail"} = $userStruc->{$uid}->{$userEmail}; + $user->{"login"} = $userStruc->{$uid}->{$userLogin}; + + push @users, $user; +} + +# PRINT USERS TO JSON +open FILE_USERS,">$fileUsers" or die "Cannot open $fileUsers: $! \n"; +binmode(FILE_USERS); +print FILE_USERS JSON::XS->new->utf8->pretty->encode(\@users); +close (FILE_USERS) or die "Cannot close $fileUsers: $! \n"; + +# PREPARE GROUPSDATA TO JSON +my @groups; +foreach my $gid (sort keys %$groupStruc) { + my $group = {}; + $group->{"id"} = $gid; + $group->{"name"} = $groupStruc->{$gid}->{$g_name}; + $group->{"parentGroupId"} = $groupStruc->{$gid}->{$g_par_id}; + + my @members; + foreach my $uid (sort keys %{$membershipStruc->{$gid}}){ + my $struct = {}; + $struct->{"userId"} = $uid; + push @members, $struct; + } + + $group->{"members"} = \@members; + push @groups, $group; +} + +# PRINT GROUPS TO JSON +open FILE_GROUPS,">$fileGroups" or die "Cannot open $fileGroups: $! \n"; +binmode(FILE_GROUPS); +print FILE_GROUPS JSON::XS->new->utf8->pretty->encode(\@groups); +close (FILE_GROUPS) or die "Cannot close $fileGroups: $! \n"; + +perunServicesInit::finalize; + +############################################################################## +# Only subs definitions down there +############################################################################## +## creates structure for users.scim file +sub processUsers { + my ($gid, $memberData) = @_; + + my %memberAttributes = attributesToHash $memberData->getAttributes; + my $uid = $memberAttributes{$A_USER_ID}; + my $status = $memberAttributes{$A_USER_STATUS}; + my $email = $memberAttributes{$A_USER_EMAIL}; + my $d_name = $memberAttributes{$A_USER_D_NAME}; + my $login = $memberAttributes{$A_USER_LOGIN}; + + if (exists $userStruc->{$uid}) { + my $memberStatus = $userStruc->{$uid}->{$userStatus}; + + if ($memberStatus eq $STATUS_EXPIRED && $status eq $STATUS_VALID){ + # change from EXPIRED to VALID + $userStruc->{$uid}->{$userStatus} = $status; + } elsif ($memberStatus eq $STATUS_SUSPENDED && $status eq $STATUS_VALID){ + # change from SUSPENDED to VALID + $userStruc->{$uid}->{$userStatus} = $status; + } elsif ($memberStatus eq $STATUS_SUSPENDED && $status eq $STATUS_EXPIRED){ + # change from SUSPENDED to EXPIRED + $userStruc->{$uid}->{$userStatus} = $status; + } + } else { + $userStruc->{$uid}->{$userStatus} = $status; + $userStruc->{$uid}->{$userEmail} = $email; + $userStruc->{$uid}->{$userDisplayName} = $d_name; + $userStruc->{$uid}->{$userLogin} = $login; + } + + processMemberships $gid, $uid; +} + +## creates structure for groups.scim file +sub processGroups { + my $group = shift; + my %groupAttributes = attributesToHash $group->getAttributes; + my $membersElement = ($group->getChildElements)[1]; + + if ($groupAttributes{$A_GROUP_NAME}) { + my $groupName = $groupAttributes{$A_GROUP_NAME}; + my $gid = $groupAttributes{$A_GROUP_ID}; + my $groupParId = $groupAttributes{$A_GROUP_PAR_ID}; + + unless(exists $groupStruc->{$gid}) { + $groupStruc->{$gid}->{$groupName} = $groupName; + $groupStruc->{$gid}->{$groupParentId} = $groupParId; + } + + foreach my $memberData ($membersElement->getChildElements) { + processUsers $gid, $memberData; + } + } +} + +## creates structure for memberships +sub processMemberships { + my ($gid, $uid) = @_; + + unless(exists $membershipStruc->{$gid}->{$uid}) { + $membershipStruc->{$gid}->{$uid} = {}; + } +} -- GitLab