ees_sharepoint/permission_sync_command.py (81 lines of code) (raw):
#
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License 2.0;
# you may not use this file except in compliance with the Elastic License 2.0.
#
"""This module allows to run a deletion sync against a Sharepoint Server instance.
It will attempt to remove from Enterprise Search instance the documents
that have been deleted from the third-party system."""
import csv
import os
from ees_sharepoint.base_command import BaseCommand
from .checkpointing import Checkpoint
from .sync_sharepoint import get_results
from .usergroup_permissions import Permissions
class PermissionSyncDisabledException(Exception):
"""Exception raised when permission sync is disabled, but expected to be enabled.
Attributes:
message -- explanation of the error
"""
def __init__(self, message="Provided configuration was invalid"):
super().__init__(message)
self.message = message
class PermissionSyncCommand(BaseCommand):
"""This class contains logic to sync user permissions from Sharepoint Server.
It can be used to run the job that will periodically sync permissions
from Sharepoint Server to Elastic Enteprise Search."""
def __init__(self, args):
super().__init__(args)
config = self.config
self.ws_source = config.get_value("workplace_search.source_id")
self.objects = config.get_value("objects")
self.site_collections = config.get_value("sharepoint.site_collections")
self.enable_permission = config.get_value("enable_document_permission")
self.mapping_sheet_path = config.get_value("sharepoint_workplace_user_mapping")
self.checkpoint = Checkpoint(config, self.logger)
self.permissions = Permissions(self.sharepoint_client, self.workplace_search_custom_client, self.logger)
def get_users_id(self):
"""This method returns the dictionary of dictionaries containing users and their id
as a key value pair for all the site-collections."""
user_ids = {}
for collection in self.site_collections:
user_id_collection = {}
rel_url = f"sites/{collection}/_api/web/siteusers"
response = self.sharepoint_client.get(rel_url, "?", "permission_users")
if not response:
self.logger.error("Could not fetch the SharePoint users")
continue
users = get_results(self.logger, response.json(), "sharepoint_users")
for user in users:
user_id_collection[user["Title"]] = user["Id"]
user_ids.update({collection: user_id_collection})
return user_ids
def get_user_groups(self, user_ids):
"""This method returns the groups of each user in all the site-collections
:param user_ids: user ids to fetch the groups of the specific user"""
user_group = {}
for collection in self.site_collections:
user_group_collection = {}
rel_url = f"sites/{collection}/"
for name, user_id in user_ids[collection].items():
response = self.permissions.fetch_groups(rel_url, user_id)
if response:
groups = get_results(self.logger, response.json(), "user_groups")
if groups:
user_group_collection[name] = [group["Title"] for group in groups]
user_group.update({collection: user_group_collection})
return user_group
def workplace_add_permission(self, permissions):
"""This method when invoked would index the permission provided in the paramater
for the user in paramter user_name
:param permissions: dictionary of dictionaries containing permissions of all the users in each site-collection."""
for collection in self.site_collections:
for user_name, permission_list in permissions[collection].items():
self.workplace_search_custom_client.add_permissions(user_name, permission_list)
def sync_permissions(self):
"""This method when invoked, checks the permission of SharePoint users and update those user
permissions in the Workplace Search."""
rows = {}
if os.path.exists(self.mapping_sheet_path) and os.path.getsize(self.mapping_sheet_path) > 0:
with open(self.mapping_sheet_path) as file:
csvreader = csv.reader(file)
for row in csvreader:
rows[row[0]] = row[1]
users = self.get_users_id()
user_names = {}
user_groups = {}
if users:
for collection in self.site_collections:
user_name_collection = {}
for user, user_id in users[collection].items():
user_name_collection.update({rows.get(user, user): user_id})
user_names.update({collection: user_name_collection})
user_groups = self.get_user_groups(user_names)
# delete all the permissions present in workplace search
self.permissions.remove_all_permissions()
if user_groups:
# add all the updated permissions
self.workplace_add_permission(user_groups)
def execute(self):
"""Runs the permission indexing logic"""
logger = self.logger
config = self.config
logger.info("Starting the permission indexing..")
enable_permission = config.get_value("enable_document_permission")
if not enable_permission:
logger.warn("Exiting as the enable permission flag is set to False")
raise PermissionSyncDisabledException
self.sync_permissions()