zachallaun

zachallaun

Feedback wanted: Authorization library with composable Ecto queries

Hi friends,

I wanted an authorization utility for an existing project I’m working on where I have a fair amount of permissions logic duplicated between functions that check whether a person can do something to a given resource and query utilities that filter a query based on what a person is allowed to do.

After spending a bit of time looking at existing solutions, I decided to spend a couple days putting something together myself.

Janus is the result.

The library is extremely alpha and not yet released on hex. It’s basically at the “works enough to test in my own project” stage, but I’d like to hear from folks on the approach I’ve taken and whether it’s worth pursuing further. Basically: I (think I) like it and will use it myself, but I’m not sure whether it makes sense to invest in bits that may make it more useful for others.

If you have a spare 5-10 minutes, please consider reading through the example in the README. I’d love to hear any thoughts or feedback. Thanks!

First Post!

csadewa

csadewa

I just looked at Janus, and i love the ease and flexibility for defining rule for security!

I have a bit of concern though, how about the performance of Janus? I look at code for a bit and it seems to depend on DB (via ecto query), so i have concern on latency and throughput of it.

Most Liked

zachallaun

zachallaun

This proved a little trickier, but the result is actually pretty dang cool. I’m not quite done implementing this yet but I’m confident it can be done.

To take your example a little further: Let’s say you were implementing user search. In the results, you wanted to display the user’s last thread, the first post in that thread, and user’s latest post in any thread.

Normal users can’t see banned users or archived threads or posts, but moderators can see both.

Here’s how it might look like using Janus:

latest_thread = Thread |> order_by(desc: :inserted_at) |> limit(1)
first_post = Post |> where(index: 0) |> limit(1)
latest_post = Post |> order_by(desc: :inserted_at) |> limit(1)

search_params
|> Accounts.search()
|> Policy.filter(:read, current_user,
  preload_filtered: [
    threads: {latest_thread, posts: first_post},
    posts: latest_post
  ]
)
|> Repo.all()

The result of this would be the users that the current user can read, preloaded with the latest thread created by that user (and that thread’s first post) that the current user can read, and the latest post by that user that the current user can read. So a normal user would see non-banned users and non-archived threads/posts, while a moderator may see banned users and archived threads/posts mixed into the results. This all done with a single query and includes users that may have no threads or posts.

Man, Ecto is really cool.

Last Post!

zachallaun

zachallaun

Ended up really happy with this in my own usage and it’s become a bit of A Thing™. If anyone is able to check out the docs, I’d be extremely appreciative of any feedback. Even better would be if someone had the time and willingness to run the policy generator and use it to define some auth rules for their own project:

defp deps do
  [
    :ex_janus, "~> 0.2.0-alpha.0"
  ]
end
$ mix janus.gen.policy

:heart:

Where Next?

Popular in RFCs Top

tmbb
I’ve started working on a toy project to compile extended POSIX-compatible regular expressions into NimbleParsec combinators. These combn...
New
pzingg
https://github.com/pzingg/phx_cookie_consent I took a phx.gen.auth application and added support for storing a user’s cookie consent set...
New
BartOtten
This thread once discussed Routex in it’s early form. It has been repurposed to gather feedback and discusses pre-releases. Currently: p...
New
ca1989
Hi all, this week I played a bit with Phoenix and Elm. I ended up with this POC: https://github.com/carlotm/elmex The repository cont...
New
marick
TL;DR I’ve forked the Lens package, changed the API some, added new lens makers and – most importantly – added a ton of documentation. In...
New
wolf4earth
Every protocol you’ve shipped assumes the spec doesn’t change during the connection. This one doesn’t. Code is typed, composable, content...
New
type1fool
After discussing some of my ideas around Event Sourcing at last night’s Elixir Happy Hour in Austin (highly recommend), I spent some time...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement