Abuuritaanka Isticmaalayaasha Google ee PowerShell iyada oo loo marayo API

Hello!

Maqaalkani wuxuu sharxi doonaa hirgelinta isdhexgalka PowerShell ee Google API si loo maareeyo isticmaalayaasha G Suite.

Waxaan u isticmaalnaa dhowr adeegyo gudaha iyo daruuraha guud ahaan ururka. Inta badan, oggolaanshaha iyaga ku jira waxay ku soo degtaa Google ama Hagaha Firfircoon, kaas oo aynaan sii haysan karin nuqul; si waafaqsan, marka shaqaale cusubi baxo, waxaad u baahan tahay inaad abuurto/ awood u yeelato xisaab labadan nidaam. Si loo habeeyo habka, waxaan go'aansanay inaan qorno qoraal aruuriya macluumaadka oo u diraya labada adeeg.

Oggolaanshaha

Markaan diyaarinayno shuruudaha, waxaan go'aansanay inaan isticmaalno maamulayaasha bini'aadamka dhabta ah si aan u oggolaanno; tani waxay fududaynaysaa falanqaynta ficillada haddii ay dhacdo isbeddello shil ah ama ula kac ah.

Google APIs waxay u isticmaalaan nidaamka OAuth 2.0 xaqiijinta iyo oggolaanshaha. Kiisaska la isticmaalo iyo sharraxaadyo faahfaahsan ayaa laga heli karaa halkan: Isticmaalka OAuth 2.0 si aad u gasho Google APIs.

Waxaan doortay qoraalka loo isticmaalo oggolaanshaha ee barnaamijyada desktop-ka. Waxa kale oo jira ikhtiyaarka ah in la isticmaalo akoonka adeegga, kaas oo aan uga baahnayn dhaqdhaqaaqa aan loo baahnayn ee isticmaalaha.

Sawirka hoose waa sharraxaad qaabaysan oo ku saabsan xaaladda la doortay ee bogga Google.

Abuuritaanka Isticmaalayaasha Google ee PowerShell iyada oo loo marayo API

  1. Marka hore, waxaan u dirnaa isticmaalaha bogga xaqiijinta Koontada Google, anagoo cadeynayna cabbirada GET:
    • codsiga id
    • meelaha uu codsigu u baahan yahay in la galo
    • ciwaanka uu isticmaaluhu dib u hagi doono ka dib marka uu habsocodku dhameeyo
    • habka aan u cusbooneysiin doono calaamadda
    • Numberka Sirta
    • qaabka gudbinta code xaqiijinta

  2. Kadib marka oggolaanshaha la dhammeeyo, isticmaaluhu waxa loo wareejin doonaa bogga lagu cayimay codsiga ugu horreeya, iyada oo khalad ama koodka oggolaanshaha uu gudbiyay cabbirrada GET
  3. Codsiga (script) wuxuu u baahan doonaa inuu helo xuduudahan oo, haddii la helo koodka, samee codsiga soo socda si loo helo calaamado
  4. Haddii codsigu sax yahay, Google API wuxuu soo celinayaa:
    • Calaamada gelitaanka oo aan ku samayn karno codsiyo
    • Muddada ansaxnimada calaamaddan
    • Calaamada soo kicinta ayaa loo baahan yahay si loo cusboonaysiiyo calaamada Helitaanka

Marka hore waxaad u baahan tahay inaad tagto Google API console: Aqoonsiga - Google API Console, dooro arjiga la rabo oo qaybta shahaadooyinka ku samee aqoonsiga OAuth ee macmiilka. Halkaa (ama ka dib, guryaha aqoonsiga la abuuray) waxaad u baahan tahay inaad qeexdo cinwaanada dib u habeynta loo oggol yahay. Xaaladeena, kuwani waxay noqon doonaan dhowr gelis maxalli ah oo leh dekedo kala duwan (eeg hoos).

Si aad uga dhigto mid ku habboon in la akhriyo algorithm-ka qoraalka, waxaad ku soo bandhigi kartaa tillaabooyinka ugu horreeya hawl gooni ah oo soo celin doonta gelitaanka iyo soo kicinta calaamadaha codsiga:

