Add json wrapper
parent
0f88f579e0
commit
091f13d834
|
@ -44,7 +44,8 @@ config :farmbot, :behaviour,
|
|||
authorization: Farmbot.Bootstrap.Authorization,
|
||||
firmware_handler: Farmbot.Firmware.StubHandler,
|
||||
http_adapter: Farmbot.HTTP.HTTPoisonAdapter,
|
||||
gpio_handler: Farmbot.System.GPIO.StubHandler
|
||||
gpio_handler: Farmbot.System.GPIO.StubHandler,
|
||||
json_parser: Farmbot.JSON.JasonParser
|
||||
|
||||
config :farmbot, :farmware,
|
||||
first_part_farmware_manifest_url: "https://raw.githubusercontent.com/FarmBot-Labs/farmware_manifests/master/manifest.json"
|
||||
|
|
|
@ -9,3 +9,5 @@ lib/farmbot/system/gpio/gpio.ex
|
|||
lib/farmbot/asset/farm_event.ex
|
||||
lib/farmbot/asset/regimen.ex
|
||||
lib/farmbot/jwt.ex
|
||||
lib/farmbot/json/jason_parser.ex
|
||||
lib/farmbot/json/parser.ex
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
defmodule Farmbot.JSON.JasonParser do
|
||||
@moduledoc "Parser handler for Jason"
|
||||
@behaviour Farmbot.JSON.Parser
|
||||
|
||||
def decode(data), do: Jason.decode(data)
|
||||
def encode(data), do: Jason.encode(data)
|
||||
|
||||
require Protocol
|
||||
Protocol.derive(Jason.Encoder, Farmbot.Jwt)
|
||||
end
|
|
@ -0,0 +1,25 @@
|
|||
defmodule Farmbot.JSON do
|
||||
@moduledoc "Wraps a dependency for easy upgrade and no vendor lock."
|
||||
|
||||
@parser Application.get_env(:farmbot, :behaviour)[:json_parser]
|
||||
@parser || Mix.raise("Unconfigured JSON Parser.")
|
||||
@spec decode(iodata) :: {:ok, term} | {:error, term}
|
||||
def decode(iodata), do: @parser.decode(iodata)
|
||||
|
||||
@spec encode(term) :: {:ok, term} | {:error, term}
|
||||
def encode(data), do: @parser.encode(data)
|
||||
|
||||
def decode!(iodata) do
|
||||
case decode(iodata) do
|
||||
{:ok, results} -> results
|
||||
{:error, reason} -> raise(reason)
|
||||
end
|
||||
end
|
||||
|
||||
def encode!(data) do
|
||||
case encode(data) do
|
||||
{:ok, results} -> results
|
||||
{:error, reason} -> raise(reason)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
defmodule Farmbot.JSON.Parser do
|
||||
@moduledoc """
|
||||
Callback module for wrapping a json dependency.
|
||||
"""
|
||||
@callback decode(iodata) :: {:ok, term} | {:error, term}
|
||||
@callback encode(term) :: {:ok, iodata} | {:error, term}
|
||||
end
|
|
@ -29,11 +29,12 @@ defmodule Farmbot.Jwt do
|
|||
body = tkn |> String.split(".") |> Enum.at(1)
|
||||
|
||||
with {:ok, json} <- Base.decode64(body, padding: false),
|
||||
{:ok, jwt} <- Poison.decode(json, as: %__MODULE__{}) do
|
||||
{:ok, data} <- Farmbot.JSON.decode(json),
|
||||
{:ok, jwt} <- decode_map(data) do
|
||||
{:ok, jwt}
|
||||
else
|
||||
:error -> {:error, :base64_decode_fail}
|
||||
{:error, :invalid, _} -> {:error, :json_decode_error}
|
||||
:error -> {:error, "base64_decode_fail"}
|
||||
{:error, _resson} -> {:error, "json_decode_error"}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -45,4 +46,18 @@ defmodule Farmbot.Jwt do
|
|||
{:error, reason} -> raise(reason)
|
||||
end
|
||||
end
|
||||
|
||||
defp decode_map(%{} = map) do
|
||||
{:ok,
|
||||
struct(
|
||||
Farmbot.Jwt,
|
||||
bot: map["bot"],
|
||||
exp: map["exp"],
|
||||
iss: map["iss"],
|
||||
mqtt: map["mqtt"],
|
||||
os_update_server: map["os_update_server"],
|
||||
vhost: map["vhost"],
|
||||
interim_email: map["interim_email"]
|
||||
)}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,6 @@ defmodule Mix.Tasks.Farmbot.Firmware.Slack do
|
|||
use Mix.Task
|
||||
import Mix.Tasks.Farmbot.Env
|
||||
|
||||
@dialyzer {[:no_return], [run: 1]}
|
||||
def run(opts) do
|
||||
token = slack_token()
|
||||
|
||||
|
|
1
mix.exs
1
mix.exs
|
@ -102,6 +102,7 @@ defmodule Farmbot.Mixfile do
|
|||
{:gen_stage, "~> 0.12"},
|
||||
{:phoenix_html, "~> 2.10.5"},
|
||||
{:poison, "~> 3.1.0"},
|
||||
{:jason, "~> 1.0"},
|
||||
{:httpoison, "~> 1.1"},
|
||||
{:jsx, "~> 2.8.0"},
|
||||
{:timex, "~> 3.3"},
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"credo": {:hex, :credo, "0.9.1", "f021affa11b32a94dc2e807a6472ce0914289c9132f99644a97fc84432b202a1", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"decimal": {:hex, :decimal, "1.4.1", "ad9e501edf7322f122f7fc151cce7c2a0c9ada96f2b0155b8a09a795c2029770", [:mix], [], "hexpm"},
|
||||
"dialyxir": {:git, "https://github.com/jeremyjh/dialyxir.git", "292191fdb71a10827e7088d01d9ba16461e40369", []},
|
||||
"dialyxir": {:git, "https://github.com/jeremyjh/dialyxir.git", "fa821b418b5e7c54ca7a2f184d55b5310693457c", []},
|
||||
"distillery": {:hex, :distillery, "1.5.2", "eec18b2d37b55b0bcb670cf2bcf64228ed38ce8b046bb30a9b636a6f5a4c0080", [:mix], [], "hexpm"},
|
||||
"earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm"},
|
||||
"ecto": {:hex, :ecto, "2.2.8", "a4463c0928b970f2cee722cd29aaac154e866a15882c5737e0038bbfcf03ec2c", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
|
@ -32,6 +32,7 @@
|
|||
"httpoison": {:hex, :httpoison, "1.1.1", "96ed7ab79f78a31081bb523eefec205fd2900a02cda6dbc2300e7a1226219566", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"idna": {:hex, :idna, "5.1.1", "cbc3b2fa1645113267cc59c760bafa64b2ea0334635ef06dbac8801e42f7279c", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"joken": {:hex, :joken, "1.5.0", "42a0953e80bd933fc98a0874e156771f78bf0e92abe6c3a9c22feb6da28efb0b", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"jose": {:hex, :jose, "1.8.4", "7946d1e5c03a76ac9ef42a6e6a20001d35987afd68c2107bcd8f01a84e75aa73", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"},
|
||||
|
|
|
@ -30,7 +30,7 @@ defmodule Farmbot.JwtTest do
|
|||
tkn = [head, "not_a_valid_token", foot] |> Enum.join(".")
|
||||
r = Jwt.decode(tkn)
|
||||
refute match?({:ok, _}, r)
|
||||
assert r == :error
|
||||
assert r == {:error, "base64_decode_fail"}
|
||||
end
|
||||
|
||||
test "Gives Poison Error when it can't be decoded as json", %{token: tkn} do
|
||||
|
@ -39,14 +39,14 @@ defmodule Farmbot.JwtTest do
|
|||
tkn = [head, not_token, foot] |> Enum.join(".")
|
||||
r = Jwt.decode(tkn)
|
||||
refute match?({:ok, _}, r)
|
||||
assert r == {:error, {:invalid, "h", 0}}
|
||||
assert r == {:error, "json_decode_error"}
|
||||
end
|
||||
|
||||
test "raises on bad token because base64", %{token: tkn} do
|
||||
[head, _body, foot] = String.split(tkn, ".")
|
||||
tkn = [head, "not_a_valid_token", foot] |> Enum.join(".")
|
||||
|
||||
assert_raise RuntimeError, "Failed to base64 decode.", fn ->
|
||||
assert_raise RuntimeError, "base64_decode_fail", fn ->
|
||||
Jwt.decode!(tkn)
|
||||
end
|
||||
end
|
||||
|
@ -56,7 +56,7 @@ defmodule Farmbot.JwtTest do
|
|||
not_token = Base.encode64("hello world", padding: false)
|
||||
tkn = [head, not_token, foot] |> Enum.join(".")
|
||||
|
||||
assert_raise RuntimeError, "Failed to json decode.", fn ->
|
||||
assert_raise RuntimeError, "json_decode_error", fn ->
|
||||
Jwt.decode!(tkn)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue