Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: use secret hash parameter to switch to admin mode #485

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ Hooks.SetIdeaLabelBackgroundColor = {
};

let liveSocket = new LiveSocket("/live", Socket, {
hooks: Hooks, params: { _csrf_token: csrfToken }
hooks: Hooks, params: { _csrf_token: csrfToken, adminSecret: window.location.hash.substring(1) }
})

// Show progress bar on live navigation and form submits
Expand Down
32 changes: 28 additions & 4 deletions lib/mindwendel/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ defmodule Mindwendel.Accounts do
alias Mindwendel.Repo
alias Mindwendel.Accounts.User
alias Mindwendel.Brainstormings.Brainstorming
alias Mindwendel.Accounts.BrainstormingModeratingUser

require Logger

Expand Down Expand Up @@ -47,7 +48,7 @@ defmodule Mindwendel.Accounts do
end

def get_user(id) do
Repo.get(User, id) |> Repo.preload(:brainstormings)
Repo.get(User, id) |> Repo.preload([:brainstormings, :moderated_brainstormings])
rescue
Ecto.Query.CastError -> nil
end
Expand All @@ -70,6 +71,32 @@ defmodule Mindwendel.Accounts do
|> Repo.update()
end

@doc """
Adds a user as moderating user to a brainstorming.

## Examples

iex> add_moderating_user(brainstorming, user)
%Brainstorming{}

"""
def add_moderating_user(%Brainstorming{} = brainstorming, %User{} = user) do
%BrainstormingModeratingUser{brainstorming_id: brainstorming.id, user_id: user.id}
|> BrainstormingModeratingUser.changeset()
|> Repo.insert()
end

def add_moderating_user(%Brainstorming{} = brainstorming, user_id) when is_binary(user_id) do
case Ecto.UUID.dump(user_id) do
:error -> brainstorming
{:ok, _} -> add_moderating_user(brainstorming, get_or_create_user(user_id))
end
end

def add_moderating_user(%Brainstorming{} = brainstorming, user_id) when is_nil(user_id) do
brainstorming
end

@doc """
Connects user to a brainstorm.

Expand All @@ -80,9 +107,6 @@ defmodule Mindwendel.Accounts do
iex> merge_brainstorming_user(brainstorming, user)
%Brainstorming{}

iex> update_user(user, %{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def merge_brainstorming_user(%Brainstorming{} = brainstorming, %User{} = user) do
# credo:disable-for-next-line
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule Mindwendel.Brainstormings.BrainstormingModeratingUser do
defmodule Mindwendel.Accounts.BrainstormingModeratingUser do
# Not using Mindwendel.Schema as the `@derive` in there clashes here
use Ecto.Schema
alias Mindwendel.Brainstormings.Brainstorming
Expand Down
2 changes: 1 addition & 1 deletion lib/mindwendel/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Mindwendel.Accounts.User do

alias Mindwendel.Brainstormings.Brainstorming
alias Mindwendel.Brainstormings.Idea
alias Mindwendel.Brainstormings.BrainstormingModeratingUser
alias Mindwendel.Accounts.BrainstormingModeratingUser
alias Mindwendel.Accounts.BrainstormingUser

schema "users" do
Expand Down
11 changes: 4 additions & 7 deletions lib/mindwendel/brainstormings.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ defmodule Mindwendel.Brainstormings do
alias Mindwendel.Lanes
alias Mindwendel.Ideas
alias Mindwendel.Brainstormings.Brainstorming
alias Mindwendel.Brainstormings.BrainstormingModeratingUser

require Logger

Expand All @@ -36,12 +35,6 @@ defmodule Mindwendel.Brainstormings do
)
end

def add_moderating_user(%Brainstorming{} = brainstorming, %User{} = user) do
%BrainstormingModeratingUser{brainstorming_id: brainstorming.id, user_id: user.id}
|> BrainstormingModeratingUser.changeset()
|> Repo.insert()
end

@doc """
Returns the list of brainstormings.

Expand Down Expand Up @@ -237,6 +230,10 @@ defmodule Mindwendel.Brainstormings do
brainstorming
end

def validate_admin_secret(brainstorming, admin_secret_id) do
brainstorming.admin_url_id == admin_secret_id
end

