| defmodule PlausibleWeb.AuthPlug do |
| @moduledoc """ |
| Plug for populating conn assigns with user data |
| on the basis of authenticated session token. |
| |
| Must be kept in sync with `PlausibleWeb.Live.AuthContext`. |
| """ |
|
|
| use Plausible |
| import Plug.Conn |
|
|
| alias PlausibleWeb.UserAuth |
|
|
| def init(options) do |
| options |
| end |
|
|
| def call(conn, _opts) do |
| case UserAuth.get_user_session(conn) do |
| {:ok, user_session} -> |
| user = user_session.user |
|
|
| current_team_id_from_session = Plug.Conn.get_session(conn, "current_team_id") |
|
|
| current_team_id = |
| conn.params["__team"] || current_team_id_from_session || user.last_team_identifier |
|
|
| {current_team, current_team_role} = |
| if current_team_id do |
| team_membership = |
| Enum.find(user.team_memberships, %{}, &(&1.team.identifier == current_team_id)) |
|
|
| {Map.get(team_membership, :team), Map.get(team_membership, :role)} |
| else |
| {nil, nil} |
| end |
|
|
| conn = |
| cond do |
| current_team && current_team_id != current_team_id_from_session -> |
| Plausible.Users.remember_last_team(user, current_team_id) |
| Plug.Conn.put_session(conn, "current_team_id", current_team_id) |
|
|
| is_nil(current_team) && not is_nil(current_team_id_from_session) -> |
| Plausible.Users.remember_last_team(user, nil) |
| Plug.Conn.delete_session(conn, "current_team_id") |
|
|
| true -> |
| conn |
| end |
|
|
| my_team = |
| user.team_memberships |
| |> Enum.find(%{}, &(&1.role == :owner and &1.team.setup_complete == false)) |
| |> Map.get(:team) |
|
|
| teams = |
| user.team_memberships |
| |> Enum.filter(& &1.team.setup_complete) |
| |> Enum.sort_by(fn tm -> [tm.role != :owner, tm.team_id] end) |
| |> Enum.map(&Map.fetch!(&1, :team)) |
|
|
| Plausible.OpenTelemetry.add_user_attributes(user) |
|
|
| Sentry.Context.set_user_context(%{id: user.id, name: user.name, email: user.email}) |
|
|
| on_ee do |
| Plausible.Audit.set_context(%{ |
| current_user: user, |
| current_team: current_team |
| }) |
| end |
|
|
| conn |
| |> assign(:current_user, user) |
| |> assign(:current_user_session, user_session) |
| |> assign(:my_team, my_team) |
| |> assign(:current_team, current_team || my_team) |
| |> assign(:current_team_role, current_team_role || (my_team && :owner)) |
| |> assign(:teams, teams) |
|
|
| {:error, :session_expired, user_session} -> |
| assign(conn, :expired_session, user_session) |
|
|
| _ -> |
| conn |
| end |
| end |
| end |
|
|