Skip to content

Proposal: add new special has_user_access? for QueryAuthorization #37

@jotaviobiondo

Description

@jotaviobiondo

Today, the has_user_access?/3 receives the user, some struct and the rule. This is nice for the Rajska.ObjectScopeAuthorization where the struct received is "complete" with all data, since it's coming from the source object that is being authorized.

But, for the Rajska.QueryAuthorization it's a bit strange, since we receive an "incomplete" struct, created using the scope and args option. This can sometimes be confusing, since we need to know if this struct is coming from the query authorization or the object authorization.

This can even limit (or force creation of workarounds), when the arguments received in the query or mutation is not directly related to the scope module. Consider this example:

Post and a Comment are Ecto structs, with Post having a has_many :comments, Comment.

object :post do
  field :id, :integer
  field :name, :string
  field :comments, list_of(:comments)
end

object :comment do
  field :id, :integer
  field :text, :string
  field :post, :post
end

field :list_posts_by_comments, list_of(:post) do
  arg :comment_ids, list_of(:integer)

  middleware Rajska.QueryAuthorization, [
    permit: :user,
    scope: Post,
    args: %{?????????: :comment_ids},
  ]
  resolve &BlogResolver.list_posts/2
end

In this case, the Post struct does not contains a comment_ids field, so we have to use the most related field form post, like this: args: %{comments: :comment_ids} or create a virtual field comment_ids in Post.

It's doable, but seems like a workaround.

My suggestions:

  1. have another function (besides has_user_access?) just for the QueryAuthorization, with a signature more or less like query_authorized?(%User{}, Post = _just_the_module, %{comment_ids: comment_ids} = args, rule)
  2. use the same has_user_access?, but add a fourth argument, acting like a metadata and pass the empty struct: has_user_access?(%User{}, %Post{} = _no_field_filled, rule, %{comment_ids: comment_ids} = metadata)

I don't think these 2 suggestions are the best API, but couldn't think a better one right now. If you guys agree with the proposal, we should probably iterate to find a more suitable API for the QueryAuthorization.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions