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

Issue/101 REST API: Chapter Management #152

Merged
merged 23 commits into from
Jul 18, 2019

Conversation

eteubert
Copy link
Member

@eteubert eteubert commented Jul 4, 2019

  1. Calling a plug directly in https://github.com/podlove/radiator/compare/issue/101-api-chapter-management?expand=1#diff-d0559d752a76cec019da187d4034d879R43 feels strange but the general idea of short-circuiting here should be ok.

  2. I added

def get_permission(_user = %Auth.User{}, _subject = %Chapter{}), do: nil

so the permission check on chapter always fails and falls back to the parent (Audio). Is that the intended place? Should there be a general def get_permission(_user = %Auth.User{}, _subject), do: nil catchall?

closes #101

@eteubert eteubert requested a review from monkeydom July 4, 2019 11:22
@monkeydom
Copy link
Collaborator

Yeah - I think probably for short circuiting errors a raise with a corrsponding catch in the error view is probably more appropriate.

Copy link
Collaborator

@monkeydom monkeydom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some notes to be addressed (all inline explained):

  • Choice of id for chapters (if not changed to the proposed start then the id needs to be reported in the GraphQL api as well to be able to be modified)
  • Missing audio_id field on get/result
  • Missing :show - if that was intentionally, it needs to be removed more thoroughly in the docs as well, if kept I think reporting audio_id in show.json is important too
  • Leakage of image files

guides/rest_api.md Outdated Show resolved Hide resolved
lib/radiator/directory/editor/permission.ex Outdated Show resolved Hide resolved
lib/radiator/directory/editor/permission.ex Outdated Show resolved Hide resolved
lib/radiator_web/views/api/chapters_view.ex Outdated Show resolved Hide resolved
lib/radiator/directory/editor.ex Outdated Show resolved Hide resolved
lib/radiator/directory/editor.ex Show resolved Hide resolved
lib/radiator/directory/editor.ex Show resolved Hide resolved
conn
|> assign(:audio, audio)

error = {:error, _} ->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned before, this is probably better done using a raise and catch the exception the way the original not found is done

@eteubert
Copy link
Member Author

Ready for a second review. A few notes:

  1. Regarding calling RadiatorWeb.Api.FallbackController directly in ChaptersController: I don't think we can raise in a plug as it breaks the typespec contract and Dialyzer complains. Tried researching a bit for similar implementations but couldn't find any, so I left it as it is for now.
  2. Leaking files in arc: I am surprised arc_ecto doesn't handle this automatically. My current solution for chapter images works "good enough" as far as my testing goes but our aim should be a generic changeset step that we can throw in everywhere we use an arc_ecto attribute. See arc_ecto: Create changeset step to auto-delete images #166

@eteubert eteubert requested a review from monkeydom July 18, 2019 11:32
Copy link
Collaborator

@monkeydom monkeydom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two comments and didn't compile and test, but looks fine to me now.

@@ -3,7 +3,12 @@ defmodule RadiatorWeb.Api.ChaptersController do

alias Radiator.Directory.Editor

plug :assign_audio when action in [:create, :update]
plug :assign_audio when action in [:show, :create, :update, :delete]
plug :assign_chapter when action in [:show, :update, :delete]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah - i see what you did there. Interesting pattern.

else
error = {:error, _} ->
conn
|> RadiatorWeb.Api.FallbackController.call(error)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, shouldn't we somehow just refer to the assigned fallbackcontroller? e.g. something like

apply(@phoenix_fallback, :call, [error])

? - in the middle of some other change now, can't verify if that is the way this should work. but the falback seems to be in the phoenix_fallback attribute

@eteubert
Copy link
Member Author

Thanks for pointing out @phoenix_fallback. However that's a tuple, either {:module, mod} or {:function, fun}, depending on type of plug used.

What I came up with:

  defp apply_action_fallback(conn, response) do
    case @phoenix_fallback do
      {:module, module} -> apply(module, :call, [conn, response]) |> halt()
    end
  end

Then I can

  defp assign_chapter(conn, _) do
    with {:ok, chapter} <-
           conn
           |> current_user()
           |> Editor.get_chapter(conn.assigns[:audio], conn.params["start"]) do
      conn
      |> assign(:chapter, chapter)
    else
      response -> apply_action_fallback(conn, response)
    end
  end

It's at least removes the direct reference to the plug module name, which is nice. What bothers me is that I cannot add the {:function, fun} case because Dialyzer determines it's a module and complains the match is pointless. Anyway, still happier with this than before.

@eteubert eteubert merged commit 4eacb68 into master Jul 18, 2019
@eteubert eteubert deleted the issue/101-api-chapter-management branch July 18, 2019 14:15
eteubert added a commit that referenced this pull request Dec 12, 2019
This logic existed before in a similar way but was removed[1]. I'm not sure why.
Also, we had a discussion[2] before on checking permissions on objects that don't have permissions and decided to avoid that and instead pass in the proper parent object into permission checks. However in that discussion the topic was chapters and it was trivial to just pass in the parent instead. Checking the permission on the Audio however is more envolved and I want this logic in _one_ place only.

[1]: 9b878fc7#diff-8fce5c34154f97d93f212e64bd95fee7L61
[2]: #152 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[User Story] Chapter Editing with REST API
2 participants