Packages
livebook
0.11.3
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
alias Livebook.Users.User
@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
{module, _} = Livebook.Config.identity_provider()
{conn, identity_data} =
module.authenticate(LivebookWeb.ZTA, conn, fields: [:id, :name, :email])
if identity_data do
put_session(conn, :identity_data, identity_data)
else
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
identity_data = get_session(conn, :identity_data)
user_data = User.new() |> user_data() |> Map.merge(identity_data)
encoded = user_data |> 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
defp user_data(user) do
user
|> Map.from_struct()
|> Map.delete(:id)
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