Ƙirƙirar Masu Amfani da Google daga PowerShell ta API

Sannu!

Wannan labarin zai bayyana aiwatar da hulɗar PowerShell tare da Google API don sarrafa masu amfani da G Suite.

Muna amfani da sabis na ciki da na gajimare da yawa a cikin ƙungiyar. Ga mafi yawancin, izini a cikin su yana zuwa zuwa Google ko Active Directory, tsakanin wanda ba za mu iya kula da kwafi ba; saboda haka, lokacin da sabon ma'aikaci ya bar, kuna buƙatar ƙirƙira / kunna asusu a cikin waɗannan tsarin guda biyu. Don sarrafa tsarin, mun yanke shawarar rubuta rubutun da ke tattara bayanai kuma ya aika zuwa ayyukan biyu.

Izini

Lokacin zana buƙatun, mun yanke shawarar amfani da ainihin masu gudanar da ɗan adam don ba da izini; wannan yana sauƙaƙa nazarin ayyuka a yayin babban canje-canje na haɗari ko ganganci.

Google APIs suna amfani da ka'idar OAuth 2.0 don tantancewa da izini. Amfani da lokuta kuma ana iya samun ƙarin cikakkun bayanai anan: Amfani da OAuth 2.0 don Samun damar Google APIs.

Na zaɓi rubutun da ake amfani da shi don izini a aikace-aikacen tebur. Hakanan akwai zaɓi don amfani da asusun sabis, wanda baya buƙatar motsi mara amfani daga mai amfani.

Hoton da ke ƙasa bayanin tsari ne na yanayin da aka zaɓa daga shafin Google.

Ƙirƙirar Masu Amfani da Google daga PowerShell ta API

  1. Da farko, muna aika mai amfani zuwa shafin tantance asusun Google, yana ƙayyadadden sigogin GET:
    • aikace-aikace id
    • yankunan da aikace-aikacen ke buƙatar samun dama ga
    • adireshin da za a tura mai amfani bayan kammala aikin
    • hanyar da za mu sabunta alamar
    • Lambar Tsaro
    • lambar tabbatarwa tsarin watsawa

  2. Bayan an gama izini, za a tura mai amfani zuwa shafin da aka kayyade a farkon buƙatun, tare da kuskure ko lambar izini da sigogin GET suka wuce.
  3. Aikace-aikacen (rubutun) zai buƙaci karɓar waɗannan sigogi kuma, idan an karɓi lambar, yi buƙatun mai zuwa don samun alamun
  4. Idan buƙatar ta yi daidai, Google API zai dawo:
    • Alamar shiga da za mu iya yin buƙatu da ita
    • Lokacin ingancin wannan alamar
    • Alamar wartsake da ake buƙata don sabunta alamar shiga.

Da farko kuna buƙatar zuwa Google API console: Takardun shaida - Google API Console, zaɓi aikace-aikacen da ake so kuma a cikin sashin Sharuɗɗa ƙirƙiri mai gano abokin ciniki OAuth. A can (ko daga baya, a cikin kaddarorin da aka ƙirƙira mai ganowa) kuna buƙatar saka adiresoshin da aka ba da izinin turawa. A cikin yanayinmu, waɗannan za su zama shigarwar gida da yawa tare da tashoshin jiragen ruwa daban-daban (duba ƙasa).

Don ƙara dacewa don karanta algorithm ɗin rubutun, zaku iya nuna matakan farko a cikin wani aikin daban wanda zai dawo da shiga da sabunta alamun aikace-aikacen:

$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

Mun saita ID ɗin Abokin ciniki da Sirrin Abokin ciniki da aka samu a cikin kaddarorin gano abokin ciniki na OAuth, kuma mai tabbatar da lamba shine kirtani na haruffa 43 zuwa 128 waɗanda dole ne a ƙirƙira su ba da gangan ba daga haruffa marasa ajiya: [AZ] / [az] / [0-9] / "-" / "." / "_" / "~".

Daga nan za a sake watsa wannan lambar. Yana kawar da lahanin da maharin zai iya tsai da martanin da aka dawo a matsayin turawa bayan izinin mai amfani.
Kuna iya aika mai tabbatar da lambar a cikin buƙatun na yanzu a cikin bayyanannen rubutu (wanda ya sa ya zama mara ma'ana - wannan ya dace da tsarin da ba sa goyan bayan SHA256), ko ta hanyar ƙirƙirar zanta ta amfani da SHA256 algorithm, wanda dole ne a sanya shi a cikin BASE64Url (mabambanta). daga Base64 ta haruffan tebur guda biyu) da kuma cire ƙarshen layin layi: =.

Na gaba, muna buƙatar fara sauraron http akan na'ura na gida don karɓar amsa bayan izini, wanda za a mayar da shi azaman turawa.

Ana yin ayyukan gudanarwa akan sabar ta musamman, ba za mu iya yanke hukuncin cewa masu gudanarwa da yawa za su gudanar da rubutun a lokaci guda ba, don haka ba da gangan ba za ta zaɓi tashar jiragen ruwa don mai amfani na yanzu, amma na ƙayyade tashar jiragen ruwa da aka riga aka ƙayyade saboda. dole ne kuma a ƙara su kamar yadda aka amince da su a cikin na'urar wasan bidiyo na API.

access_type=offline yana nufin cewa aikace-aikacen na iya sabunta alamar da ta ƙare da kanta ba tare da hulɗar mai amfani da mai binciken ba,
amsa_type=kodi yana saita tsarin yadda za'a dawo da lambar (magana ga tsohuwar hanyar ba da izini, lokacin da mai amfani ya kwafi lambar daga mai binciken zuwa cikin rubutun),
ikonsa yana nuna iyaka da nau'in shiga. Dole ne a raba su ta sarari ko %20 (bisa ga Rufin URL). Ana iya ganin jerin wuraren shiga tare da nau'ikan a nan: Matsakaicin OAuth 2.0 don Google APIs.

Bayan karɓar lambar izini, aikace-aikacen zai dawo da saƙon kusa ga mai binciken, dakatar da sauraron tashar jiragen ruwa kuma aika buƙatar POST don samun alamar. Mun nuna a ciki da ƙayyadaddun id da sirri daga API ɗin console, adireshin da za a tura mai amfani da Grant_type daidai da ƙayyadaddun ƙa'idar.

A cikin martani, za mu sami alamar shiga, lokacin ingancin sa a cikin daƙiƙa, da alamar Refresh, wanda da shi zamu iya sabunta alamar shiga.

Dole ne aikace-aikacen ya adana alamun a cikin amintaccen wuri tare da tsawon rai, don haka har sai mun soke damar da aka samu, aikace-aikacen ba zai dawo da alamar refresh ba. A ƙarshe, na ƙara buƙatar soke alamar; idan ba a kammala aikace-aikacen cikin nasara ba kuma ba a dawo da alamar refresh ba, za ta sake fara aikin (mun yi la'akari da cewa ba shi da haɗari don adana alamun gida a kan tashar, kuma mun yi aiki). 'Bana son rikitarwa abubuwa da cryptography ko bude browser akai-akai).

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
}

Kamar yadda kuka riga kuka lura, lokacin soke alama, ana amfani da Invoke-WebRequest. Ba kamar Invoke-RestMethod ba, baya mayar da bayanan da aka karɓa a cikin tsari mai amfani kuma yana nuna matsayin buƙatar.

Bayan haka, rubutun yana tambayarka don shigar da sunan farko da na ƙarshe na mai amfani, yana samar da shiga + imel.

Bukatu

Buƙatun na gaba za su kasance - da farko, kuna buƙatar bincika ko mai amfani da shiga iri ɗaya ya riga ya wanzu don samun shawara kan ƙirƙirar sabo ko kunna na yanzu.

Na yanke shawarar aiwatar da duk buƙatun a cikin tsarin aiki ɗaya tare da zaɓi, ta amfani da sauyawa:

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'])
      }
    }
  }
}

A cikin kowace buƙatu, kuna buƙatar aika taken izini mai ɗauke da nau'in alamar da alamar shiga kanta. A halin yanzu, nau'in alamar koyaushe shine Bearer. Domin muna buƙatar bincika cewa alamar ba ta ƙare ba kuma mu sabunta shi bayan sa'a guda daga lokacin da aka fitar da shi, na ƙayyade buƙatar wani aikin da ke dawo da alamar Access. Wannan yanki ɗaya na lambar yana a farkon rubutun lokacin karɓar alamar shiga ta farko:

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
}

Duba shiga don wanzuwa:

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
}

Saƙon imel: buƙatar tambayar $ zai tambayi API don neman mai amfani da ainihin imel ɗin, gami da laƙabi. Hakanan zaka iya amfani da katin ƙira: =,:, :{PREFIX}*.

Don samun bayanai, yi amfani da hanyar neman GET, don saka bayanai (ƙirƙirar asusu ko ƙara memba zuwa ƙungiya) - POST, don sabunta bayanan da ke akwai - PUT, don share rikodin (misali, memba daga rukuni) - GAME.

Rubutun kuma zai nemi lambar waya (lambar da ba ta da inganci) da kuma haɗawa cikin rukunin rarraba yanki. Yana yanke shawarar wace ƙungiyar ƙungiya mai amfani yakamata ya kasance bisa zaɓin Active Directory OU kuma ya fito da kalmar sirri:

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"

Sannan ya fara sarrafa asusun:

$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
}

Ayyukan ɗaukaka da ƙirƙirar asusu suna da irin wannan haɗin gwiwa; ba duk ƙarin filayen da ake buƙata ba; a cikin sashin da lambobin waya, kuna buƙatar ƙididdige tsararru wanda zai iya ƙunsar rikodin har zuwa guda tare da lambar da nau'in sa.

Domin kar a sami kuskure yayin ƙara mai amfani zuwa ƙungiya, zamu iya fara bincika ko ya riga ya kasance memba na wannan rukunin ta hanyar samun jerin sunayen membobin ƙungiyar ko abun da ke ciki daga mai amfani da kansa.

Neman membobin ƙungiyar na takamaiman mai amfani ba zai zama mai maimaitawa ba kuma zai nuna membobin kai tsaye kawai. Haɗe da mai amfani a cikin ƙungiyar iyaye waɗanda tuni suna da ƙungiyar yara waɗanda mai amfani ya kasance memba na zai yi nasara.

ƙarshe

Abin da ya rage shi ne aika mai amfani da kalmar sirri don sabon asusun. Muna yin haka ta hanyar SMS, kuma mu aika da cikakken bayani tare da umarni da shiga cikin imel na sirri, wanda, tare da lambar waya, sashen daukar ma'aikata ya bayar. A matsayin madadin, zaku iya ajiye kuɗi kuma ku aika kalmar wucewa ta sirrin hira ta wayar tarho, wanda kuma ana iya la'akari da abu na biyu (MacBooks zai zama banda).

Na gode don karantawa har zuwa ƙarshe. Zan yi farin cikin ganin shawarwari don inganta salon rubutun labarai kuma ina fata ku sami ƴan kurakurai lokacin rubuta rubutun =)

Jerin hanyoyin haɗin yanar gizo waɗanda ƙila su zama masu fa'ida ta zahiri ko kuma a sauƙaƙe amsa tambayoyi:

source: www.habr.com

Add a comment