diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index af0dd2a3..cb6cca9f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -565,6 +565,17 @@ jobs: export newbuilding="${newbase}-building" export newresource="${newbase}-resource" export newou="aaaGithub Actions/${newbase}" + + # cleanup old runs + GAM_CSV_ROW_FILTER="name:regex:gha_test_${JID}_" $gam print vaultholds | $gam csv - gam delete vaulthold "id:~~holdId~~" matter "id:~~matterId~~" + GAM_CSV_ROW_FILTER="name:regex:gha_test_${JID}_" $gam print features | $gam csv - gam delete feature ~name + GAM_CSV_ROW_FILTER="name:regex:^gha_test_${JID}_" $gam user $gam_user print shareddrives asadmin | $gam csv - gam user $gam_user delete shareddrive ~id nukefromorbit + $gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail + GAM_CSV_ROW_FILTER="name:regex:^gha_test_${JID}_" $gam print ous fromparent "aaaGithub Actions" | $gam csv - gam delete ou ~orgUnitId + GAM_CSV_ROW_FILTER="groupKey.id:regex:^gha_test_${JID}_" $gam print cigroups | $gam csv - gam delete cigroup ~groupKey.id + GAM_CSV_ROW_FILTER="resourceId:regex:^gha_test_${JID}_" $gam print resources | $gam csv - gam delete resource ~resourceId + GAM_CSV_ROW_FILTER="buildingId:regex:^gha_test_${JID}_" $gam print buildings | $gam csv - gam delete building ~buildingId + echo "Creating OrgUnit ${newou}" $gam create ou "${newou}" export GAM_THREADS=5 @@ -617,8 +628,8 @@ jobs: $gam users "$newbase-bulkuser-7 $newbase-bulkuser-8 $newbase-bulkuser-9" modify messages query in:anywhere maxtomodify 99999 addlabel IMPORTANT addlabel STARRED doit $gam user $newuser delete label --ALL_LABELS-- GAM_CSV_ROW_FILTER="name:regex:gha-test-${JID}" $gam print features | $gam csv - gam delete feature ~name - $gam create feature name Whiteboard-$newbase $gam create feature name VC-$newbase + $gam create feature name Whiteboard-$newbase $gam create building "My Building - $newbase" id $newbuilding floors 1,2,3,4,5,6,7,8,9,10,11,12,14,15 description "No 13th floor here..." $gam create resource $newresource "Resource Calendar $tstamp" capacity 25 features Whiteboard-$newbase,VC-$newbase building $newbuilding floor 15 type Room $gam info resource $newresource @@ -654,8 +665,8 @@ jobs: $gam delete hold "GHA hold $newbase" matter $matterid $gam update matter $matterid action close $gam update matter $matterid action delete - #$gam delete user $newuser - #$gam undelete user $newuser + # shakes off vault hold on user so we can delete + $gam print users query "email:${newuser}" orgunitpath | $gam csv - gam update user ~primaryEmail ou ~orgUnitPath $gam delete user $newuser $gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail $gam print mobile @@ -671,8 +682,8 @@ jobs: $gam report users fields accounts:is_less_secure_apps_access_allowed,gmail:last_imap_time,gmail:last_pop_time filters "accounts:last_login_time>2019-01-01T00:00:00.000Z" todrive $gam report admin start -3d todrive $gam print devices nopersonaldevices nodeviceusers filter "serial:$JID$JID$JID$JID-" | $gam csv - gam delete device id ~name - #$gam print userinvitations - #$gam print userinvitations | $gam csv - gam send userinvitation ~name + $gam print userinvitations + $gam print userinvitations | $gam csv - gam send userinvitation ~name $gam create caalevel "zzz_${newbase}" basic condition ipsubnetworks 1.1.1.1/32,2.2.2.2/32 endcondition $gam print caalevels $gam delete caalevel "zzz_${newbase}" @@ -727,11 +738,6 @@ jobs: - name: Download artifacts uses: actions/download-artifact@v3 - - name: Set datetime version string - id: dateversion - run: | - echo "dateversion=$(date +'%Y%m%d.%k%M%S')" >> $GITHUB_STATE - - name: VirusTotal Scan uses: crazy-max/ghaction-virustotal@v3 with: @@ -743,9 +749,8 @@ jobs: name: Publish draft release with: repo_token: "${{ secrets.GITHUB_TOKEN }}" - automatic_release_tag: ${{ steps.dateversion.outputs.dateversion }} + automatic_release_tag: latest prerelease: false draft: true - title: "GAM ${{ steps.dateversion.outputs.dateversion }}" files: | gam-binaries/* diff --git a/src/GamCommands.txt b/src/GamCommands.txt index e7da854b..755b2fa4 100644 --- a/src/GamCommands.txt +++ b/src/GamCommands.txt @@ -1548,6 +1548,22 @@ gam print group-members|groups-members [todrive] [roles ] [membernames] [fields ] [includederivedmembership] +gam create inboundssoprofile name entityid loginurl logouturl changepasswordurl +gam update inboundssoprofile [entityid ] [loginurl ] [logouturl ] [changepasswordurl ] +gam info inboundssoprofile +gam delete inboundssoprofile +gam print inboundssoprofiles + +gam create inboundssocredentials profile (pemfile )|(generatekey [keysize 1024|2048|4096]) [replaceolddest] +gam delete inboundssocredentials +gam print inboundssocredentials [profile|profiles ] + +gam create inboundssoassignment (group rank )|(ou|org|orgunit ) + (mode sso_off)|(mode saml_sso profile )(mode domain_wide_saml_if_enabled) [neverredirect] +gam update inboundssoassignment [(group rank )|(ou|org|orgunit )] + [(mode sso_off)|(mode saml_sso profile )(mode domain_wide_saml_if_enabled)] [neverredirect] +gam print inboundssoassignments + gam send userinvitation gam cancel userinvitation gam check userinvitation|isinvitable diff --git a/src/gam/__init__.py b/src/gam/__init__.py index 1beacfdb..2c468c2e 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -11426,6 +11426,8 @@ def ProcessGAMCommand(args): i, encoding = getCharSet(i + 1) f = fileutils.open_file(filename, encoding=encoding) csvFile = csv.DictReader(f) + if not csvFile.fieldnames: + controlflow.system_error_exit(0, f'CSV file {filename} is empty') if (i == len(sys.argv)) or (sys.argv[i].lower() != 'gam') or (i + 1 == len(sys.argv)): controlflow.system_error_exit( diff --git a/src/gam/gapi/cloudidentity/inboundsso.py b/src/gam/gapi/cloudidentity/inboundsso.py index b9b833b0..e47a16b4 100644 --- a/src/gam/gapi/cloudidentity/inboundsso.py +++ b/src/gam/gapi/cloudidentity/inboundsso.py @@ -252,7 +252,7 @@ def create_credentials(): key_size = int(sys.argv[i+1]) if key_size not in allowed_sizes: controlflow.expected_argument_exit('key_size', - ALLOWED_KEY_SIZES, + allowed_sizes, key_size) i += 2 else: @@ -335,6 +335,8 @@ def print_show_credentials(action='print'): elif myarg == 'todrive': todrive = True i += 1 + for profile in sys.argv[i+1].replace(',', ' ').split(): + profiles.append(profile_displayname_to_name(profile, ci)) else: controlflow.invalid_argument_exit(myarg, 'gam print inboundssocredentials') if not profiles: @@ -408,7 +410,7 @@ def parse_assignment(body, i, ci): ci, group) i += 2 - elif myarg in ['ou', 'orgunit']: + elif myarg in ['ou', 'org', 'orgunit']: body['targetOrgUnit'] = get_orgunit_id(sys.argv[i+1]) i += 2 else: diff --git a/src/gam/gapi/vault.py b/src/gam/gapi/vault.py index 973af9a1..8cc72db0 100644 --- a/src/gam/gapi/vault.py +++ b/src/gam/gapi/vault.py @@ -11,6 +11,7 @@ from gam import controlflow from gam import display from gam import fileutils from gam import gapi +from gam.gapi import errors as gapi_errors from gam.gapi import storage as gapi_storage from gam.gapi import directory as gapi_directory from gam.gapi.directory import orgunits as gapi_directory_orgunits @@ -976,10 +977,14 @@ def printHolds(): for matterId in matterIds: i += 1 sys.stderr.write(f'Retrieving holds for matter {matterId} ({i}/{matter_count})\n') - holds = gapi.get_all_pages(v.matters().holds(), + try: + holds = gapi.get_all_pages(v.matters().holds(), 'list', 'holds', + throw_reasons=[gapi_errors.ErrorReason.FOUR_O_O], matterId=matterId) + except googleapiclient.errors.HttpError: + continue for hold in holds: display.add_row_titles_to_csv_file( utils.flatten_json(hold, flattened={'matterId': matterId}),