mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-03 12:21:35 +00:00
Inbound SSO improvements
This commit is contained in:
@@ -11624,6 +11624,8 @@ def ProcessGAMCommand(args):
|
|||||||
gapi_directory_customer.doGetCustomerInfo()
|
gapi_directory_customer.doGetCustomerInfo()
|
||||||
elif argument in ['inboundssoprofile', 'inboundssoprofiles']:
|
elif argument in ['inboundssoprofile', 'inboundssoprofiles']:
|
||||||
gapi_cloudidentity_inboundsso.info_profile()
|
gapi_cloudidentity_inboundsso.info_profile()
|
||||||
|
elif argument in ['inboundssoassignment', 'inboundssoassignments']:
|
||||||
|
gapi_cloudidentity_inboundsso.info_assignment()
|
||||||
elif argument in ['org', 'ou', 'orgunit']:
|
elif argument in ['org', 'ou', 'orgunit']:
|
||||||
gapi_directory_orgunits.info()
|
gapi_directory_orgunits.info()
|
||||||
elif argument == 'resource':
|
elif argument == 'resource':
|
||||||
@@ -11795,13 +11797,13 @@ def ProcessGAMCommand(args):
|
|||||||
elif argument in ['groupmembers', 'groupsmembers']:
|
elif argument in ['groupmembers', 'groupsmembers']:
|
||||||
gapi_directory_groups.print_members()
|
gapi_directory_groups.print_members()
|
||||||
elif argument in ['inboundssoassignment', 'inboundssoassignments']:
|
elif argument in ['inboundssoassignment', 'inboundssoassignments']:
|
||||||
gapi_cloudidentity_inboundsso.print_assignments()
|
gapi_cloudidentity_inboundsso.print_show_assignments()
|
||||||
elif argument in ['cigroupmembers', 'cigroupsmembers']:
|
elif argument in ['cigroupmembers', 'cigroupsmembers']:
|
||||||
gapi_cloudidentity_groups.print_members()
|
gapi_cloudidentity_groups.print_members()
|
||||||
elif argument in ['inboundssoprofile', 'inboundssoprofiles']:
|
elif argument in ['inboundssoprofile', 'inboundssoprofiles']:
|
||||||
gapi_cloudidentity_inboundsso.print_profiles()
|
gapi_cloudidentity_inboundsso.print_show_profiles()
|
||||||
elif argument in ['inboundssocredential', 'inboundssocredentials']:
|
elif argument in ['inboundssocredential', 'inboundssocredentials']:
|
||||||
gapi_cloudidentity_inboundsso.print_credentials()
|
gapi_cloudidentity_inboundsso.print_show_credentials()
|
||||||
elif argument in ['orgs', 'ous']:
|
elif argument in ['orgs', 'ous']:
|
||||||
gapi_directory_orgunits.print_()
|
gapi_directory_orgunits.print_()
|
||||||
elif argument == 'privileges':
|
elif argument == 'privileges':
|
||||||
@@ -11902,6 +11904,12 @@ def ProcessGAMCommand(args):
|
|||||||
gapi_licensing.show()
|
gapi_licensing.show()
|
||||||
elif argument in ['project', 'projects']:
|
elif argument in ['project', 'projects']:
|
||||||
doPrintShowProjects(False)
|
doPrintShowProjects(False)
|
||||||
|
elif argument in ['inboundssoprofile', 'inboundssoprofiles']:
|
||||||
|
gapi_cloudidentity_inboundsso.print_show_profiles('show')
|
||||||
|
elif argument in ['inboundssocredential', 'inboundssocredentials']:
|
||||||
|
gapi_cloudidentity_inboundsso.print_show_credentials('show')
|
||||||
|
elif argument in ['inboundssoassignment', 'inboundssoassignments']:
|
||||||
|
gapi_cloudidentity_inboundsso.print_show_assignments('show')
|
||||||
elif argument in ['sakey', 'sakeys']:
|
elif argument in ['sakey', 'sakeys']:
|
||||||
doShowServiceAccountKeys()
|
doShowServiceAccountKeys()
|
||||||
elif argument in ['browsertoken', 'browsertokens']:
|
elif argument in ['browsertoken', 'browsertokens']:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"""Methods related to Cloud Identity Inbound (Google as SP) SAML SSO"""
|
"""Methods related to Cloud Identity Inbound (Google as SP) SAML SSO"""
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
@@ -11,6 +12,7 @@ from gam import controlflow
|
|||||||
from gam import display
|
from gam import display
|
||||||
from gam import fileutils
|
from gam import fileutils
|
||||||
from gam import gapi
|
from gam import gapi
|
||||||
|
from gam import utils
|
||||||
from gam.gapi import errors as gapi_errors
|
from gam.gapi import errors as gapi_errors
|
||||||
from gam.gapi import cloudidentity as gapi_cloudidentity
|
from gam.gapi import cloudidentity as gapi_cloudidentity
|
||||||
from gam.gapi import directory as gapi_directory
|
from gam.gapi import directory as gapi_directory
|
||||||
@@ -91,6 +93,41 @@ def profile_displayname_to_name(displayName, ci=None):
|
|||||||
controlflow.system_error_exit(3, err_text)
|
controlflow.system_error_exit(3, err_text)
|
||||||
|
|
||||||
|
|
||||||
|
'''get an assignment based on target'''
|
||||||
|
def assignment_by_target(target, ci=None):
|
||||||
|
if not ci:
|
||||||
|
ci = build()
|
||||||
|
group_pattern = r'^groups/[^/]+$'
|
||||||
|
ou_pattern = r'^orgUnits/[^/]+$'
|
||||||
|
if re.match(group_pattern, target):
|
||||||
|
target_type = 'targetGroup'
|
||||||
|
elif re.match(ou_pattern, target):
|
||||||
|
target_type = 'targetOrgUnit'
|
||||||
|
elif target.lower().startswith('group:'):
|
||||||
|
target_type = 'targetGroup'
|
||||||
|
group_email = target[6:]
|
||||||
|
target = gapi_cloudidentity_groups.group_email_to_id(
|
||||||
|
ci,
|
||||||
|
group_email)
|
||||||
|
elif target.lower().startswith('orgunit:'):
|
||||||
|
target_type = 'targetOrgUnit'
|
||||||
|
ou_name = target[8:]
|
||||||
|
target = get_orgunit_id(ou_name)
|
||||||
|
else:
|
||||||
|
controlflow.system_error_exit(3, 'assignments should be prefixed with group: or orgunit:')
|
||||||
|
customer = get_sso_customer()
|
||||||
|
_filter = f'customer=="{customer}"'
|
||||||
|
assignments = gapi.get_all_pages(ci.inboundSsoAssignments(),
|
||||||
|
'list',
|
||||||
|
'inboundSsoAssignments',
|
||||||
|
filter=_filter,
|
||||||
|
)
|
||||||
|
for assignment in assignments:
|
||||||
|
if target_type in assignment and assignment[target_type] == target:
|
||||||
|
return assignment
|
||||||
|
controlflow.system_error_exit(3, f'No SSO profile assigned to group {target}')
|
||||||
|
|
||||||
|
|
||||||
'''gam create inboundssoprofile'''
|
'''gam create inboundssoprofile'''
|
||||||
def create_profile():
|
def create_profile():
|
||||||
ci = build()
|
ci = build()
|
||||||
@@ -104,18 +141,42 @@ def create_profile():
|
|||||||
|
|
||||||
|
|
||||||
'''gam print inboundssoprofiles'''
|
'''gam print inboundssoprofiles'''
|
||||||
def print_profiles():
|
def print_show_profiles(action='print'):
|
||||||
customer = get_sso_customer()
|
customer = get_sso_customer()
|
||||||
_filter = f'customer=="{customer}"'
|
_filter = f'customer=="{customer}"'
|
||||||
ci = build()
|
ci = build()
|
||||||
|
todrive = False
|
||||||
|
i = 3
|
||||||
|
while i < len(sys.argv):
|
||||||
|
myarg = sys.argv[i].lower().replace('_', '')
|
||||||
|
if myarg == 'todrive':
|
||||||
|
todrive = True
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
controlflow.invalid_argument_exit(myarg, 'gam print inboundssoprofiles')
|
||||||
|
|
||||||
profiles = gapi.get_all_pages(ci.inboundSamlSsoProfiles(),
|
profiles = gapi.get_all_pages(ci.inboundSamlSsoProfiles(),
|
||||||
'list',
|
'list',
|
||||||
'inboundSamlSsoProfiles',
|
'inboundSamlSsoProfiles',
|
||||||
filter=_filter,
|
filter=_filter,
|
||||||
)
|
)
|
||||||
for profile in profiles:
|
if action == 'show':
|
||||||
display.print_json(profile)
|
for profile in profiles:
|
||||||
print()
|
display.print_json(profile)
|
||||||
|
print()
|
||||||
|
elif action == 'print':
|
||||||
|
csv_rows = []
|
||||||
|
titles = []
|
||||||
|
for profile in profiles:
|
||||||
|
row = utils.flatten_json(profile)
|
||||||
|
for item in row:
|
||||||
|
if item not in titles:
|
||||||
|
titles.append(item)
|
||||||
|
csv_rows.append(row)
|
||||||
|
display.write_csv_file(csv_rows,
|
||||||
|
titles,
|
||||||
|
'Inbound SSO Profiles',
|
||||||
|
todrive)
|
||||||
|
|
||||||
|
|
||||||
'''gam update inboundssoprofile'''
|
'''gam update inboundssoprofile'''
|
||||||
@@ -134,16 +195,20 @@ def update_profile():
|
|||||||
|
|
||||||
|
|
||||||
'''gam info inboundssoprofile'''
|
'''gam info inboundssoprofile'''
|
||||||
def info_profile():
|
def info_profile(return_only=False, displayName=None, ci=None):
|
||||||
ci = build()
|
if not ci:
|
||||||
name = profile_displayname_to_name(sys.argv[3], ci)
|
ci = build()
|
||||||
|
if not displayName:
|
||||||
|
displayName = sys.argv[3]
|
||||||
|
name = profile_displayname_to_name(displayName, ci)
|
||||||
result = gapi.call(ci.inboundSamlSsoProfiles(),
|
result = gapi.call(ci.inboundSamlSsoProfiles(),
|
||||||
'get',
|
'get',
|
||||||
name=name,
|
name=name,
|
||||||
)
|
)
|
||||||
|
if return_only:
|
||||||
|
return result
|
||||||
display.print_json(result)
|
display.print_json(result)
|
||||||
|
|
||||||
|
|
||||||
'''gam delete inboundssoprofile'''
|
'''gam delete inboundssoprofile'''
|
||||||
def delete_profile():
|
def delete_profile():
|
||||||
ci = build()
|
ci = build()
|
||||||
@@ -256,16 +321,20 @@ def delete_credentials(ci=None, name=None):
|
|||||||
|
|
||||||
|
|
||||||
'''gam print inboundssocredentials'''
|
'''gam print inboundssocredentials'''
|
||||||
def print_credentials():
|
def print_show_credentials(action='print'):
|
||||||
ci = build()
|
ci = build()
|
||||||
|
todrive = False
|
||||||
i = 3
|
i = 3
|
||||||
profiles = []
|
profiles = []
|
||||||
while i > len(sys.argv):
|
while i < len(sys.argv):
|
||||||
myarg = sys.argv[i].lower().replace('_', '')
|
myarg = sys.argv[i].lower().replace('_', '')
|
||||||
if myarg in ['profile', 'profiles']:
|
if myarg in ['profile', 'profiles']:
|
||||||
profiles = sys.argv[i+1].split(',')
|
profiles = sys.argv[i+1].split(',')
|
||||||
for profile in profiles:
|
for profile in profiles:
|
||||||
profile = profile_displayname_to_name(profile, ci)
|
profile = profile_displayname_to_name(profile, ci)
|
||||||
|
elif myarg == 'todrive':
|
||||||
|
todrive = True
|
||||||
|
i += 1
|
||||||
else:
|
else:
|
||||||
controlflow.invalid_argument_exit(myarg, 'gam print inboundssocredentials')
|
controlflow.invalid_argument_exit(myarg, 'gam print inboundssocredentials')
|
||||||
if not profiles:
|
if not profiles:
|
||||||
@@ -278,15 +347,31 @@ def print_credentials():
|
|||||||
filter=_filter,
|
filter=_filter,
|
||||||
)
|
)
|
||||||
profiles = [p['name'] for p in profiles]
|
profiles = [p['name'] for p in profiles]
|
||||||
|
if action == 'print':
|
||||||
|
titles = []
|
||||||
|
csv_rows = []
|
||||||
|
credentials = []
|
||||||
for profile in profiles:
|
for profile in profiles:
|
||||||
credentials = gapi.get_all_pages(ci.inboundSamlSsoProfiles().idpCredentials(),
|
results = gapi.get_all_pages(ci.inboundSamlSsoProfiles().idpCredentials(),
|
||||||
'list',
|
'list',
|
||||||
'idpCredentials',
|
'idpCredentials',
|
||||||
parent=profile)
|
parent=profile)
|
||||||
|
credentials.extend(results)
|
||||||
|
if action == 'show':
|
||||||
for c in credentials:
|
for c in credentials:
|
||||||
display.print_json(c)
|
display.print_json(c)
|
||||||
print()
|
print()
|
||||||
|
elif action == 'print':
|
||||||
|
for c in credentials:
|
||||||
|
csv_row = utils.flatten_json(c)
|
||||||
|
for item in csv_row:
|
||||||
|
if item not in titles:
|
||||||
|
titles.append(item)
|
||||||
|
csv_rows.append(csv_row)
|
||||||
|
display.write_csv_file(csv_rows,
|
||||||
|
titles,
|
||||||
|
'Inbound SSO Credentials',
|
||||||
|
todrive)
|
||||||
|
|
||||||
'''parse command for create/update inboundssoassignment'''
|
'''parse command for create/update inboundssoassignment'''
|
||||||
def parse_assignment(body, i, ci):
|
def parse_assignment(body, i, ci):
|
||||||
@@ -347,7 +432,7 @@ def create_assignment():
|
|||||||
'''gam update inboundssoassignment'''
|
'''gam update inboundssoassignment'''
|
||||||
def update_assignment():
|
def update_assignment():
|
||||||
ci = build()
|
ci = build()
|
||||||
name = sys.argv[3]
|
name = assignment_target_to_name(sys.argv[3], ci)
|
||||||
body = {}
|
body = {}
|
||||||
body = parse_assignment(body, 4, ci)
|
body = parse_assignment(body, 4, ci)
|
||||||
updateMask = ','.join(list(body.keys()))
|
updateMask = ','.join(list(body.keys()))
|
||||||
@@ -360,11 +445,32 @@ def update_assignment():
|
|||||||
display.print_json(result)
|
display.print_json(result)
|
||||||
|
|
||||||
|
|
||||||
|
'''gam info inboundssoassignment'''
|
||||||
|
def info_assignment():
|
||||||
|
ci = build()
|
||||||
|
assignment = assignment_by_target(sys.argv[3], ci)
|
||||||
|
profile = assignment.get('samlSsoInfo', {}).get('inboundSamlSsoProfile')
|
||||||
|
if profile:
|
||||||
|
assignment['samlSsoInfo']['inboundSamlSsoProfile'] = info_profile(return_only=True,
|
||||||
|
displayName=f'id:{profile}',
|
||||||
|
ci=ci)
|
||||||
|
display.print_json(assignment)
|
||||||
|
|
||||||
|
|
||||||
'''gam print inboundssoassignments'''
|
'''gam print inboundssoassignments'''
|
||||||
def print_assignments():
|
def print_show_assignments(action='print'):
|
||||||
ci = build()
|
ci = build()
|
||||||
customer = get_sso_customer()
|
customer = get_sso_customer()
|
||||||
_filter = f'customer=="{customer}"'
|
_filter = f'customer=="{customer}"'
|
||||||
|
todrive = False
|
||||||
|
i = 3
|
||||||
|
while i < len(sys.argv):
|
||||||
|
myarg = sys.argv[i].lower().replace('_', '')
|
||||||
|
if myarg == 'todrive':
|
||||||
|
todrive = True
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
controlflow.invalid_argument_exit(myarg, 'gam print inboundssoassignments')
|
||||||
assignments = gapi.get_all_pages(ci.inboundSsoAssignments(),
|
assignments = gapi.get_all_pages(ci.inboundSsoAssignments(),
|
||||||
'list',
|
'list',
|
||||||
'inboundSsoAssignments',
|
'inboundSsoAssignments',
|
||||||
@@ -379,6 +485,20 @@ def print_assignments():
|
|||||||
ou_id = ou_id.split('/')[1]
|
ou_id = ou_id.split('/')[1]
|
||||||
ou_id = f'id:{ou_id}'
|
ou_id = f'id:{ou_id}'
|
||||||
assignment['orgUnit'] = gapi_directory_orgunits.orgunit_from_orgunitid(ou_id, cd)
|
assignment['orgUnit'] = gapi_directory_orgunits.orgunit_from_orgunitid(ou_id, cd)
|
||||||
display.print_json(assignment)
|
if action == 'show':
|
||||||
print()
|
for assignment in assignments:
|
||||||
|
display.print_json(assignment)
|
||||||
|
print()
|
||||||
|
elif action == 'print':
|
||||||
|
titles = []
|
||||||
|
csv_rows = []
|
||||||
|
for assignment in assignments:
|
||||||
|
csv_row = utils.flatten_json(assignment)
|
||||||
|
for item in csv_row:
|
||||||
|
if item not in titles:
|
||||||
|
titles.append(item)
|
||||||
|
csv_rows.append(csv_row)
|
||||||
|
display.write_csv_file(csv_rows,
|
||||||
|
titles,
|
||||||
|
'Inbound SSO Assignments',
|
||||||
|
todrive)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import sys
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
import gam
|
import gam
|
||||||
|
from gam import controlflow
|
||||||
from gam import display
|
from gam import display
|
||||||
from gam import gapi
|
from gam import gapi
|
||||||
from gam.gapi import directory as gapi_directory
|
from gam.gapi import directory as gapi_directory
|
||||||
@@ -18,7 +19,7 @@ def delete():
|
|||||||
userKey=user_email,
|
userKey=user_email,
|
||||||
throw_reasons=[gapi_errors.ErrorReason.CONDITION_NOT_MET])
|
throw_reasons=[gapi_errors.ErrorReason.CONDITION_NOT_MET])
|
||||||
except gam.gapi.errors.GapiConditionNotMetError as err:
|
except gam.gapi.errors.GapiConditionNotMetError as err:
|
||||||
display.print_error(
|
controlflow.system_error_exit(3,
|
||||||
f'{err} The user {user_email} may be (or have recently been) on Google Vault Hold and thus not eligible for deletion. You can check holds with "gam user <email> show vaultholds".'
|
f'{err} The user {user_email} may be (or have recently been) on Google Vault Hold and thus not eligible for deletion. You can check holds with "gam user <email> show vaultholds".'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user