-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pull out channel valid_token? (#441)
- Loading branch information
Showing
6 changed files
with
156 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
defmodule SkateWeb.ChannelAuth do | ||
alias SkateWeb.AuthManager | ||
|
||
@doc """ | ||
Checks wether a socket has a valid token. | ||
Attempts to refresh the token. | ||
Only returns false if all refreshing fails, | ||
and the user needs to log in again. | ||
""" | ||
@spec valid_token?(Phoenix.Socket.t()) :: boolean() | ||
def valid_token?(socket) do | ||
token = Guardian.Phoenix.Socket.current_token(socket) | ||
|
||
case AuthManager.decode_and_verify(token) do | ||
{:ok, _claims} -> | ||
# Refresh a token before it expires | ||
case AuthManager.refresh(token) do | ||
{:ok, _old_claims, {_new_token, _new_claims}} -> | ||
true | ||
|
||
{:error, :token_expired} -> | ||
valid_token_after_refresh?(socket) | ||
end | ||
|
||
{:error, :token_expired} -> | ||
valid_token_after_refresh?(socket) | ||
|
||
_ -> | ||
false | ||
end | ||
end | ||
|
||
@spec valid_token_after_refresh?(Phoenix.Socket.t()) :: boolean() | ||
defp valid_token_after_refresh?(socket) do | ||
refresh_token_store = Application.get_env(:skate, :refresh_token_store) | ||
|
||
refresh_token = | ||
socket | ||
|> Guardian.Phoenix.Socket.current_resource() | ||
|> refresh_token_store.get_refresh_token() | ||
|
||
# Exchange a token of type "refresh" for a new token of type "access" | ||
case AuthManager.exchange(refresh_token, "refresh", "access") do | ||
{:ok, _old_stuff, {_new_token, _new_claims}} -> | ||
true | ||
|
||
_ -> | ||
false | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ defmodule SkateWeb.VehiclesChannelTest do | |
|
||
alias Phoenix.Socket | ||
alias Realtime.Vehicle | ||
alias SkateWeb.{AuthManager, UserSocket, VehiclesChannel} | ||
alias SkateWeb.{UserSocket, VehiclesChannel} | ||
|
||
@vehicle %Vehicle{ | ||
id: "y0507", | ||
|
@@ -41,8 +41,7 @@ defmodule SkateWeb.VehiclesChannelTest do | |
} | ||
|
||
setup do | ||
reassign_env(:realtime, :trip_fn, fn _trip_id -> nil end) | ||
reassign_env(:realtime, :block_fn, fn _block_id, _service_id -> nil end) | ||
reassign_env(:skate, :valid_token_fn, fn _socket -> true end) | ||
|
||
socket = socket(UserSocket, "", %{guardian_default_resource: "test_uid"}) | ||
|
||
|
@@ -95,30 +94,18 @@ defmodule SkateWeb.VehiclesChannelTest do | |
|
||
describe "handle_info/2" do | ||
setup do | ||
reassign_env( | ||
:skate, | ||
:refresh_token_store, | ||
SkateWeb.VehiclesChannelTest.FakeRefreshTokenStore | ||
) | ||
|
||
ets = GenServer.call(Realtime.Server.default_name(), :ets) | ||
|
||
{:ok, ets: ets} | ||
end | ||
|
||
test "pushes new vehicle data onto the socket when socket is authenticated", %{ | ||
test "pushes new vehicle data onto the socket", %{ | ||
socket: socket, | ||
ets: ets | ||
} do | ||
assert Realtime.Server.update({%{"1" => [@vehicle]}, []}) == :ok | ||
|
||
{:ok, token, claims} = | ||
AuthManager.encode_and_sign("[email protected]", %{ | ||
"exp" => System.system_time(:second) + 500 | ||
}) | ||
|
||
{:ok, _, socket} = subscribe_and_join(socket, VehiclesChannel, "vehicles:route:1") | ||
socket = Guardian.Phoenix.Socket.assign_rtc(socket, "[email protected]", token, claims) | ||
|
||
assert {:noreply, socket} = | ||
VehiclesChannel.handle_info( | ||
|
@@ -130,19 +117,13 @@ defmodule SkateWeb.VehiclesChannelTest do | |
assert_push("vehicles", %{data: [^vehicle]}) | ||
end | ||
|
||
test "pushes new shuttle data onto the socket when socket is authenticated", %{ | ||
test "pushes new shuttle data onto the socket", %{ | ||
socket: socket, | ||
ets: ets | ||
} do | ||
assert Realtime.Server.update({%{}, [@vehicle]}) == :ok | ||
|
||
{:ok, token, claims} = | ||
AuthManager.encode_and_sign("[email protected]", %{ | ||
"exp" => System.system_time(:second) + 500 | ||
}) | ||
|
||
{:ok, _, socket} = subscribe_and_join(socket, VehiclesChannel, "vehicles:shuttle:all") | ||
socket = Guardian.Phoenix.Socket.assign_rtc(socket, "[email protected]", token, claims) | ||
|
||
assert {:noreply, socket} = | ||
VehiclesChannel.handle_info( | ||
|
@@ -154,19 +135,13 @@ defmodule SkateWeb.VehiclesChannelTest do | |
assert_push("shuttles", %{data: [^vehicle]}) | ||
end | ||
|
||
test "pushes new search results data onto the socket when socket is authenticated", %{ | ||
test "pushes new search results data onto the socket", %{ | ||
socket: socket, | ||
ets: ets | ||
} do | ||
assert Realtime.Server.update({%{}, [@vehicle]}) == :ok | ||
|
||
{:ok, token, claims} = | ||
AuthManager.encode_and_sign("[email protected]", %{ | ||
"exp" => System.system_time(:second) + 500 | ||
}) | ||
|
||
{:ok, _, socket} = subscribe_and_join(socket, VehiclesChannel, "vehicles:search:all:507") | ||
socket = Guardian.Phoenix.Socket.assign_rtc(socket, "[email protected]", token, claims) | ||
|
||
assert {:noreply, socket} = | ||
VehiclesChannel.handle_info( | ||
|
@@ -178,45 +153,15 @@ defmodule SkateWeb.VehiclesChannelTest do | |
assert_push("search", %{data: [^vehicle]}) | ||
end | ||
|
||
test "refresh the authentication using the refresh token if we have one", %{ | ||
socket: socket, | ||
ets: ets | ||
} do | ||
assert Realtime.Server.update({%{"1" => [@vehicle]}, []}) | ||
|
||
{:ok, token, claims} = | ||
AuthManager.encode_and_sign("[email protected]", %{ | ||
"exp" => System.system_time(:second) - 100 | ||
}) | ||
|
||
{:ok, _, socket} = subscribe_and_join(socket, VehiclesChannel, "vehicles:route:1") | ||
|
||
socket = Guardian.Phoenix.Socket.assign_rtc(socket, "[email protected]", token, claims) | ||
|
||
assert {:noreply, socket} = | ||
VehiclesChannel.handle_info( | ||
{:new_realtime_data, {ets, {:route_id, "1"}}}, | ||
socket | ||
) | ||
|
||
vehicle = @vehicle | ||
assert_push("vehicles", %{data: [^vehicle]}) | ||
end | ||
|
||
test "rejects sending vehicle data when socket is not authenticated", %{ | ||
socket: socket, | ||
ets: ets | ||
} do | ||
{:ok, token, claims} = | ||
AuthManager.encode_and_sign("[email protected]", %{ | ||
"exp" => System.system_time(:second) - 100 | ||
}) | ||
assert Realtime.Server.update({%{}, [@vehicle]}) == :ok | ||
reassign_env(:skate, :valid_token_fn, fn _socket -> false end) | ||
|
||
{:ok, _, socket} = subscribe_and_join(socket, VehiclesChannel, "vehicles:route:1") | ||
|
||
socket = | ||
Guardian.Phoenix.Socket.assign_rtc(socket, "[email protected]", token, claims) | ||
|
||
{:stop, :normal, _socket} = | ||
VehiclesChannel.handle_info( | ||
{:new_realtime_data, {ets, {:route_id, "1"}}}, | ||
|
@@ -226,21 +171,4 @@ defmodule SkateWeb.VehiclesChannelTest do | |
assert_push("auth_expired", _) | ||
end | ||
end | ||
|
||
defmodule FakeRefreshTokenStore do | ||
def get_refresh_token("[email protected]") do | ||
{:ok, token, _claims} = | ||
AuthManager.encode_and_sign( | ||
"[email protected]", | ||
%{ | ||
"exp" => System.system_time(:second) + 500 | ||
}, | ||
token_type: "refresh" | ||
) | ||
|
||
token | ||
end | ||
|
||
def get_refresh_token(_), do: nil | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.