woohaaha

woohaaha

Authorization as business logic

I see a lot of posts/discussions around authorization and how one should not mix it up with business logic. So in the controller they will authorize, and then perform the action.

In my head I feel like authorization IS business logic. Authorization is part of the rules that make an app operate as intended. I kind of want authorization logic to sit right next to resource actions.

def create_user(attrs, %User{role: role} = current_user) do
   with :ok <- authorize(:create_user, role),
      changeset = User.changeset(attrs),
      {:ok, user} = Repo.insert(attrs) do:
  # stuff
end

Can anyone explain concretely why authorization is NOT business logic?

Most Liked

bennelsonweiss

bennelsonweiss

Two comments about this, see the reference number in the code block for each:

  1. It depends what Blogs.get_post returns here, but if it returns like Map.get then it will either return a blog post or nil, and since you’re using = there either will be a valid return value.

    This means that you could be passing nil to Blogs.update_post which would probably result in an error if you’re not checking for nil in Blogs.update_post.

    A cleaner solution would be either to use a version of Blogs.get_post! that raises or a Blogs.fetch_post that returns either {:ok, post} or and error that you can match on during the with.

  2. error -> {:error, error} may not behave how you expect- if Blogs.update_post returns {:error, error} then you’re capturing that value as error, which means you’re returning {:error, {:error, error}} from the with.

hauleth

hauleth

While I agree that authorisation is part of the business logic, I disagree that authorisation is part of create_user function. While this indeed prevents (in most cases) accidental omission of the check, it makes API less flexible, which mean that we need additional functions to create 1st user or create users in tests.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

If this is related to comments I made in the RBAC thread, I’ll clarify a bit here.

In my head I feel like authorization IS business logic

I agree with this. What I was warning about was making all business logic authorization logic. That is to say, it’s reasonable to ask “is this user authorized to create a user”. It’s also reasonable to say “Is it valid to create a user with no username? No”. But it’d be weird to say “You are authorized to create a user with a valid user name, and not authorized to create a user without a username”.

All of it is business logic, but within the domain of business logic there are some questions that make sense rendered in terms of authorization, and other questions that make more sense rendered in terms of validation. If you treat auth as merely one of a dozen different properties that must be true about an entity when it is being created then it blurs that line in a way that I think is unhelpful.

stefanchrobot

stefanchrobot

Wow, great insight! I always struggled whether my context should return the schema or an ok/error tuple. Using get/fetch approach makes total sense and it follows the std lib.

Where Next?

Popular in Questions Top

dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
kostonstyle
Hi all I want to have a unix time, from the current time plus 1 hour. DateTime.now + 1 hour How to get it in elixir? Thanks
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

We're in Beta

About us Mission Statement