feat(portal): Sync transitive memberships for Google Workspace (#3524)

Simple flag flattens groups for us, the response goes from this:
```
{
  "kind": "admin#directory#members",
  "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/imfnHDtNRUYTX-TXo9Wx-Vkties\"",
  "members": [
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/MPY45KYgoPIU6Hg4EKDnN37iS_0\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "GROUP",
      "status": "ACTIVE"
    },
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/OMG8U2W2iFiQQxRb_og9WlQgmFc\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "GROUP",
      "status": "ACTIVE"
    }
  ]
}
```
to this:
```
{
  "kind": "admin#directory#members",
  "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/c7FOY_1zR63uMaLyM2_y9Y86cTA\"",
  "members": [
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/ensFY6DvZ10v87OlK6VjWqBWlb0\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "USER",
      "status": "ACTIVE"
    },
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/0zfy-53NUSeG8H9ZByTOVM29Djs\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "USER",
      "status": "ACTIVE"
    },
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/nJga9tGb4YjfHKeVSwV2a3PYu4Y\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "USER",
      "status": "ACTIVE"
    },
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/YUAlMAD1lcOVfs56U-8lm6G4Lr8\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "USER",
      "status": "ACTIVE"
    },
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/2nmJRU48HjxV9CC85ZKJ2kq80Ow\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "USER",
      "status": "ACTIVE"
    },
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/aTk1AuuEGTZFbVzVvbC7438M65Y\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "GROUP",
      "status": "ACTIVE"
    },
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/4nBIP5jw6Kxn54pjS1tjrQHtuNA\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "USER",
      "status": "ACTIVE"
    },
    {
      "kind": "admin#directory#member",
      "etag": "\"WAJlQ2CAtCOLo0U_9sYFBfdkZrUK9X-qYRarohkyMdU/luCHBeG7WcB54TUHTLr2Xy7he8s\"",
      "id": "XXXXXXX",
      "email": "XXXXXXXX@firezone.dev",
      "role": "MEMBER",
      "type": "GROUP",
      "status": "ACTIVE"
    }
  ]
}
```
and we already ignore groups in the response so no other changes are
needed.
This commit is contained in:
Andrew Dryga
2024-02-02 00:26:29 -06:00
committed by GitHub
parent d406f603f4
commit a5bd96901a
2 changed files with 3 additions and 1 deletions

View File

@@ -90,7 +90,9 @@ defmodule Domain.Auth.Adapters.GoogleWorkspace.APIClient do
Domain.Config.fetch_env!(:domain, __MODULE__)
|> Keyword.fetch!(:endpoint)
params = %{"includeDerivedMembership" => true}
uri = URI.parse("#{endpoint}/admin/directory/v1/groups/#{group_id}/members")
uri = URI.append_query(uri, URI.encode_query(params))
with {:ok, members} <- list_all(uri, api_token, "members") do
members =

View File

@@ -141,7 +141,7 @@ defmodule Domain.Auth.Adapters.GoogleWorkspace.APIClientTest do
end
assert_receive {:bypass_request, conn}
assert conn.params == %{}
assert conn.params == %{"includeDerivedMembership" => "true"}
assert Plug.Conn.get_req_header(conn, "authorization") == ["Bearer #{api_token}"]
end