magiclabs / example-nextjs-faunadb-todomvc

example-nextjs-faunadb-todomvc.vercel.app
28 stars 9 forks source link

Convert project from deprecated permissions scheme to using ABAC #2

Open hichana opened 4 years ago

hichana commented 4 years ago

Great starter, thank you.

The permissions scheme used in the project is deprecated: https://docs.fauna.com/fauna/current/security/permissions.html

It would be nice to convert it to use ABAC. For example, a couple steps to do this that I've found so far (there may be more but it seems to work for me so far) are:

  1. change the query to create the collection 'todos' from CreateCollection({ name: "todos", permissions: { create: Collection("users") } }); to CreateCollection({ name: "todos" });.

  2. change the todo model query to write the todos from

  async addTodo(title) {
    const user = q.Identity();
    const newTodo = { title, user, completed: false };

    const res = await this.client.query(
      q.Create(q.Collection('todos'), {
        data: newTodo,
        permissions: { read: user, write: user },
      })
    )
    return res.ref.id
  }

to

  async addTodo(title) {
    const user = q.Identity();
    const newTodo = { title, user, completed: false };

    const res = await this.client.query(
      q.Create(q.Collection('todos'), {
        data: newTodo,
      })
    )
    return res.ref.id
  }
  1. Add the ABAC role in the shell:
CreateRole({
  name: "todo-user-role",
  membership: [
    {
      resource: Collection("users")
    }
  ],
  privileges: [
    {
      resource: Collection("todos"),
      actions: {
        read: Query(
          Lambda(
            "todoRef",
            Let(
              {
                todo: Get(Var("todoRef")),
                userRef: Select(["data", "user"], Var("todo"))
              },
              Equals(Var("userRef"), Identity())
            )
          )
        ),
        write: true,
        create: true,
        delete: true,
        history_read: false,
        history_write: false,
        unrestricted_read: false
      }
    },
    {
      resource: Index("all_todos"),
      actions: {
        unrestricted_read: false,
        read: true
      }
    },
    {
      resource: Index("todos_by_completed_state"),
      actions: {
        unrestricted_read: false,
        read: true
      }
    },
    {
      resource: Index("users_by_email"),
      actions: {
        unrestricted_read: false,
        read: true
      }
    }
  ]
})
smithki commented 3 years ago

I would happily accept a PR to address this deprecation. @hichana I appreciate the initial research on your part. If the community can support us with the new implementation, we'll take care of updating the tutorial ASAP.