Skip to content

Commit

Permalink
Merge branch 'master' into production
Browse files Browse the repository at this point in the history
  • Loading branch information
HejdaJakub committed Apr 25, 2023
2 parents 8dee8e3 + 4f8cb1a commit faf2536
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 238 deletions.
32 changes: 24 additions & 8 deletions gen/o365_mu_users_export
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,40 @@ use utf8;

local $::SERVICE_NAME = "o365_mu_users_export";
local $::PROTOCOL_VERSION = "3.0.0";
my $SCRIPT_VERSION = "3.0.0";
my $SCRIPT_VERSION = "3.0.1";

perunServicesInit::init;
my $DIRECTORY = perunServicesInit::getDirectory;
my $data = perunServicesInit::getHashedHierarchicalData;

#Constants
our $A_UF_LOGIN; *A_UF_LOGIN = \'urn:perun:user_facility:attribute-def:virt:login';
our $A_UF_MFA_STATUS; *A_UF_MFA_STATUS = \'urn:perun:user:attribute-def:virt:mfaStatus:mu';
our $A_UF_O365_STATE; *A_UF_O365_STATE = \'urn:perun:user_facility:attribute-def:def:o365InternalUserState';
our $A_UF_DISABLE_O365_MAIL_FORWARD; *A_UF_DISABLE_O365_MAIL_FORWARD = \'urn:perun:user_facility:attribute-def:def:disableO365MailForward';
our $A_UF_O365_STORE_AND_FORWARD; *A_UF_O365_STORE_AND_FORWARD = \'urn:perun:user_facility:attribute-def:def:o365MailStoreAndForward';

my $validLogins = {};
my $validLoginsO365 = {};
my $validLoginsMFA = {};

#RULES:
# add any user with mfaStatus attribute value filled to the mfa structure
# for the O365 structure:
#1] any user who has UCO
#2] status of user in o365 is not 0
#3] disableMailForward == true
#OR
#3] disableMailForward == false AND mailStoreAndForward == true
foreach my $memberId ( $data->getMemberIdsForFacility() ) {
my $uco = $data->getUserFacilityAttributeValue( member => $memberId, attrName => $A_UF_LOGIN );
#skip all users without UCO
# skip all users without UCO
next unless $uco;
# check whether user has mfa configured and add to mfa structure if so
my $mfaStatus = $data->getUserAttributeValue( member => $memberId, attrName => $A_UF_MFA_STATUS );
if ($mfaStatus && $mfaStatus ne "") {
$validLoginsMFA->{$uco} = $mfaStatus;
}
# now check for O365 rules
my $o365Status = $data->getUserFacilityAttributeValue( member => $memberId, attrName => $A_UF_O365_STATE );
#skip all users with 0 or empty value in status attribute (everything except 0 is OK here)
next unless $o365Status;
Expand All @@ -43,16 +53,22 @@ foreach my $memberId ( $data->getMemberIdsForFacility() ) {
next unless $storeAndForward;
}
#if all rules are met, add uco to the list
$validLogins->{$uco} = $uco;
$validLoginsO365->{$uco} = $uco;
}

my $fileName = "$DIRECTORY/$::SERVICE_NAME";
open FILE,">$fileName" or die "Cannot open $fileName: $! \n";
binmode FILE, ":utf8";

foreach my $uco (sort keys %{$validLogins}) {
open FILE,">:encoding(UTF-8)","$fileName" or die "Cannot open $fileName: $! \n";
foreach my $uco (sort keys %{$validLoginsO365}) {
print FILE $uco . "\n";
}
close (FILE);

my $mfaFileName = $fileName."_mfa";
open FILE,">:encoding(UTF-8)","$mfaFileName" or die "Cannot open $mfaFileName: $! \n";
foreach my $uco (sort keys %{$validLoginsMFA}) {
print FILE $uco . "\t";
print FILE $validLoginsMFA->{$uco} . "\n"
}
close (FILE);

perunServicesInit::finalize;
121 changes: 24 additions & 97 deletions send/atlassian_mu
Original file line number Diff line number Diff line change
@@ -1,109 +1,36 @@
#!/bin/bash
#!/usr/bin/env python3

SERVICE_NAME="atlassian_mu"
EXECSCRIPT="./atlassian_mu_process.pl"
import re
import sys

FACILITY_NAME=$1
DESTINATION=$2
DESTINATION_TYPE=$3
import send_lib

#Test if destination is in not empty and in the correct format
if [ -z "$DESTINATION" ]; then
echo "Missing Destination argument (Name of configuration file to retrieve endpoint URL and key from)" >&2
exit 252
else
if echo "$DESTINATION" | grep "[^.A-Za-z_0-9-]"; then
echo "Bad format of destination!" >&2
exit 251
fi
fi
SERVICE_NAME = "atlassian_mu"
EXECSCRIPT = "./atlassian_mu_process.pl"

#Test if name of facility is not empty
if [ -z "$FACILITY_NAME" ]; then
echo "Missing FacilityName argument" >&2
exit 245
fi
OK = 0
NOK = 1

#Basic path to find data from gen service
SERVICE_FILES_BASE_DIR="`pwd`/../gen/spool"
SERVICE_FILES_DIR="$SERVICE_FILES_BASE_DIR/$FACILITY_NAME/$SERVICE_NAME"
#Just safety check. This should not happen
if [ ! -d "$SERVICE_FILES_DIR" ]; then echo '$SERVICE_FILES_DIR: '$SERVICE_FILES_DIR' is not a directory' >&2 ; exit 1; fi
DESTINATION_REGEX = "[.A-Za-z_0-9-]*"

#Create lock to disallow calling more than once at time (method similar to locks in slave scripts)
LOCK_DIR=${LOCK_DIR:=/var/lock}
LOCK_FILE="${LOCK_DIR}/perun-${SERVICE_NAME}-$DESTINATION.lock"
LOCK_PIDFILE="$LOCK_FILE/pid"
function create_lock {
if mkdir "${LOCK_FILE}"; then
trap 'rm -r -f "${LOCK_FILE}"' EXIT
echo $$ > "$LOCK_PIDFILE";
if [ $? -ne 0 ]; then
echo "Can't create lock file." >&2
exit 250
fi
else
# lock file exists, check for existence of concurrent process
if ps ax | grep "$SERVICE_NAME" | sed 's/^\([0-9]\+\).*/\1/' | grep "\(^\| \)`cat $LOCK_PIDFILE`\( \|$\)"; then
# concurrent process is running - this skript must terminate
echo "Concurrent process $SERVICE_NAME is running" >&2
exit 249
else
# lock is not valid; it should be deleted
rm -r "$LOCK_FILE"
if [ $? -ne 0 ]; then
echo "Can't remove not valid lock file." >&2
exit 248
fi
echo "Invalid lock file found and deleted: $LOCK_FILE" >&2
mkdir "${LOCK_FILE}"
if [ $? -ne 0 ]; then
echo "Can't create lock after removing invalid lock." >&2
exit 247
fi
trap 'rm -r -f "${LOCK_FILE}"' EXIT
echo $$ > "$LOCK_PIDFILE"
if [ $? -ne 0 ]; then
echo "Can't create lock file after removing invalid lock file." >&2
exit 246
fi
fi
fi
}

#start script by creating new lock
create_lock
if __name__ == "__main__":

#prepare temporary working directory
TMP_HOSTNAME_DIR="`mktemp -d /tmp/perun-send.XXXXXXXXXX`"
if [ $? -ne 0 ]; then
echo "Can't create temporary dir" >&2
exit 255
fi
send_lib.check_input_fields(sys.argv)
facility_name = sys.argv[1]
destination = sys.argv[2]
send_lib.check_destination_format(destination, '', re.compile(DESTINATION_REGEX))

#prepare after exit removing of temporary files and directories
trap 'rm -r -f "${LOCK_FILE}" "${TMP_HOSTNAME_DIR}"' EXIT
# create lock to ensure only one script of this type is running
send_lib.create_lock(SERVICE_NAME, destination)

#copy all needed files to the temporary directory
cp $SERVICE_FILES_DIR/*.scim $TMP_HOSTNAME_DIR
if [ $? -ne 0 ]; then
echo "Can't copy service file to temporary dir" >&2
exit 254
fi
# prepare temporary working directory and copy all needed files into it
with send_lib.prepare_temporary_directory() as tmpDir:
send_lib.copy_files_to_directory(send_lib.get_gen_folder(facility_name, SERVICE_NAME), tmpDir, re.compile(".*scim$"))

#test if exists perl script to call from this one
if [ ! -f "$EXECSCRIPT" ]; then
echo "Can't locate connector file!" >&2
exit 253
fi
# run script
process_return_code = send_lib.exec_script(EXECSCRIPT, ["-c", f"/etc/perun/services/{SERVICE_NAME}/{destination}", "-d", f"{tmpDir}/"]).wait()
if process_return_code != OK:
send_lib.die_with_error("Process exit with error", process_return_code)

#call perl script with mandatory options
$EXECSCRIPT -c "/etc/perun/services/$SERVICE_NAME/$DESTINATION" -d "$TMP_HOSTNAME_DIR/"

#catch return statement and process it
ERRORCODE=$?
if [ $ERRORCODE -ne 0 ]; then
echo "Process exit with error" >&2
fi

exit $ERRORCODE
exit(OK)
125 changes: 66 additions & 59 deletions send/bbmri_collections
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,59 +1,66 @@
#!/bin/bash
SERVICE_NAME="bbmri_collections"

TIMEOUT="5400" #90s * 60 sec = 1.5h
TIMEOUT_KILL="60" # 60 sec to kill after timeout

FACILITY_NAME=$1
DESTINATION=$2
DESTINATION_TYPE=$3

SERVICE_FILES_BASE_DIR="`pwd`/../gen/spool"
USER_FILE_NAME="users.scim"
GROUP_FILE_NAME="groups.scim"
USER_FILE="$SERVICE_FILES_BASE_DIR/$FACILITY_NAME/$SERVICE_NAME/$USER_FILE_NAME"
GROUP_FILE="$SERVICE_FILES_BASE_DIR/$FACILITY_NAME/$SERVICE_NAME/$GROUP_FILE_NAME"
USER_ENDPOINT="users"
GROUP_ENDPOINT="mapping"

# Destination type has to be 'url'
if [ "$DESTINATION_TYPE" != "url" ]; then
echo "Unknown destination type '$DESTINATION_TYPE' (url type required)." >&2
exit 1;
fi

# Read user name and password from configuration if it is present ( expect string "-u user:pass" )
[ -r /etc/perun/services/$SERVICE_NAME/$SERVICE_NAME ] && . /etc/perun/services/$SERVICE_NAME/$SERVICE_NAME

# Specify command to transfer the data
TRANSPORT_COMMAND="curl -Ss -i --http1.1 -H Content-Type:application/json -f -X POST"
USER_TRANSPORT_COMMAND="$TRANSPORT_COMMAND -d @- $USERNAME_AND_PASSWORD $DESTINATION$USER_ENDPOINT"
GROUP_TRANSPORT_COMMAND="$TRANSPORT_COMMAND -d @- $USERNAME_AND_PASSWORD $DESTINATION$GROUP_ENDPOINT"

# HTTP Request with timeout for USERS
cat "$USER_FILE" | timeout -k $TIMEOUT_KILL $TIMEOUT $USER_TRANSPORT_COMMAND
# Catch errors
ERR_CODE=$?
#Error code 124 means - timed out
if [ $ERR_CODE -eq 124 ]; then
echo "Propagation users - Communication with the peer has timed out with return code: $ERR_CODE (Warning: this error can mask original error 124 from peer!)" >&2
else
if [ $ERR_CODE -ne 0 ]; then
echo "Propagation users - Communication with the peer ends with return code: $ERR_CODE" >&2
fi
fi

# HTTP Request with timeout for GROUPS
cat "$GROUP_FILE" | timeout -k $TIMEOUT_KILL $TIMEOUT $GROUP_TRANSPORT_COMMAND
# Catch errors
ERR_CODE=$?
#Error code 124 means - timed out
if [ $ERR_CODE -eq 124 ]; then
echo "Propagation groups - Communication with the peer ends with return code: $ERR_CODE (Warning: this error can mask original error 124 from peer!)" >&2
else
if [ $ERR_CODE -ne 0 ]; then
echo "Propagation groups - Communication with the peer ends with return code: $ERR_CODE" >&2
fi
fi

exit $ERR_CODE
#!/usr/bin/env python3
import os
import send_lib
import sys
import requests
import json

SERVICE_NAME = "bbmri_collections"
TIMEOUT = 5400 # 90s * 60 sec = 1.5h

send_lib.check_input_fields(sys.argv, True)

facility = sys.argv[1]
destination = sys.argv[2]
destination_type = sys.argv[3]

send_lib.check_destination_type_allowed(destination_type, send_lib.DESTINATION_TYPE_URL)
send_lib.check_destination_format(destination, destination_type)

gen_folder = send_lib.get_gen_folder(facility, SERVICE_NAME)
user_file_name = "users.scim"
group_file_name = "groups.scim"
user_filepath = os.path.join(gen_folder, user_file_name)
group_filepath = os.path.join(gen_folder, group_file_name)
user_endpoint = "users"
group_endpoint = "mapping"


# Read username and password from configuration if it is present - else auth is not added to the request
auth = None
try:
# expected format of the auth file /etc/perun/services/bbmri_collections/bbmri_collections.py
# supplement $ variables with destination url, username and password
# credentials = {
# '$url1': { 'username': '$user1', 'password': '$pwd1' },
# '$url2': { 'username': '$user2', 'password': '$pwd2' }
# }
sys.path.insert(1, '/etc/perun/services/' + SERVICE_NAME + '/')
credentials = __import__(SERVICE_NAME).credentials
if destination in credentials.keys():
username = credentials.get(destination).get('username')
password = credentials.get(destination).get('password')
auth = (username, password)
except ImportError:
# this means that config file does not exist
pass

with open(user_filepath, 'rb') as f:
headers = {'Content-Type': 'application/json'}
response = requests.post(destination + user_endpoint, headers=headers, auth=auth, timeout=TIMEOUT, json=json.load(f))
if response.status_code == 124:
send_lib.die_with_error("Propagation users - Communication with the peer has timed out with return code:"
" 124 (Warning: this error can mask original error 124 from peer!)")
if not response.ok:
send_lib.die_with_error(
"Propagation users - Communication with the peer ends with return code: " + str(response.status_code))

with open(group_filepath, 'rb') as f:
headers = {'Content-Type': 'application/json'}
response = requests.post(destination + group_endpoint, headers=headers, auth=auth, timeout=TIMEOUT, json=json.load(f))
if response.status_code == 124:
send_lib.die_with_error("Propagation groups - Communication with the peer has timed out with return code:"
" 124 (Warning: this error can mask original error 124 from peer!)")
if not response.ok:
send_lib.die_with_error(
"Propagation groups - Communication with the peer ends with return code: " + str(response.status_code))
Loading

0 comments on commit faf2536

Please sign in to comment.