@doc """
Returns a subscibe result.

Expand Down
2 changes: 1 addition & 1 deletion lib/mindwendel/brainstormings/brainstorming.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule Mindwendel.Brainstormings.Brainstorming do
alias Mindwendel.Brainstormings.Idea
alias Mindwendel.Brainstormings.IdeaLabel
alias Mindwendel.Brainstormings.Lane
alias Mindwendel.Brainstormings.BrainstormingModeratingUser
alias Mindwendel.Accounts.BrainstormingModeratingUser
alias Mindwendel.Accounts.User
alias Mindwendel.Accounts.BrainstormingUser

Expand Down
35 changes: 0 additions & 35 deletions lib/mindwendel_web/channels/user_socket.ex

This file was deleted.

6 changes: 3 additions & 3 deletions lib/mindwendel_web/endpoint.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ defmodule MindwendelWeb.Endpoint do
signing_salt: "Kxo5qCGx"
]

socket "/socket", MindwendelWeb.UserSocket,
websocket: true,
longpoll: false
# socket "/socket", MindwendelWeb.UserSocket,
# websocket: true,
# longpoll: false

socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]

Expand Down
12 changes: 9 additions & 3 deletions lib/mindwendel_web/live/brainstorming_live/show.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ defmodule MindwendelWeb.BrainstormingLive.Show do
def mount(%{"id" => id}, session, socket) do
if connected?(socket), do: Brainstormings.subscribe(id)

# If the admin secret in the URL after the hash (only available inside the client session) is given, add the user as moderating user to the brainstorming.
# If not, add the user as normal user.
current_user_id = Mindwendel.Services.SessionService.get_current_user_id(session)
brainstorming = Brainstormings.get_brainstorming!(id)
admin_secret = get_connect_params(socket)["adminSecret"]

brainstorming =
Brainstormings.get_brainstorming!(id)
|> Accounts.merge_brainstorming_user(current_user_id)
case Brainstormings.validate_admin_secret(brainstorming, admin_secret) do
true -> Accounts.add_moderating_user(brainstorming, current_user_id)
_ -> Accounts.merge_brainstorming_user(brainstorming, current_user_id)
end

lanes = Lanes.get_lanes_for_brainstorming_with_labels_filtered(id)
# load the user, also for permissions of brainstormings
current_user = Mindwendel.Accounts.get_user(current_user_id)

{
Expand Down
2 changes: 1 addition & 1 deletion lib/mindwendel_web/live/idea_live/card_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ defmodule MindwendelWeb.IdeaLive.CardComponent do

%{current_user: current_user, brainstorming: brainstorming} = socket.assigns

if current_user.id in [idea.user_id | brainstorming.moderating_users |> Enum.map(& &1.id)] do
if has_moderating_or_ownership_permission(brainstorming, idea, current_user) do
{:ok, _} = Ideas.delete_idea(idea)
end

Expand Down
3 changes: 1 addition & 2 deletions lib/mindwendel_web/live/label_live/captions_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ defmodule MindwendelWeb.LabelLive.CaptionsComponent do
alias Mindwendel.Brainstormings

def handle_event("set_filter_idea_label", %{"id" => idea_label_id}, socket) do
brainstorming = socket.assigns.brainstorming
current_user = socket.assigns.current_user
%{current_user: current_user, brainstorming: brainstorming} = socket.assigns

if has_moderating_permission(brainstorming, current_user) do
# If the filter is already present, remove it as its toggled. If not, add it.
Expand Down
2 changes: 1 addition & 1 deletion lib/mindwendel_web/live/live_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule MindwendelWeb.LiveHelpers do
end

def has_moderating_permission(brainstorming, current_user) do
Enum.member?(brainstorming.moderating_users |> Enum.map(& &1.id), current_user.id)
Enum.member?(current_user.moderated_brainstormings |> Enum.map(& &1.id), brainstorming.id)
end

def has_ownership(record, current_user) do
Expand Down
6 changes: 3 additions & 3 deletions priv/gettext/de/LC_MESSAGES/default.po
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ msgstr "Wie können wir ..."
msgid "Ready?"
msgstr "Fertig?"

#: lib/mindwendel_web/live/brainstorming_live/show.ex:168
#: lib/mindwendel_web/live/brainstorming_live/show.ex:174
#, elixir-autogen, elixir-format
msgid "%{name} - Edit"
msgstr "%{name} - Editieren"

#: lib/mindwendel_web/live/brainstorming_live/show.ex:145
#: lib/mindwendel_web/live/brainstorming_live/show.ex:151
#, elixir-autogen, elixir-format
msgid "%{name} - New Idea"
msgstr "%{name} - Neue Idee"
Expand Down Expand Up @@ -403,7 +403,7 @@ msgstr "Löschen"
msgid "Type the label name"
msgstr "Gebe dem Label einen Namen"

#: lib/mindwendel_web/live/brainstorming_live/show.ex:155
#: lib/mindwendel_web/live/brainstorming_live/show.ex:161
#, elixir-autogen, elixir-format, fuzzy
msgid "%{name} - New Lane"
msgstr "%{name} - Neue Idee"
Expand Down
6 changes: 3 additions & 3 deletions priv/gettext/default.pot
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ msgstr ""
msgid "Ready?"
msgstr ""

#: lib/mindwendel_web/live/brainstorming_live/show.ex:168
#: lib/mindwendel_web/live/brainstorming_live/show.ex:174
#, elixir-autogen, elixir-format
msgid "%{name} - Edit"
msgstr ""

#: lib/mindwendel_web/live/brainstorming_live/show.ex:145
#: lib/mindwendel_web/live/brainstorming_live/show.ex:151
#, elixir-autogen, elixir-format
msgid "%{name} - New Idea"
msgstr ""
Expand Down Expand Up @@ -402,7 +402,7 @@ msgstr ""
msgid "Type the label name"
msgstr ""

#: lib/mindwendel_web/live/brainstorming_live/show.ex:155
#: lib/mindwendel_web/live/brainstorming_live/show.ex:161
#, elixir-autogen, elixir-format
msgid "%{name} - New Lane"
msgstr ""
Expand Down
6 changes: 3 additions & 3 deletions priv/gettext/en/LC_MESSAGES/default.po
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ msgstr ""
msgid "Ready?"
msgstr ""

#: lib/mindwendel_web/live/brainstorming_live/show.ex:168
#: lib/mindwendel_web/live/brainstorming_live/show.ex:174
#, elixir-autogen, elixir-format
msgid "%{name} - Edit"
msgstr ""

#: lib/mindwendel_web/live/brainstorming_live/show.ex:145
#: lib/mindwendel_web/live/brainstorming_live/show.ex:151
#, elixir-autogen, elixir-format
msgid "%{name} - New Idea"
msgstr ""
Expand Down Expand Up @@ -403,7 +403,7 @@ msgstr ""
msgid "Type the label name"
msgstr ""

#: lib/mindwendel_web/live/brainstorming_live/show.ex:155
#: lib/mindwendel_web/live/brainstorming_live/show.ex:161
#, elixir-autogen, elixir-format, fuzzy
msgid "%{name} - New Lane"
msgstr ""
Expand Down
50 changes: 46 additions & 4 deletions test/mindwendel/accounts_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,54 @@ defmodule Mindwendel.AccountsTest do
use Mindwendel.DataCase, async: true
alias Mindwendel.Factory
alias Mindwendel.Accounts
alias Mindwendel.Brainstormings
alias Mindwendel.Accounts.User
alias Mindwendel.Accounts.BrainstormingUser
alias Mindwendel.Accounts.BrainstormingModeratingUser
alias Mindwendel.Brainstormings.Brainstorming

import ExUnit.CaptureLog

setup do
%{user: Factory.insert!(:user)}
user = Factory.insert!(:user)
brainstorming = Factory.insert!(:brainstorming)

%{
brainstorming: brainstorming,
user: user
}
end

describe "#add_moderating_user" do
test "adds a moderating user to the brainstorming", %{
brainstorming: brainstorming,
user: %User{id: user_id} = user
} do
Accounts.add_moderating_user(brainstorming, user)

assert 1 = Repo.one(from(bmu in BrainstormingModeratingUser, select: count(bmu.user_id)))
assert brainstorming_moderatoring_user = Repo.one(BrainstormingModeratingUser)
assert brainstorming_moderatoring_user.user_id == user.id
assert brainstorming_moderatoring_user.brainstorming_id == brainstorming.id

assert [%User{id: ^user_id}] =
Brainstormings.get_brainstorming!(brainstorming.id).moderating_users
end

test "responds with an error when brainstorming already contains the moderating user", %{
brainstorming: brainstorming,
user: user
} do
Accounts.add_moderating_user(brainstorming, user)

assert {:error,
%Ecto.Changeset{
valid?: false,
errors: [
brainstorming_id: {_, [{:constraint, :unique}, _]}
]
}} = Accounts.add_moderating_user(brainstorming, user)
end
end

describe "get_or_create_user" do
Expand All @@ -31,7 +71,7 @@ defmodule Mindwendel.AccountsTest do

describe "get_user" do
test "returns user when it exists", %{user: existing_user} do
assert existing_user |> Repo.preload(:brainstormings) ==
assert existing_user |> Repo.preload([:brainstormings, :moderated_brainstormings]) ==
Accounts.get_user(existing_user.id)
end

Expand All @@ -54,11 +94,13 @@ defmodule Mindwendel.AccountsTest do
|> Repo.preload(:users)

old_user = Factory.insert!(:user, updated_at: ~N[2021-01-01 10:00:00])
Accounts.merge_brainstorming_user(old_brainstorming, old_user.id)

updated_old_brainstorming =
Accounts.merge_brainstorming_user(old_brainstorming, old_user.id)

%{
old_user: old_user,
old_brainstorming: old_brainstorming
old_brainstorming: updated_old_brainstorming
}
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule Mindwendel.Brainstormings.CreateBrainstormingTest do
use Mindwendel.DataCase, async: true
alias Mindwendel.Brainstormings.BrainstormingModeratingUser
alias Mindwendel.Accounts.BrainstormingModeratingUser
alias Mindwendel.Accounts.BrainstormingUser
alias Mindwendel.Factory

Expand Down
Loading