$client_secret = 'Our Client Secret'
$client_id = 'Our Client ID'
function Get-GoogleAuthToken {
  if (-not [System.Net.HttpListener]::IsSupported) {
    "HttpListener is not supported."
    exit 1
  }
  $codeverifier = -join ((65..90) + (97..122) + (48..57) + 45 + 46 + 95 + 126 |Get-Random -Count 60| % {[char]$_})
  $hasher = new-object System.Security.Cryptography.SHA256Managed
  $hashByteArray = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($codeverifier))
  $base64 = ((([System.Convert]::ToBase64String($hashByteArray)).replace('=','')).replace('+','-')).replace('/','_')
  $ports = @(10600,15084,39700,42847,65387,32079)
  $port = $ports[(get-random -Minimum 0 -maximum 5)]
  Write-Host "Start browser..."
  Start-Process "https://accounts.google.com/o/oauth2/v2/auth?code_challenge_method=S256&code_challenge=$base64&access_type=offline&client_id=$client_id&redirect_uri=http://localhost:$port&response_type=code&scope=https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/admin.directory.group"
  $listener = New-Object System.Net.HttpListener
  $listener.Prefixes.Add("http://localhost:"+$port+'/')
  try {$listener.Start()} catch {
    "Unable to start listener."
    exit 1
  }
  while (($code -eq $null)) {
    $context = $listener.GetContext()
    Write-Host "Connection accepted" -f 'mag'
    $url = $context.Request.RawUrl
    $code = $url.split('?')[1].split('=')[1].split('&')[0]
    if ($url.split('?')[1].split('=')[0] -eq 'error') {
      Write-Host "Error!"$code -f 'red'
      $buffer = [System.Text.Encoding]::UTF8.GetBytes("Error!"+$code)
      $context.Response.ContentLength64 = $buffer.Length
      $context.Response.OutputStream.Write($buffer, 0, $buffer.Length)
      $context.Response.OutputStream.Close()
      $listener.Stop()
      exit 1
    }
    $buffer = [System.Text.Encoding]::UTF8.GetBytes("Now you can close this browser tab.")
    $context.Response.ContentLength64 = $buffer.Length
    $context.Response.OutputStream.Write($buffer, 0, $buffer.Length)
    $context.Response.OutputStream.Close()
    $listener.Stop()
  }
  Return Invoke-RestMethod -Method Post -Uri "https://www.googleapis.com/oauth2/v4/token" -Body @{
    code = $code
    client_id = $client_id
    client_secret = $client_secret
    redirect_uri = 'http://localhost:'+$port
    grant_type = 'authorization_code'
    code_verifier   = $codeverifier
  }
  $code = $null

Waxaan dejinay Aqoonsiga Macmiilka iyo Sirta Macmiilka ee laga helay OAuth guryaha aqoonsiga macmiilka, iyo xaqiijiyaha koodka waa xadhig ka kooban 43 ilaa 128 xaraf oo ay tahay in si aan kala sooc lahayn looga soo saaro jilayaasha aan kaydsanin: [AZ] / [az] / [0-9] / "-" / "." / "_" / "~".

Koodhkan ayaa markaa mar kale la gudbin doonaa. Waxay meesha ka saaraysaa u nuglaanshaha uu qofka wax weeraraya ka qaban karo jawaabta loo soo celiyay dib u jiheynta ka dib oggolaanshaha isticmaalaha.
Waxaad u diri kartaa xaqiijinta koodka codsiga hadda jira qoraal cad (taas oo ka dhigaysa mid aan macno lahayn - tani waxay ku habboon tahay oo keliya nidaamyada aan taageerin SHA256), ama adoo abuuraya xashiish adoo isticmaalaya algorithm SHA256, kaas oo ay tahay in lagu dhejiyo BASE64Url ( kala duwan laga bilaabo Base64 oo leh laba xaraf oo miis ah) oo ka saara dhamaadka xariiqda xarriiqda: =.

Marka xigta, waxaan u baahanahay inaan bilowno dhageysiga http mashiinka maxalliga ah si aan u helno jawaab ka dib oggolaanshaha, kaas oo dib loogu soo celin doono.

Hawlaha maamulka waxaa lagu qabtaa server gaar ah, kama saari karno suurtagalnimada in dhowr maamulayaal ay isku mar wada shaqeeyaan qoraalka, sidaas darteed waxay si aan kala sooc lahayn u dooran doontaa deked isticmaalaha hadda, laakiin waxaan cayimay dekedo horay loo sii qeexay sababtoo ah sidoo kale waa in lagu daraa sida lagu kalsoon yahay API console.

