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

Remove ja_resource and canary reliance from UserController #882

Merged
merged 10 commits into from
Sep 7, 2017

Conversation

snewcomer
Copy link
Contributor

@snewcomer snewcomer commented Aug 31, 2017

What's in this PR?

[WIP]
Remove ja_resource from User Controller

References

Fixes #882

Progress on: #864

def can?(%User{}, _action, nil), do: true

def can?(%User{} = current_user, :update, %User{} = user), do: Policy.User.update?(user, current_user)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NOTE: had to leave these in here b/c other tests not in the user_controller_test were depending on this

Copy link
Contributor

Choose a reason for hiding this comment

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

I understand why line 44 needs to stay, but are you sure about 45? Which tests fail if you remove it? Assuming you add the "fixes" i described below.

defp login(conn, _opts) do
Plug.Conn.register_before_send(conn, &do_login(&1))
end
# defp login(conn, _opts) do
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@begedin any idea why commenting these lines (and the plug :login) above out allows for a passing test suite? Otherwise I get this line and this line failing

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure, but I would expect the plug to cause things to fail either way. It was added mainly to get around some ja_resource quirks.

What I would do is remove plug :login when action in [:create], as well as defp login and defp do_login completely.

Then, in create/2, I would add a |> Guardian.Plug.sign_in(user) between conn and |> put_status(:created), or really, anywhere in that chain.

That would be the most explicit and easiest to read approach for dealing with it anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@begedin is this b/c the user is signed in automatically after creating a user?

Copy link
Contributor

@begedin begedin left a comment

Choose a reason for hiding this comment

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

This generally looks good. Ping me for another review when you try the advice I gave.

def create(%Conn{} = conn, %{} = params) do
with {:ok, %User{} = user} <- %User{} |> User.registration_changeset(params) |> Repo.insert
do
conn |> Plug.Conn.fetch_session |> Guardian.Plug.sign_in(user) |> put_status(:created) |> render("show.json-api", data: user)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@begedin so this worked.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Although a bit lost on why this is needed as compared to before these changes.

Copy link
Contributor

Choose a reason for hiding this comment

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

The login function was a plug. It automatically ran before performing the create action and told the conn that, after performing create, it needs to run the do_login function.

The do_login function then signed the user into the conn if the create action was successful.

Basically, from a user's perspective, "i want to be signed in when I register".

We had to do it via a plug, due to some quirks with canary.

Now that canary is gone, we can do the more direct route, so we just do it as part of the action itself.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you mean the fetch_session part, that should not be needed. What happens if you remove it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

@snewcomer Strange, but it makes sense.

I think you actually found a bug in the old login function. We were just calling Conn.assign instead of actually formally signing the user in.

Additionally, it looks like our client is not expecting to sign the user in automatically upon registration and instead does it manually.

Considering these two, I think the simplest thing we can do is outright remove both fetch_session and sign_in.

Simply put, the code should read conn |> put_status(:created) |> render("show.json-api", data: user)and we can leave it that that.

Sorry to make go through all of this, but hey, we discovered a bug and a piece of code that does nothing along the way!

def create(%Conn{} = conn, %{} = params) do
with {:ok, %User{} = user} <- %User{} |> User.registration_changeset(params) |> Repo.insert
do
conn |> Plug.Conn.fetch_session |> Guardian.Plug.sign_in(user) |> put_status(:created) |> render("show.json-api", data: user)
Copy link
Contributor

Choose a reason for hiding this comment

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

@snewcomer Strange, but it makes sense.

I think you actually found a bug in the old login function. We were just calling Conn.assign instead of actually formally signing the user in.

Additionally, it looks like our client is not expecting to sign the user in automatically upon registration and instead does it manually.

Considering these two, I think the simplest thing we can do is outright remove both fetch_session and sign_in.

Simply put, the code should read conn |> put_status(:created) |> render("show.json-api", data: user)and we can leave it that that.

Sorry to make go through all of this, but hey, we discovered a bug and a piece of code that does nothing along the way!

@snewcomer snewcomer changed the title [WIP] [USER CONTROLLER]: remove ja_resource [WIP] [USER CONTROLLER]: remove ja_resource close #913 Sep 6, 2017
@@ -30,6 +30,8 @@ defmodule CodeCorps.Policy do
defp can?(%User{} = user, :update, %Comment{} = comment, %{}), do: Policy.Comment.update?(user, comment)
defp can?(%User{} = user, :create, %Organization{}, %{}), do: Policy.Organization.create?(user)
defp can?(%User{} = user, :update, %Organization{} = organization, %{}), do: Policy.Organization.update?(user, organization)
defp can?(%User{} = current_user, :update, %User{} = user, %{}), do: Policy.User.update?(user, current_user)
defp can?(%User{}, _action, %User{} = _user, %{}), do: true
Copy link
Contributor

Choose a reason for hiding this comment

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

Remind me again, why is this one needed? It seems unsafe, as it would technically allow any user to perform any action on any other user.

If you meant to copy-paste the one from line 46 below, then the third argument would be nil, but that means you'd also have to update the spec to allow nil, not just User.t as the third argument.

However, I don't think the catch all from below is strictly necessary when not using canary, so could you double check?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep my bad. Good call!

@begedin begedin changed the title [WIP] [USER CONTROLLER]: remove ja_resource close #913 Remove ja_resource and canary reliance from UserController Sep 7, 2017
@begedin begedin merged commit c579fb7 into develop Sep 7, 2017
@begedin begedin deleted the user-controller-no-jaresource branch September 7, 2017 15:15
@begedin
Copy link
Contributor

begedin commented Sep 7, 2017

Hey @snewcomer. I merged! Excellent work.

@joshsmith
Copy link
Contributor

🙌 I love seeing things like this happening when I'm not even looking. Great work @snewcomer!

untra pushed a commit to untra/code-corps-api that referenced this pull request Sep 16, 2017
…s#882)

* Removed ja_resource and canary reliance from UserController
* Fixed bug
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants