Skip to content
This repository has been archived by the owner on Apr 3, 2024. It is now read-only.

Introduces authorize_controller functionality #61

Merged
merged 6 commits into from
Jun 13, 2017

Conversation

ghatighorias
Copy link
Contributor

send calling controller to the canada.can? function instead of model

This way a user can be authorized based on the action And the controller the action is called from

send calling controller to the canada.can? function instead of model
Copy link
Owner

@cpjk cpjk left a comment

Choose a reason for hiding this comment

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

A few comments. Let me know if I made any mistakes. I'm also open to suggestions of course.

@@ -181,6 +181,27 @@ defmodule Canary.Plugs do
plug :load_resource, model: Post, id_name: "slug", id_field: "slug", only: [:show], persisted: true
```
"""
def authorize_controller(%{assigns: %{current_user: nil}} = conn, opts) do
Copy link
Owner

Choose a reason for hiding this comment

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

Why %{current_user: nil}? It looks like this makes the assumption that a nil user should always be unauthorized. However, this is not always true. For example, we might not assign a current_user for users that are not logged in, but we still want non-logged in users to be able to access certain controller actions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

okay I got it, it was my bad understanding of the tests. will fix this also

conn
end
end
def authorize_controller(conn, _), do: Plug.Conn.assign(conn, :authorized, true)
Copy link
Owner

Choose a reason for hiding this comment

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

It looks like this is saying "whenever there is no phoenix_controller set in the conn, set authorized: true"

I think it would be better to delete this line, and allow the match error to be raised. If someone is using authorize_controller, they should know to set phoenix_controller in the conn, and it makes sense that an error should occur if it is not there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes this is rather excessive. again it was my bad understanding of the test

Copy link
Contributor Author

Choose a reason for hiding this comment

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

did you have time to check the changes ? are they okay now ?

|> handle_unauthorized(opts)
end
def authorize_controller(%{assigns: %{current_user: user},
private: %{phoenix_controller: controller}} = conn, opts) do
Copy link
Owner

Choose a reason for hiding this comment

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

I think it would be nice to allow non-phoenix users to use a controller key other than phoenix_controller. Maybe canary_controller?

So we would fetch the controller like controller = conn.assigns[:canary_controller] || conn.assigns[:phoenix_controller] or something like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agree, didn't think about this point at all.

1 - does not authomatically deauthenticate when current_user is nil
2 - allow allow non-phoenix users to use a controller key using :canary_controller
3 - when the controller is not set properly fail the authentication
4 - updates the tests accordingly
Copy link
Owner

@cpjk cpjk left a comment

Choose a reason for hiding this comment

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

Sorry for not getting back to you earlier. I've had a busy week.

The changes look good!

There are a just a couple small things that I missed before, but other than that, looks great.

@@ -181,6 +181,22 @@ defmodule Canary.Plugs do
plug :load_resource, model: Post, id_name: "slug", id_field: "slug", only: [:show], persisted: true
```
"""
def authorize_controller(conn, opts) do
Copy link
Owner

@cpjk cpjk Jun 10, 2017

Choose a reason for hiding this comment

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

I'm sorry for missing this before, but we should move authorize_controller so that it is below do_authorize_resource. This will keep the @doc string above with authorize_resource, since that is the function it refers to. It will also keep do_authorize_resource with authorize_resource.

We should also add a new @doc string above authorize_controller, so that it will be added to the hex docs, and a section in the README.md describing the usage of authorize_controller.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done :)
Please check if the documentation is good enough.
Thanks a lot

Copy link
Owner

Choose a reason for hiding this comment

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

Just 2 more comments. Sorry for the repeated change requests, but it's better if we make sure everything is fine now, rather than having to fix bugs later :)

adds documentation
2) :canary_controller in conn.assigns
In case you are not using phoenix, make sure you set the controller name in the conn.assigns
Note that in case neither of :phoenix_controller or :canary_controller are found the requested
authorization will automatically fails
Copy link
Owner

Choose a reason for hiding this comment

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

From controller = conn.assigns[:canary_controller] || conn.private[:phoenix_controller], it looks like when neither phoenix_controller or canary_controller are present, controller will be nil, meaning that we will just authorize against a nil controller in Canada, so authorization will not necessarily fail (this could be set to true in the Canada rules). I think this behaviour is fine since it is consistent with how authorize_resource works, but we should make sure the docs here are consistent with the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you're right. I totally missed this. I have updated it

expected = Plug.Conn.assign(conn, :authorized, false)

assert authorize_controller(conn, opts) == expected
end
Copy link
Owner

Choose a reason for hiding this comment

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

We should probably add a test for when authorization fails because a rule specified that the user could not access a given controller (as a regression test).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added two more test for a controller that has partial access

@cpjk
Copy link
Owner

cpjk commented Jun 13, 2017

LGTM! Thanks for the PR!

thumbs_up

@cpjk cpjk merged commit 36b9a82 into cpjk:master Jun 13, 2017
@gsempe
Copy link

gsempe commented Jul 17, 2018

My question is related to this PR. I don't find any canary_controller guide/documentation/best practice on how to fill this key. Can you, please, share ideas about that?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants