Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add flags for including non-security and mail-enabled groups #10

Merged
merged 2 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ There is no hard depth limit, but **caution** has to be exercised when using thi

It it advised to first run `--query-graph-only` and `--save-graph-response-json results.json` parameters together in order to inspect the groups discovered during the deep search. And only continue with sync if results are below the maximum number of groups SCIM endpoint supports!

## Group types

By default only ["Security Groups"](https://learn.microsoft.com/en-us/graph/api/resources/groups-overview?view=graph-rest-1.0&tabs=http#security-groups-and-mail-enabled-security-groups) will be included in the sync.
This decision was made in order to [limit the number of groups included in the synchronisation](https://github.com/grusin-db/uc-azure-account-scim-sync-py/issues/9).
[Other groups types](https://learn.microsoft.com/en-us/graph/api/resources/groups-overview?view=graph-rest-1.0&tabs=http#group-types-in-microsoft-entra-id-and-microsoft-graph) can be included using the `--include-non-security-groups` and `--include-mail-enabled-groups` flags.

## Incremental synchronization (default)

Uses [Graph API change feed](https://learn.microsoft.com/en-us/graph/api/resources/change-notifications-api-overview?view=graph-rest-1.0) to determine the [groups that have changed](https://learn.microsoft.com/en-us/graph/api/group-delta?view=graph-rest-1.0&tabs=http#query-parameters) since last run. In this mode, all previously synchronized groups will be checked for changes. That means that groups that changed in AAD/Entra, but never were requested to be synced will be ignored.
Expand Down Expand Up @@ -127,6 +133,10 @@ Options:
--full-sync synchronizes all groups defined in `groups-
json-file` instead of using graph api change
feed
--include-non-security-groups include non-security Entra groups in the
sync [default: False]
--include-mail-enabled-groups include mail-enabled Entra groups in the
sync [default: False]
--help Show this message and exit.
```

Expand Down
19 changes: 17 additions & 2 deletions azure_dbr_scim_sync/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,21 @@
is_flag=True,
show_default=True,
help="synchronizes all groups defined in `groups-json-file` instead of using graph api change feed")
@click.option(
'--include-non-security-groups',
default=False,
is_flag=True,
show_default=True,
help="include non-security Entra groups in the sync")
@click.option(
'--include-mail-enabled-groups',
default=False,
is_flag=True,
show_default=True,
help="include mail-enabled Entra groups in the sync")
def sync_cli(groups_json_file, verbose, debug, dry_run_security_principals, dry_run_members, worker_threads,
save_graph_response_json, query_graph_only, group_search_depth, full_sync,
graph_change_feed_grace_time):
graph_change_feed_grace_time, include_non_security_groups, include_mail_enabled_groups):
install_logger()

logger = logging.getLogger('sync')
Expand All @@ -71,7 +83,10 @@ def sync_cli(groups_json_file, verbose, debug, dry_run_security_principals, dry_
if verbose:
logger.setLevel(logging.DEBUG)

graph_client = GraphAPIClient()
graph_client = GraphAPIClient(
include_mail_enabled_groups=include_mail_enabled_groups,
include_non_security_groups=include_non_security_groups
)
account_client = get_account_client()

if groups_json_file:
Expand Down
21 changes: 16 additions & 5 deletions azure_dbr_scim_sync/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,14 @@ def save_to_json_file(self, file_name: str):

class GraphAPIClient:

def __init__(self, tenant_id: str = None, spn_id: str = None, spn_key: str = None):
def __init__(self,
include_mail_enabled_groups: bool = False,
include_non_security_groups: bool = False):
self._tenant_id = None

self._include_mail_enabled_groups = include_mail_enabled_groups
self._include_non_security_groups = include_non_security_groups

retry_strategy = Retry(
total=6,
backoff_factor=1,
Expand Down Expand Up @@ -123,10 +128,13 @@ def get_group_by_name(self, name: str) -> dict:
if data and len(data) == 1:
group_info = data[0]
# https://learn.microsoft.com/en-us/graph/api/resources/groups-overview?view=graph-rest-1.0&tabs=http#group-types-in-microsoft-entra-id-and-microsoft-graph
if group_info.get('mailEnabled') == False and group_info.get('securityEnabled') == True:
if (
(group_info.get('securityEnabled') or self._include_non_security_groups) and
((not group_info.get('mailEnabled')) or self._include_mail_enabled_groups)
):
return group_info

logger.warning(f"Skipping non security group '{name}': {data}")
logger.warning(f"Skipping group '{name}': {data}")

return None

Expand Down Expand Up @@ -240,12 +248,15 @@ def _register_group(d):
id = d['id']
if id not in sync_data.groups:
try:
if d.get('mailEnabled') == False and d.get('securityEnabled') == True:
if (
(d.get('securityEnabled') or self._include_non_security_groups) and
((not d.get('mailEnabled')) or self._include_mail_enabled_groups)
):
obj = GraphGroup.model_validate(d)
sync_data.groups[id] = obj
logger.debug(f"Downloaded GraphGroup: {obj}")
else:
logger.info(f"Skipping non security group '{d['displayName']}': {d}")
logger.info(f"Skipping group '{d['displayName']}': {d}")
return None
except Exception as e:
logger.error(f"Invalid GraphGroup: {d}", exc_info=e)
Expand Down