Testing with JOSE (PS256 signing not working)
This commit is contained in:
parent
1abcfbc9f6
commit
3fd3f2c444
6
config/config.exs.example
Executable file
6
config/config.exs.example
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
# use Mix.Config
|
||||||
|
|
||||||
|
# config :yandex_translate,
|
||||||
|
# service_account_id: "SERVICE_ACCOUNT_ID"
|
||||||
|
# authorized_key_id: "AUTHORIZED_KEY_ID"
|
||||||
|
# private_key: "PRIVATE_KEY"
|
@ -1,2 +1,41 @@
|
|||||||
defmodule YandexTranslate do
|
defmodule YandexTranslate do
|
||||||
|
@iam_token_url "https://iam.api.cloud.yandex.net/iam/v1/tokens"
|
||||||
|
|
||||||
|
def get_key(type, key \\ Application.get_env(:yandex_translate, :private_key))
|
||||||
|
|
||||||
|
def get_key(:public, key),
|
||||||
|
do: get_key(:private, key) |> JOSE.JWK.to_public()
|
||||||
|
|
||||||
|
def get_key(:private, key),
|
||||||
|
do: fetch_key(key)
|
||||||
|
|
||||||
|
defp fetch_key("-----BEGIN" <> _ = key_content), do: JOSE.JWK.from_pem(key_content)
|
||||||
|
|
||||||
|
defp fetch_key(key_file), do: JOSE.JWK.from_pem_file(key_file)
|
||||||
|
|
||||||
|
def get_iam_token(),
|
||||||
|
do: Application.get_all_env(:yandex_translate) |> Map.new() |> get_iam_token()
|
||||||
|
|
||||||
|
def get_iam_token(%{service_account_id: iss, private_key: private_key, authorized_key_id: kid}) do
|
||||||
|
now = DateTime.utc_now() |> DateTime.to_unix()
|
||||||
|
jwk = get_key(:private, private_key) |> JOSE.JWK.merge(%{"kid" => kid})
|
||||||
|
|
||||||
|
# JSON Web Signature (JWS)
|
||||||
|
jws = %{
|
||||||
|
"alg" => "RS256",
|
||||||
|
"typ" => "JWT",
|
||||||
|
"kid" => kid
|
||||||
|
}
|
||||||
|
|
||||||
|
# JSON Web Token (JWT)
|
||||||
|
jwt =
|
||||||
|
JOSE.JWT.from(%{
|
||||||
|
"iss" => iss,
|
||||||
|
"exp" => now + 60 * 60,
|
||||||
|
"iat" => now,
|
||||||
|
"aud" => @iam_token_url
|
||||||
|
})
|
||||||
|
|
||||||
|
_signed = JOSE.JWT.sign(jwk, jws, jwt) |> JOSE.JWS.compact() |> elem(1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
15
lib/yandex_translate/token.ex
Normal file
15
lib/yandex_translate/token.ex
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# defmodule YandexTranslate.Token do
|
||||||
|
# @iam_token_url "https://iam.api.cloud.yandex.net/iam/v1/tokens"
|
||||||
|
|
||||||
|
# use Joken.Config
|
||||||
|
|
||||||
|
# @impl Joken.Config
|
||||||
|
# def token_config() do
|
||||||
|
# default_claims(
|
||||||
|
# iss: Application.get_env(:yandex_translate, :service_account_id),
|
||||||
|
# default_exp: 60 * 60,
|
||||||
|
# skip: [:jti, :nbf],
|
||||||
|
# aud: @iam_token_url
|
||||||
|
# )
|
||||||
|
# end
|
||||||
|
# end
|
14
mix.exs
14
mix.exs
@ -20,17 +20,21 @@ defmodule YandexTranslate.Mixfile do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def application do
|
def application do
|
||||||
[
|
[extra_applications: applications(Mix.env())]
|
||||||
extra_applications: [:logger]
|
|
||||||
]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp applications(:dev), do: applications(:all) ++ [:remix]
|
||||||
|
defp applications(_all), do: [:logger, :jose]
|
||||||
|
|
||||||
defp deps do
|
defp deps do
|
||||||
[
|
[
|
||||||
{:joken, "~> 2.1.0"},
|
# {:joken, "~> 2.1.0"},
|
||||||
|
# {:jose, "~> 1.9.0"},
|
||||||
|
{:jose, github: "potatosalad/erlang-jose", branch: "master"},
|
||||||
{:jason, "~> 1.1.2"},
|
{:jason, "~> 1.1.2"},
|
||||||
{:mojito, "~> 0.3.0"},
|
{:mojito, "~> 0.3.0"},
|
||||||
{:ex_doc, "~> 0.20.2", only: :dev}
|
{:ex_doc, "~> 0.20.2", only: :dev},
|
||||||
|
{:remix, "~> 0.0.2", only: :dev}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
4
mix.lock
4
mix.lock
@ -9,7 +9,7 @@
|
|||||||
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"joken": {:hex, :joken, "2.1.0", "bf21a73105d82649f617c5e59a7f8919aa47013d2519ebcc39d998d8d12adda9", [:mix], [{:jose, "~> 1.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm"},
|
"joken": {:hex, :joken, "2.1.0", "bf21a73105d82649f617c5e59a7f8919aa47013d2519ebcc39d998d8d12adda9", [:mix], [{:jose, "~> 1.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"jose": {:hex, :jose, "1.9.0", "4167c5f6d06ffaebffd15cdb8da61a108445ef5e85ab8f5a7ad926fdf3ada154", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"},
|
"jose": {:git, "https://github.com/potatosalad/erlang-jose.git", "80551fc36abab81b6fac798e112a9c1a644b60f1", [branch: "master"]},
|
||||||
"makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
|
"makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
|
"makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
||||||
@ -17,9 +17,11 @@
|
|||||||
"mint": {:hex, :mint, "0.2.1", "a2ec8729fcad5c8b6460e07dfa64b008b3d9697a9f4604cd5684a87b44677c99", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm"},
|
"mint": {:hex, :mint, "0.2.1", "a2ec8729fcad5c8b6460e07dfa64b008b3d9697a9f4604cd5684a87b44677c99", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"mojito": {:hex, :mojito, "0.3.0", "806cd3c1832333a9ee784e7ea2799863fbe4de55ecb4623a8f4ef870c2844cc6", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 0.2.1", [hex: :mint, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm"},
|
"mojito": {:hex, :mojito, "0.3.0", "806cd3c1832333a9ee784e7ea2799863fbe4de55ecb4623a8f4ef870c2844cc6", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 0.2.1", [hex: :mint, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"},
|
"nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"},
|
||||||
|
"ojson": {:hex, :ojson, "1.0.0", "fd28614eadaec00a15cdb2f53f29d8717a812a508ddb80d202f2f2e2aaeabbcc", [:mix, :rebar3], [], "hexpm"},
|
||||||
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
|
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
|
||||||
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
|
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
|
||||||
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm"},
|
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm"},
|
||||||
|
"remix": {:hex, :remix, "0.0.2", "f06115659d8ede8d725fae1708920ef73353a1b39efe6a232d2a38b1f2902109", [:mix], [], "hexpm"},
|
||||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
|
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
|
||||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
|
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
|
||||||
}
|
}
|
||||||
|
128
test/yandex_translate_test.exs
Executable file
128
test/yandex_translate_test.exs
Executable file
@ -0,0 +1,128 @@
|
|||||||
|
# defmodule YandexTranslatorTest do
|
||||||
|
# use ExUnit.Case
|
||||||
|
|
||||||
|
# setup_all do
|
||||||
|
# {:ok, %{"iamToken" => iam_token}} = YandexTranslator.get_iam_token
|
||||||
|
# {:ok, iam_token: iam_token}
|
||||||
|
# end
|
||||||
|
|
||||||
|
# describe "cloud api" do
|
||||||
|
# test "request for getting languages with invalid key" do
|
||||||
|
# {:error, %{"error_message" => error_message}} = YandexTranslator.langs([iam_token: "1"])
|
||||||
|
|
||||||
|
# assert error_message == "rpc error: code = Unauthenticated desc = invalid auth data"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for detecting language with invalid key" do
|
||||||
|
# {:error, %{"error_message" => error_message}} = YandexTranslator.detect([iam_token: "1", text: "Hello"])
|
||||||
|
|
||||||
|
# assert error_message == "rpc error: code = Unauthenticated desc = invalid auth data"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for translating text with invalid key" do
|
||||||
|
# {:error, %{"error_message" => error_message}} = YandexTranslator.translate([iam_token: "1", text: "Hello", lang: "ru"])
|
||||||
|
|
||||||
|
# assert error_message == "rpc error: code = Unauthenticated desc = invalid auth data"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for getting languages", state do
|
||||||
|
# {:ok, %{"languages" => languages}} = YandexTranslator.langs([iam_token: state[:iam_token]])
|
||||||
|
|
||||||
|
# assert is_list(languages) == true
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for detecting language", state do
|
||||||
|
# {:ok, %{"language" => language}} = YandexTranslator.detect([iam_token: state[:iam_token], text: "Hello"])
|
||||||
|
|
||||||
|
# assert language == "en"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for translating text", state do
|
||||||
|
# {:ok, %{"translations" => [%{"text" => text}]}} = YandexTranslator.translate([iam_token: state[:iam_token], text: "Hello", target: "es"])
|
||||||
|
|
||||||
|
# assert text == "Saludar"
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
# describe "old api, invalid requests" do
|
||||||
|
# test "request for getting languages with invalid key" do
|
||||||
|
# {:error, %{"code" => code, "message" => message}} = YandexTranslator.langs([key: "", format: "json"])
|
||||||
|
|
||||||
|
# assert code == 401
|
||||||
|
# assert message == "API key is invalid"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for getting languages with invalid key, xml format" do
|
||||||
|
# {:error, body} = YandexTranslator.langs([key: ""])
|
||||||
|
|
||||||
|
# assert String.length(body) != 0
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for detecting language with invalid key" do
|
||||||
|
# {:error, %{"code" => code, "message" => message}} = YandexTranslator.detect([key: "", text: "Hello", format: "json"])
|
||||||
|
|
||||||
|
# assert code == 401
|
||||||
|
# assert message == "API key is invalid"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for detecting language with invalid key, xml format" do
|
||||||
|
# {:error, body} = YandexTranslator.detect([key: "", text: "Hello"])
|
||||||
|
|
||||||
|
# assert String.length(body) != 0
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for translating text with invalid key" do
|
||||||
|
# {:error, %{"code" => code, "message" => message}} = YandexTranslator.translate([key: "", text: "Hello", lang: "ru", format: "json"])
|
||||||
|
|
||||||
|
# assert code == 401
|
||||||
|
# assert message == "API key is invalid"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for translating text with invalid key, xml format" do
|
||||||
|
# {:error, body} = YandexTranslator.translate([key: "", text: "Hello", lang: "ru"])
|
||||||
|
|
||||||
|
# assert String.length(body) != 0
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
# describe "old api, valid requests" do
|
||||||
|
# test "request for getting languages" do
|
||||||
|
# {:ok, %{"dirs" => dirs}} = YandexTranslator.langs([format: "json"])
|
||||||
|
|
||||||
|
# assert is_list(dirs) == true
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for getting languages, xml format" do
|
||||||
|
# {:ok, body} = YandexTranslator.langs
|
||||||
|
|
||||||
|
# assert String.length(body) != 0
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for detecting language" do
|
||||||
|
# {:ok, %{"code" => code, "lang" => lang}} = YandexTranslator.detect([text: "Hello", format: "json"])
|
||||||
|
|
||||||
|
# assert code == 200
|
||||||
|
# assert lang == "en"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for detecting language, xml format" do
|
||||||
|
# {:ok, body} = YandexTranslator.detect([text: "Hello"])
|
||||||
|
|
||||||
|
# assert String.length(body) != 0
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for translating text" do
|
||||||
|
# {:ok, %{"code" => code, "lang" => lang, "text" => text}} = YandexTranslator.translate([text: "Hello", lang: "ru", format: "json"])
|
||||||
|
|
||||||
|
# assert code == 200
|
||||||
|
# assert lang == "en-ru"
|
||||||
|
# assert text == ["Привет"]
|
||||||
|
# end
|
||||||
|
|
||||||
|
# test "request for translating text, xml format" do
|
||||||
|
# {:ok, body} = YandexTranslator.translate([text: "Hello", lang: "ru"])
|
||||||
|
|
||||||
|
# assert String.length(body) != 0
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
Loading…
x
Reference in New Issue
Block a user