Skip to content

Commit

Permalink
Add Domain Verification API (#55)
Browse files Browse the repository at this point in the history
* Remove legacy `WorkOS.API`

* Add `OrganizationDomain` struct

* Add Domain Verification API methods

* Add domain verification API methods
  • Loading branch information
LauraBeatris committed Dec 4, 2023
1 parent 179e599 commit aca8fea
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 99 deletions.
99 changes: 0 additions & 99 deletions lib/workos/api.ex

This file was deleted.

1 change: 1 addition & 0 deletions lib/workos/client/tesla_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule WorkOS.Client.TeslaClient do
@moduledoc """
Tesla client for WorkOS. This is the default HTTP client used.
"""

@behaviour WorkOS.Client

@doc """
Expand Down
62 changes: 62 additions & 0 deletions lib/workos/domain_verification.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
defmodule WorkOS.DomainVerification do
@moduledoc """
Manage Domain Verification in WorkOS.
@see https://workos.com/docs/reference/domain-verification
"""

alias WorkOS.DomainVerification.OrganizationDomain

@doc """
Gets an organization domain given an ID.
"""
@spec get_organization_domain(String.t()) :: WorkOS.Client.response(OrganizationDomain.t())
@spec get_organization_domain(WorkOS.Client.t(), String.t()) ::
WorkOS.Client.response(OrganizationDomain.t())
def get_organization_domain(client \\ WorkOS.client(), organization_domain_id) do
WorkOS.Client.get(client, OrganizationDomain, "/organization_domains/:id",
opts: [
path_params: [id: organization_domain_id]
]
)
end

@doc """
Creates an organization domain.
Parameter options:
* `:organization_id` - ID of the parent Organization. (required)
* `:domain` - Domain for the Organization Domain. (required)
"""
@spec create_organization_domain(map()) :: WorkOS.Client.response(OrganizationDomain.t())
@spec create_organization_domain(WorkOS.Client.t(), map()) ::
WorkOS.Client.response(OrganizationDomain.t())
def create_organization_domain(client \\ WorkOS.client(), opts)
when is_map_key(opts, :organization_id) and is_map_key(opts, :domain) do
WorkOS.Client.post(
client,
OrganizationDomain,
"/organization_domains",
%{
organization_id: opts[:organization_id],
domain: opts[:domain]
}
)
end

@doc """
Verifies an organization domain
"""
@spec verify_organization_domain(String.t()) :: WorkOS.Client.response(OrganizationDomain.t())
@spec verify_organization_domain(WorkOS.Client.t(), String.t()) ::
WorkOS.Client.response(OrganizationDomain.t())
def verify_organization_domain(client \\ WorkOS.client(), organization_domain_id) do
WorkOS.Client.post(client, OrganizationDomain, "/organization_domains/:id/verify", %{},
opts: [
path_params: [id: organization_domain_id]
]
)
end
end
45 changes: 45 additions & 0 deletions lib/workos/domain_verification/organization_domain.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
defmodule WorkOS.DomainVerification.OrganizationDomain do
@moduledoc """
WorkOS Organization Domain struct.
"""

@behaviour WorkOS.Castable

@type t() :: %__MODULE__{
id: String.t(),
organization_id: String.t(),
domain: String.t(),
state: String.t(),
verification_strategy: String.t(),
verification_token: String.t()
}

@enforce_keys [
:id,
:organization_id,
:domain,
:state,
:verification_strategy,
:verification_token
]
defstruct [
:id,
:organization_id,
:domain,
:state,
:verification_strategy,
:verification_token
]

@impl true
def cast(map) do
%__MODULE__{
id: map["id"],
organization_id: map["organization_id"],
domain: map["domain"],
state: map["state"],
verification_strategy: map["verification_strategy"],
verification_token: map["verification_token"]
}
end
end
2 changes: 2 additions & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ defmodule WorkOS.MixProject do
"Core API": [
WorkOS.AuditLogs,
WorkOS.DirectorySync,
WorkOS.DomainVerification,
WorkOS.Events,
WorkOS.Organizations,
WorkOS.Passwordless,
Expand All @@ -98,6 +99,7 @@ defmodule WorkOS.MixProject do
WorkOS.DirectorySync.Directory,
WorkOS.DirectorySync.Directory.Group,
WorkOS.DirectorySync.Directory.User,
WorkOS.DomainVerification.OrganizationDomain,
WorkOS.Events.Event,
WorkOS.Organizations.Organization,
WorkOS.Organizations.Organization.Domain,
Expand Down
80 changes: 80 additions & 0 deletions test/support/domain_verification_client_mock.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
defmodule WorkOS.DomainVerification.ClientMock do
@moduledoc false

use ExUnit.Case

@organization_domain_mock %{
"object" => "organization_domain",
"id" => "org_domain_01HCZRAP3TPQ0X0DKJHR32TATG",
"domain" => "workos.com",
"state" => "verified",
"verification_token" => nil,
"verification_strategy" => "manual"
}

def get_organization_domain(context, opts \\ []) do
Tesla.Mock.mock(fn request ->
%{api_key: api_key} = context

organization_domain_id =
opts |> Keyword.get(:assert_fields) |> Keyword.get(:organization_domain_id)

assert request.method == :get
assert request.url == "#{WorkOS.base_url()}/organization_domains/#{organization_domain_id}"

assert Enum.find(request.headers, &(elem(&1, 0) == "Authorization")) ==
{"Authorization", "Bearer #{api_key}"}

success_body = @organization_domain_mock

{status, body} = Keyword.get(opts, :respond_with, {200, success_body})
%Tesla.Env{status: status, body: body}
end)
end

def create_organization_domain(context, opts \\ []) do
Tesla.Mock.mock(fn request ->
%{api_key: api_key} = context

assert request.method == :post
assert request.url == "#{WorkOS.base_url()}/organization_domains"

assert Enum.find(request.headers, &(elem(&1, 0) == "Authorization")) ==
{"Authorization", "Bearer #{api_key}"}

body = Jason.decode!(request.body)

for {field, value} <-
Keyword.get(opts, :assert_fields, []) do
assert body[to_string(field)] == value
end

success_body = @organization_domain_mock

{status, body} = Keyword.get(opts, :respond_with, {200, success_body})
%Tesla.Env{status: status, body: body}
end)
end

def verify_organization_domain(context, opts \\ []) do
Tesla.Mock.mock(fn request ->
%{api_key: api_key} = context

organization_domain_id =
opts |> Keyword.get(:assert_fields) |> Keyword.get(:organization_domain_id)

assert request.method == :post

assert request.url ==
"#{WorkOS.base_url()}/organization_domains/#{organization_domain_id}/verify"

assert Enum.find(request.headers, &(elem(&1, 0) == "Authorization")) ==
{"Authorization", "Bearer #{api_key}"}

success_body = @organization_domain_mock

{status, body} = Keyword.get(opts, :respond_with, {200, success_body})
%Tesla.Env{status: status, body: body}
end)
end
end
52 changes: 52 additions & 0 deletions test/workos/domain_verification_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule WorkOS.DomainVerificationTest do
use WorkOS.TestCase

alias WorkOS.DomainVerification.ClientMock

setup :setup_env

describe "get_organization_domain" do
test "requests an organization domain", context do
opts = [organization_domain_id: "org_domain_01HCZRAP3TPQ0X0DKJHR32TATG"]

context |> ClientMock.get_organization_domain(assert_fields: opts)

assert {:ok, %WorkOS.DomainVerification.OrganizationDomain{id: id}} =
WorkOS.DomainVerification.get_organization_domain(
opts
|> Keyword.get(:organization_domain_id)
)

refute is_nil(id)
end
end

describe "create_organization_domain" do
test "with a valid payload, creates an organization domain", context do
opts = [organization_id: "org_01HCZRAP3TPQ0X0DKJHR32TATG", domain: "workos.com"]

context |> ClientMock.create_organization_domain(assert_fields: opts)

assert {:ok, %WorkOS.DomainVerification.OrganizationDomain{id: id}} =
WorkOS.DomainVerification.create_organization_domain(opts |> Enum.into(%{}))

refute is_nil(id)
end
end

describe "verify_organization_domain" do
test "verifies an organization domain", context do
opts = [organization_domain_id: "org_domain_01HCZRAP3TPQ0X0DKJHR32TATG"]

context |> ClientMock.verify_organization_domain(assert_fields: opts)

assert {:ok, %WorkOS.DomainVerification.OrganizationDomain{id: id}} =
WorkOS.DomainVerification.verify_organization_domain(
opts
|> Keyword.get(:organization_domain_id)
)

refute is_nil(id)
end
end
end

0 comments on commit aca8fea

Please sign in to comment.