Ok so in just 1 day I have almost ported my Rails API over to Phoenix, thanks everyone!
So in rails I have a class where I take in a few models as inputs, and based on those models I created my authorization class that I use in my controllers.
class PermissionService
attr_access :model1, :model2, :model3
def initialize(model1, model2, model3)
...
end
def can_do_this?()
model1.prop1 && model3.prop5
end
def can_do_that?()
end
end
So far in Phoenix I created a custom Plug that I can in my API pipeline, I get the api token from the request and I load etc. using Ecto.
How would I design a module?? to mimick my PermissionService I have in ruby.
You can port that code in a relatively straightforward manner. However, there are probably more idiomatic approaches but it’s hard to suggest them without knowing more concrete details of your use-case. The code below definitely smells more OO than functional.
defmodule MyPermissionService do
defstruct [:model1, :model2, :model3]
def new(model1, model2, model3) do
%__MODULE__{model1: model1, model2: model2, model3: model3}
end
def can_do_this?(%__MODULE__{} = service) do
%__MODULE__{model1: model1, model3: model3} = service
model1.prop1 && model3.prop5
end
...
end
def YourController do
plug :can_do_this when action in [:actions_can_do_this]
plug :can_do_that when action in [:actions_can_do_that]
# function plug can_do_this
defp can_do_this(conn, _) do
end
# function plug can_do_that
defp can_do_that(conn, _) do
end
end
Of course we can extract those function plugs into its own module.
I would suggest not to carbon copy your rails/ruby code, think for second how can you model this functionally for example I could create a module that implements the functions to check some permission it could be any module instead of taking 1,2,3 models
defmodule PermissionService do
def can_do_x(list_of_some_model) when is_list(list_of_some_model) do
end
def can_do_x(some_model) do
end
def can_do_y(some_model) do
end
end
not only you can extend this example to accept arbitrary models you can also use it as plugs if you like with minor changes
Note: possible improvements you can create behavior which is implemented by your permission models
can access post, can create forum, can reply to post
Update
Thanks for your suggestions, I think I will make it more functional, and also create plugs where it makes sense as sometimes I want the request execution to redirect or halt, and at other times it will be a simple message to the UI or a specific JSON response.
Hey @salman, I have read your post and I had similar requirements as you (Blog system not forum system as in your case, but context are almost same). I have struggled with dirty rules definition and I recently created library
Maybe you could take a look to it and let me know any suggestions/if it fits in your context and what can I improve to fit it
I went the custom route at this time, I’ll check your lib out though thanks.
I wanted something very specific to my needs because I didn’t want to wrestle with another library.
I tend to like full-control when it comes to a permission system (authorization)