access_type=offline macneheedu waxa weeye in arjigu iskii u cusboonaysiin karo calaamada dhacday iyada oo aan isticmaaluhu la falgelin browserka,
jawaab_type=kood dejiyaa qaabka sida koodka dib loogu soo celinayo (tixraac habkii hore ee oggolaanshaha, markii isticmaaluhu koodhka ka soo guuriyay browserka oo galay qoraalka),
baaxad waxay tilmaamaysaa baaxadda iyo nooca gelitaanka. Waa in lagu kala saaraa meelo bannaan ama %20 (sida ku cad URL Encoding). Liiska meelaha laga galo oo leh noocyo ayaa laga arki karaa halkan: Baaxadda OAuth 2.0 ee Google APIs.

Ka dib markii la helo nambarka oggolaanshaha, codsigu wuxuu ku soo celin doonaa fariin u dhow browserka, joojiya dhegeysiga dekedda oo soo diri codsi POST si loo helo calaamadda. Waxaan ku tusinaa aqoonsiga hore loo cayimay iyo sirta ka socota API-ga console-ka, ciwaanka adeegsadaha loo wareejin doono iyo Grant_type iyadoo la raacayo qeexitaanka borotokoolka.

Jawaabta, waxaan ku heli doonaa calaamada Helitaanka, muddada ay shaqaynayso ilbidhiqsiyo gudahood, iyo calaamad cusub, kaas oo aan ku cusboonaysiin karno calaamada Helitaanka.

Codsigu waa inuu ku kaydiyaa calaamadaha meel aamin ah oo cimri dheer leh, markaa ilaa aan ka noqono gelitaanka la helay, codsigu ma soo celin doono calaamada dib u soo kicinta. Dhammaadkii, waxaan ku daray codsi ah in la buriyo calaamadda; haddii codsiga aan si guul leh loo dhammayn oo calaamada dib u soo celinta aan la soo celin, waxay bilaabi doontaa nidaamka mar kale (waxaan u aragnay inay tahay mid aan badbaado lahayn in lagu kaydiyo calaamadaha gudaha terminalka, annaguna waan sameynay Ma rabto in aad wax ku xoojiso cryptografiga ama aad si joogto ah u furto browserka).

do {
  $token_result = Get-GoogleAuthToken
  $token = $token_result.access_token
  if ($token_result.refresh_token -eq $null) {
    Write-Host ("Session is not destroyed. Revoking token...")
    Invoke-WebRequest -Uri ("https://accounts.google.com/o/oauth2/revoke?token="+$token)
  }
} while ($token_result.refresh_token -eq $null)
$refresh_token = $token_result.refresh_token
$minute = ([int]("{0:mm}" -f ([timespan]::fromseconds($token_result.expires_in))))+((Get-date).Minute)-2
if ($minute -lt 0) {$minute += 60}
elseif ($minute -gt 59) {$minute -=60}
$token_expire = @{
  hour = ([int]("{0:hh}" -f ([timespan]::fromseconds($token_result.expires_in))))+((Get-date).Hour)
  minute = $minute
}

Sidaad horeyba u aragtay, marka aad burinayso calaamada, Codsiga-WebCodka ayaa la isticmaalaa. Si ka duwan Invoke-RestMethod, kuma soo celiso xogta la helay qaab la isticmaali karo waxayna tusinaysaa heerka codsiga.

Marka xigta, qoraalku wuxuu ku weydiinayaa inaad geliso isticmaalaha magaciisa koowaad iyo kan dambe, adigoo abuuraya soo gal + iimaylka.

Codsiyada

Codsiyada soo socdaa waxay noqon doonaan - marka hore, waxaad u baahan tahay inaad hubiso in isticmaale isla login uu hore u jiray si aad u hesho go'aan ku saabsan abuurista mid cusub ama awood siinta kan hadda jira.

Waxaan go'aansaday inaan hirgeliyo dhammaan codsiyada qaabka hal shaqo oo leh xulasho, anigoo isticmaalaya furaha:

function GoogleQuery {
  param (
    $type,
    $query
  )
  switch ($type) {
    "SearchAccount" {
      Return Invoke-RestMethod -Method Get -Uri "https://www.googleapis.com/admin/directory/v1/users" -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body @{
        domain = 'rocketguys.com'
        query  = "email:$query"
      }
    }
    "UpdateAccount" {
      $body = @{
        name  = @{
          givenName = $query['givenName']
          familyName = $query['familyName']
        }
        suspended = 'false'
        password = $query['password']
        changePasswordAtNextLogin = 'true'
        phones = @(@{
          primary = 'true'
          value = $query['phone']
          type = "mobile"
        })
        orgUnitPath = $query['orgunit']
      }
      Return Invoke-RestMethod -Method Put -Uri ("https://www.googleapis.com/admin/directory/v1/users/"+$query['email']) -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body (ConvertTo-Json $body) -ContentType 'application/json; charset=utf-8'
    }
    
    "CreateAccount" {
      $body = @{
        primaryEmail = $query['email']
        name  = @{
          givenName = $query['givenName']
          familyName = $query['familyName']
        }
        suspended = 'false'
        password = $query['password']
        changePasswordAtNextLogin = 'true'
        phones = @(@{
          primary = 'true'
          value = $query['phone']
          type = "mobile"
        })
        orgUnitPath = $query['orgunit']
      }
      Return Invoke-RestMethod -Method Post -Uri "https://www.googleapis.com/admin/directory/v1/users" -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body (ConvertTo-Json $body) -ContentType 'application/json; charset=utf-8'
    }
    "AddMember" {
      $body = @{
        userKey = $query['email']
      }
      $ifrequest = Invoke-RestMethod -Method Get -Uri "https://www.googleapis.com/admin/directory/v1/groups" -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body $body
      $array = @()
      foreach ($group in $ifrequest.groups) {$array += $group.email}
      if ($array -notcontains $query['groupkey']) {
        $body = @{
          email = $query['email']
          role = "MEMBER"
        }
        Return Invoke-RestMethod -Method Post -Uri ("https://www.googleapis.com/admin/directory/v1/groups/"+$query['groupkey']+"/members") -Headers @{Authorization = "Bearer "+(Get-GoogleToken)} -Body (ConvertTo-Json $body) -ContentType 'application/json; charset=utf-8'
      } else {
        Return ($query['email']+" now is a member of "+$query['groupkey'])
      }
    }
  }
}

Codsi kasta, waxaad u baahan tahay inaad dirto madaxa Oggolaanshaha ka kooban nooca calaamada iyo calaamadda Helitaanka lafteeda. Hadda, nooca calaamaduhu had iyo jeer waa Bearer. Sababtoo ah Waxaan u baahanahay inaan hubino in calaamadda aysan dhicin oo aan cusbooneysiinno saacad ka dib markii la soo saaray, waxaan cayimay codsi shaqo kale oo soo celiya calaamadda Helitaanka. Isla gabal kood ah ayaa ku yaal bilowga qoraalka marka la helayo calaamadda Helitaanka koowaad:

function Get-GoogleToken {
  if (((Get-date).Hour -gt $token_expire.hour) -or (((Get-date).Hour -ge $token_expire.hour) -and ((Get-date).Minute -gt $token_expire.minute))) {
  Write-Host "Token Expired. Refreshing..."
    $request = (Invoke-RestMethod -Method Post -Uri "https://www.googleapis.com/oauth2/v4/token" -ContentType 'application/x-www-form-urlencoded' -Body @{
      client_id = $client_id
      client_secret = $client_secret
      refresh_token = $refresh_token
      grant_type = 'refresh_token'
    })
    $token = $request.access_token
    $minute = ([int]("{0:mm}" -f ([timespan]::fromseconds($request.expires_in))))+((Get-date).Minute)-2
    if ($minute -lt 0) {$minute += 60}
    elseif ($minute -gt 59) {$minute -=60}
    $script:token_expire = @{
      hour = ([int]("{0:hh}" -f ([timespan]::fromseconds($request.expires_in))))+((Get-date).Hour)
      minute = $minute
    }
  }
  return $token
}

Hubinta gelitaanka jiritaanka:

function Check_Google {
  $query = (GoogleQuery 'SearchAccount' $username)
  if ($query.users -ne $null) {
    $user = $query.users[0]
    Write-Host $user.name.fullName' - '$user.PrimaryEmail' - suspended: '$user.Suspended
    $GAresult = $user
  }
  if ($GAresult) {
      $return = $GAresult
  } else {$return = 'gg'}
  return $return
}

Iimaylka: $question request wuxuu ku weydiin doonaa API-ga inuu raadiyo isticmaale si sax ah iimaylkaas, oo ay ku jiraan magacyo. Waxa kale oo aad isticmaali kartaa khariidad: =,:, :{PREFIX}*.

Si aad xogta u hesho, isticmaal habka codsiga GET, si aad xogta u geliso (abuurista akoon ama ku darista xubin koox) - POST, si aad u cusboonaysiiso xogta jirta - PUT, si aad u tirtirto diiwaanka (tusaale, xubin ka tirsan koox) - Tirtir

Qoraalku waxa kale oo uu waydiin doonaa nambar telefoon (xadhig aan ansax ahayn) iyo in lagu daro kooxda qaybinta gobolka. Waxay go'aaminaysaa unugga urureedka isticmaaluhu waa inuu lahaadaa iyadoo lagu salaynayo Hagaha Firfircoon ee OU ee la doortay wuxuuna la imaanayaa erayga sirta ah:

do {
  $phone = Read-Host "Π’Π΅Π»Π΅Ρ„ΠΎΠ½ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ +7Ρ…Ρ…Ρ…Ρ…Ρ…Ρ…Ρ…Ρ…"
} while (-not $phone)
do {
    $moscow = Read-Host "Π’ Московский офис? (y/n) "
} while (-not (($moscow -eq 'y') -or ($moscow -eq 'n')))
$orgunit = '/'
if ($OU -like "*OU=Delivery,OU=Users,OU=ROOT,DC=rocket,DC=local") {
    Write-host "Π‘ΡƒΠ΄Π΅Ρ‚ создана Π² /Team delivery"
    $orgunit = "/Team delivery"
}
$Password =  -join ( 48..57 + 65..90 + 97..122 | Get-Random -Count 12 | % {[char]$_})+"*Ba"

Kadibna wuxuu bilaabay inuu xisaabiyo xisaabaadka:

$query = @{
  email = $email
  givenName = $firstname
  familyName = $lastname
  password = $password
  phone = $phone
  orgunit = $orgunit
}
if ($GMailExist) {
  Write-Host "ЗапускаСм ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°" -f mag
  (GoogleQuery 'UpdateAccount' $query) | fl
  write-host "НС Π·Π°Π±ΡƒΠ΄ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π³Ρ€ΡƒΠΏΠΏΡ‹ Ρƒ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ $Username Π² Google."
} else {
  Write-Host "ЗапускаСм созданиС Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°" -f mag
  (GoogleQuery 'CreateAccount' $query) | fl
}
if ($moscow -eq "y"){
  write-host "ДобавляСм Π² Π³Ρ€ΡƒΠΏΠΏΡƒ moscowoffice"
  $query = @{
    groupkey = '[email protected]'
    email = $email
  }
  (GoogleQuery 'AddMember' $query) | fl
}

Hawlaha cusboonaysiinta iyo abuurista akoonku waxay leeyihiin isku mid, looma baahna dhammaan meelaha dheeraadka ah, qaybta leh lambarada taleefanka, waxaad u baahan tahay inaad qeexdo array ka koobnaan kara ilaa hal rikoodh oo lambarka iyo noociisa ah.

Si aan cilad u helin marka isticmaale koox lagu daro, waxaan marka hore hubin karnaa in uu horay uga tirsanaan jiray kooxdan anagoo ka helayna liiska xubnaha kooxda ama halabuurka isticmaalaha laftiisa.

Weydiinta xubinnimada kooxda ee isticmaale gaar ah ma noqon doonto mid soo noqnoqota oo waxay muujinaysaa xubinnimada tooska ah. Ku darida isticmaalaha kooxda waalidka ee horey u lahaa koox caruur ah oo isticmaaluhu uu xubin ka yahay ayaa guulaysan doona.

gunaanad

Waxa hadhay oo dhan waa in loo diro isticmaalaha erayga sirta ah ee akoonka cusub. Waxaan ku sameynaa tan SMS-ka, waxaana ku dirnaa macluumaad guud oo leh tilmaamo iyo galitaanka iimaylka gaarka ah, kaas oo, oo ay weheliso lambarka taleefanka, ay bixisay waaxda shaqaalaynta. Beddel ahaan, waxaad kaydin kartaa lacag oo aad u diri kartaa eraygaaga sirta ah sirta telegram-ka sirta ah, taas oo sidoo kale loo tixgelin karo qodobka labaad (MacBooks waxay noqon doontaa mid ka reeban).

Waad ku mahadsan tahay akhrinta ilaa dhamaadka. Waan ku farxi doonaa inaan arko talooyinka hagaajinta habka qorista maqaallada waxaanan jeclaan lahaa inaad qabato khaladaad yar markaad qoreyso qoraallada =)

Liiska xiriiriyeyaasha laga yaabo inay mawduuc ahaan faa'iido u yeeshaan ama si fudud uga jawaabaan su'aalaha:

Source: www.habr.com

Add a comment