Packages
livebook
0.13.2
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_web/plugs/user_plug.ex
defmodule LivebookWeb.UserPlug do
# Initializes the session and cookies with user-related info.
#
# The first time someone visits Livebook
# this plug stores a new random user id or the ZTA user
# in the session under `:identity_data`.
#
# Additionally the cookies are checked for the presence
# of `"user_data"` and if there is none, a new user
# attributes are stored there. This makes sure
# the client-side can always access some `"user_data"`
# for `connect_params` of the socket connection.
@behaviour Plug
import Plug.Conn
import Phoenix.Controller
@impl true
def init(opts), do: opts
@impl true
def call(conn, _opts) do
conn
|> ensure_user_identity()
|> ensure_user_data()
|> mirror_user_data_in_session()
end
defp ensure_user_identity(conn) do
{_type, module, _key} = Livebook.Config.identity_provider()
{conn, identity_data} = module.authenticate(LivebookWeb.ZTA, conn, [])
cond do
identity_data ->
# Ensure we have a unique ID to identify this user/session.
id =
identity_data[:id] || get_session(conn, :identity_data)[:id] ||
Livebook.Utils.random_long_id()
put_session(conn, :identity_data, Map.put(identity_data, :id, id))
conn.halted ->
conn
true ->
conn
|> put_status(:forbidden)
|> put_view(LivebookWeb.ErrorHTML)
|> render("403.html", %{status: 403})
|> halt()
end
end
defp ensure_user_data(conn) when conn.halted, do: conn
defp ensure_user_data(conn) do
if Map.has_key?(conn.req_cookies, "lb_user_data") do
conn
else
encoded =
%{"name" => nil, "hex_color" => Livebook.EctoTypes.HexColor.random()}
|> Jason.encode!()
|> Base.encode64()
# We disable HttpOnly, so that it can be accessed on the client
# and set expiration to 5 years
opts = [http_only: false, max_age: 157_680_000] ++ LivebookWeb.Endpoint.cookie_options()
put_resp_cookie(conn, "lb_user_data", encoded, opts)
end
end
# Copies user_data from cookie to session, so that it's
# accessible to LiveViews
defp mirror_user_data_in_session(conn) when conn.halted, do: conn
defp mirror_user_data_in_session(conn) do
user_data = conn.cookies["lb_user_data"] |> Base.decode64!() |> Jason.decode!()
put_session(conn, :user_data, user_data)
end
end