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