frenzy/lib/frenzy_web/controllers/account_controller.ex

158 lines
4.4 KiB
Elixir

defmodule FrenzyWeb.AccountController do
use FrenzyWeb, :controller
alias Frenzy.{Repo, User, FervorClient}
alias FrenzyWeb.Endpoint
def show(conn, _params) do
user = conn.assigns[:user] |> Repo.preload(:approved_clients)
clients =
user.approved_clients
|> Enum.map(fn approved_client ->
fervor_client = Repo.get_by(FervorClient, client_id: approved_client.client_id)
{approved_client, fervor_client}
end)
render(conn, "show.html", %{
user: user,
clients: clients,
can_link_oidc: Frenzy.oidc_enabled?() && user.oidc_subject in [nil, ""]
})
end
def change_password(conn, _params) do
render(conn, "change_password.html")
end
def do_change_password(conn, %{
"old_password" => old,
"new_password" => new,
"confirm_new_password" => confirm
}) do
user = conn.assigns[:user] |> Repo.preload([:approved_clients, :groups])
case Bcrypt.check_pass(user, old) do
{:ok, user} ->
case new do
^old ->
conn
|> put_flash(:error, "New password cannot be the same as old password.")
|> redirect(to: Routes.account_path(Endpoint, :change_password))
^confirm ->
changeset = User.change_password_changeset(user, %{password: new})
{:ok, _user} = Repo.update(changeset)
conn
|> put_flash(:info, "Password changed.")
|> redirect(to: Routes.account_path(Endpoint, :show))
_ ->
conn
|> put_flash(:error, "New password and confirmation did not match.")
|> redirect(to: Routes.account_path(Endpoint, :change_password))
end
{:error, _reason} ->
conn
|> put_flash(:error, "Invalid old password.")
|> redirect(to: Routes.account_path(Endpoint, :change_password))
end
end
def do_change_password(conn, _params) do
redirect(conn, to: Routes.account_path(Endpoint, :change_password))
end
def change_fever_password(conn, _params) do
render(conn, "change_fever_password.html")
end
def do_change_fever_password(conn, %{
"new_password" => new
}) do
user = conn.assigns[:user] |> Repo.preload([:approved_clients, :groups])
changeset =
User.change_fever_password_changeset(user, %{
username: user.username,
fever_password: new
})
{:ok, _user} = Repo.update(changeset)
conn
|> put_flash(:info, "Fever password changed.")
|> redirect(to: Routes.account_path(Endpoint, :show))
end
def do_change_fever_password(conn, _params) do
redirect(conn, to: Routes.account_path(Endpoint, :change_fever_password))
end
def remove_client(conn, %{"client_id" => client_id}) do
user = conn.assigns[:user] |> Repo.preload(:approved_clients)
approved_client = Enum.find(user.approved_clients, fn c -> c.client_id == client_id end)
unless is_nil(approved_client) do
{:ok, _} = Repo.delete(approved_client)
end
redirect(conn, to: Routes.account_path(Endpoint, :show))
end
def import(conn, %{"file" => %Plug.Upload{} = file}) do
user = conn.assigns[:user]
{:ok, content} = File.read(file.path)
parsed = Frenzy.OPML.Importer.parse_opml(content)
total_imported_feeds =
Enum.map(parsed, fn {group_id, feeds} ->
group_title =
case group_id do
:default -> "Default"
_ when is_binary(group_id) -> group_id
end
group_changeset = Ecto.build_assoc(user, :groups, %{title: group_title})
{:ok, group} = Repo.insert(group_changeset)
Enum.each(feeds, fn feed_url ->
feed_changeset =
Ecto.build_assoc(group, :feeds, %{
feed_url: feed_url
})
{:ok, _feed} = Repo.insert(feed_changeset)
end)
Enum.count(feeds)
end)
|> Enum.sum()
conn
|> put_flash(
:info,
"Imported #{Enum.count(parsed)} groups and #{total_imported_feeds} feeds."
)
|> redirect(to: Routes.group_path(Endpoint, :index))
end
def export(conn, _params) do
user = conn.assigns[:user] |> Repo.preload(:groups)
opml = Frenzy.OPML.Exporter.export(user.groups)
send_download(conn, {:binary, opml}, filename: "frenzy_export.opml")
end
def link_oidc(conn, _params) do
conn
|> put_session(:continue_path, Routes.account_path(conn, :show))
|> redirect(to: Routes.login_path(conn, :ueberauth_request, "oidc"))
end
end