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

How to hook authorization into ja_resource? #32

Open
begedin opened this issue Oct 11, 2016 · 4 comments
Open

How to hook authorization into ja_resource? #32

begedin opened this issue Oct 11, 2016 · 4 comments

Comments

@begedin
Copy link
Contributor

begedin commented Oct 11, 2016

In our project, we would like to use ja_resource but we're having issues with authorising users. In a lot of cases, the user being authorised to perform an action depends on the changeset they are trying to persist. (For example, an admin can demote another admin, but they should not be allowed to promote them to a higher role). That would mean, that, at some point, we would have to hook into the changeset generated by handle_create/update, call authorisation on that changeset and then either allow ja_resource to continue or halt everything due to lack of proper rights.

The way the whole create process works right now, it doesn't really allow us to put a plug between the loading of resource/creation of changeset and performing of action.

Ideally, we would have something like the option to split up the default ja_resource plug into two of them, so that

plug Authenticate when action in [:create, :update, :delete]
plug JaResource

could become

plug MyApp.Authenticate when action in [:create, :update, :delete]
plug JaResource.load
plug MyApp.Authorize
plug JaResource.perform

Looking at #30, we could split it even further, potentially having something like

plug MyApp.Authenticate when action in [:create, :update, :delete]
plug JaResource.load
plug MyApp.Authorize
plug JaResource.perform
plug MyApp.Track
plug JaResource.render

Any thoughts on that? Our team would definitely find it useful, but it might be overkill.

@alanpeabody
Copy link
Contributor

@begedin Thank you for opening an issue, I appreciate the feedback! Currently I don't foresee using plugs as the way to add "hooks" because the use of assigns is the only way to pass data and isn't as clean as direct function calls.

For now I think you have 2 options:

Option 1

With out any changes to ja_resource can define your own handle_create, handle_update, and handle_delete functions. You can return an %Ecto.Changeset{} or a %Plug.Conn{} from any of them. You can do your own logic in shared functions as needed, eg:

def handle_update(conn, struct, params) do
  changeset = super(conn, struct, params) # or just create you changeset here like you would w/o ja_resource
  if Shared.authorized?(conn, changeset) do
    changeset
  else
    Shared.render_unauthorized(conn)
  end
end

You could get fancier with some meta programing if you choose.

Option 2

RE #30: I am open to callbacks that allow customization of default behavior. In this case callbacks that provided default but overridable "insert_struct", "update_struct", and "delete_struct" functions might be a hook you could use.

That said, currently this isn't a need for my team because we try to do as much logic outside of the controller as possible. I believe this is in embracing the philosophy of "services" that phoenix is moving towards. Personally I use an "interactor" pattern for most everything and keep my logic there.

@jeroenhouben
Copy link

I believe this is in embracing the philosophy of "services" that phoenix is moving towards.

@alanpeabody could you maybe point to a blog or article?

btw I really like JaResource. Thanks for open sourcing it!

@alanpeabody
Copy link
Contributor

@jeroenhouben I am not aware of any blogs, Chris McCord's keynote from Elixir Conf is my primary source of information: https://confreaks.tv/videos/elixirconf2016-keynote

@jeroenhouben
Copy link

thx @alanpeabody - I'll go and watch that :)

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

No branches or pull requests

3 participants