Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions lib/realtime_web/channels/auth/channels_authorization.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ defmodule RealtimeWeb.ChannelsAuthorization do
require Logger
import Realtime.Logs

@doc """
Authorize connection to access channel
"""
@spec authorize(binary(), binary(), binary() | nil) :: {:ok, map()} | {:error, any()}
def authorize(token, jwt_secret, jwt_jwks) when is_binary(token) do
token
|> clean_token()
|> RealtimeWeb.JwtVerification.verify(jwt_secret, jwt_jwks)
end

def authorize(_token, _jwt_secret, _jwt_jwks), do: :error

defp clean_token(token) do
Regex.replace(~r/\s|\n/, URI.decode(token), "")
end
def authorize(_token, _jwt_secret, _jwt_jwks), do: {:error, :invalid_token}

def authorize_conn(token, jwt_secret, jwt_jwks) do
case authorize(token, jwt_secret, jwt_jwks) do
Expand All @@ -30,11 +30,10 @@ defmodule RealtimeWeb.ChannelsAuthorization do
end

{:error, reason} ->
log_error("ErrorAuthorizingWebsocket", reason)
{:error, reason}

error ->
log_error("ErrorAuthorizingWebsocket", error)
{:error, :unknown}
end
end

defp clean_token(token), do: Regex.replace(~r/\s|\n/, URI.decode(token), "")
end
4 changes: 4 additions & 0 deletions lib/realtime_web/channels/auth/jwt_verification.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ defmodule RealtimeWeb.JwtVerification do
@es_algorithms ["ES256", "ES384", "ES512"]
@ed_algorithms ["Ed25519", "Ed448"]

@doc """
Verify JWT token and validate claims
"""
@spec verify(binary(), binary(), binary() | nil) :: {:ok, map()} | {:error, any()}
def verify(token, jwt_secret, jwt_jwks) when is_binary(token) do
with {:ok, _claims} <- check_claims_format(token),
{:ok, header} <- check_header_format(token),
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Realtime.MixProject do
def project do
[
app: :realtime,
version: "2.33.82",
version: "2.33.83",
elixir: "~> 1.17.3",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
Expand Down
48 changes: 24 additions & 24 deletions test/realtime_web/channels/auth/channels_authorization_test.exs
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
defmodule RealtimeWeb.ChannelsAuthorizationTest do
use ExUnit.Case

import Mock
import Generators

alias RealtimeWeb.{ChannelsAuthorization, JwtVerification}

@secret ""

test "authorize/3 when token is authorized" do
input_token = "\n token %20 1 %20 2 %20 3 "
expected_token = "token123"

with_mock JwtVerification,
verify: fn token, @secret, _jwks ->
assert token == expected_token
{:ok, %{}}
end do
assert {:ok, %{}} = ChannelsAuthorization.authorize(input_token, @secret, nil)
describe "authorize_conn/3" do
test "when token is authorized" do
input_token = "\n token %20 1 %20 2 %20 3 "
expected_token = "token123"

with_mock JwtVerification,
verify: fn token, @secret, _jwks ->
assert token == expected_token
{:ok, %{}}
end do
assert {:ok, %{}} = ChannelsAuthorization.authorize(input_token, @secret, nil)
end
end
end

test "authorize/3 when token is unauthorized" do
with_mock JwtVerification, verify: fn _token, _secret, _jwks -> :error end do
assert :error = ChannelsAuthorization.authorize("bad_token", @secret, nil)
test "when token is unauthorized" do
with_mock JwtVerification, verify: fn _token, _secret, _jwks -> :error end do
assert :error = ChannelsAuthorization.authorize("bad_token", @secret, nil)
end
end
end

test "authorize/3 when token is not a string" do
assert :error = ChannelsAuthorization.authorize([], @secret, nil)
end
test "when token is not a string" do
assert {:error, :invalid_token} = ChannelsAuthorization.authorize([], @secret, nil)
end

test "authorize_conn/3 fails when has missing headers" do
jwt = generate_jwt_token(@secret, %{})
test "authorize_conn/3 fails when has missing headers" do
jwt = generate_jwt_token(@secret, %{})

assert {:error, :missing_claims} =
ChannelsAuthorization.authorize_conn(jwt, @secret, nil)
assert {:error, :missing_claims} =
ChannelsAuthorization.authorize_conn(jwt, @secret, nil)
end
end
end
Loading
Loading