Role-based UDF call works in dashboard but not query from site despite correct token

Hi there,

I built a site in v4 and have been migrating to v10. To start, I rewrote all my queries in FQL10 in a test database. Once everything was working, I added the v10 queries to the live (originally v4) DB with a new naming convention and continued testing.

The issue I’m encountering in the live DB is, I believe, some sort of role/access conflict, where despite having the proper token and role/access configuration, queries are throwing “insufficient privileges” errors ONLY in the live DB. If I call the relevant UDFs from the Dashboard with the proper role set, everything works. If I call the functions from the test DB, which is configured identically and running on the same code except pointing at a different DB, everything works.

All this leads me to wonder if there’s some conflict between the old (still-present) set of Roles in the live DB and the new ones I’ve added for FQL 10. I event tried experimentally disabling collection membership in the old Roles, but so far that hasn’t worked either.

If the errors were cropping up in more than just this specific use-case I’d be certain I was just screwing something up, but at the moment I’m at a loss at to how to proceed.

Any advice on how to resolve this would be much appreciated. I’ve combed the forums a bit but haven’t seen any similar issues.

Thanks!

bryan

Hi @ottomaddox and welcome! :wave:

It sounds like you wrote new Roles using v10 in the dev database, but are still using the original Roles in prod which were written in v4, is that correct?

If so let’s compare those Roles side by side. Can you share the old and new definitions here?

Please also share the v4 query which works and the v10 query which fails so we can compare that too.

1 Like

Hey, thanks so much for the welcome and quick reply!

To clarify, I wrote new Roles using v10 in the dev database, then added those rules to the prod database when I added the new v10 functions. My issue occurs when I try to query the prod database with the v10 UDFs via the accompanying v10 Role. Queries on the dev database work as expected, and v4 queries/Roles on the prod database work as well.

(Perhaps notably, I can query the prod database with v10 UDFs if the associated Role doesn’t have a membership property (i.e. by using the @role header in the UDF)).

My “AuthUser” Role in v4 looked like this:

{
  ref: Role("AuthRole"),
  ts: 1706371540620000,
  name: "AuthRole",
  privileges: [
    {
      resource: Collection("User"),
      actions: {
        read: true,
        write: false,
        create: false,
        delete: false,
        history_read: false,
        history_write: false,
        unrestricted_read: false
      }
    },
    {
      resource: Ref(Ref("functions"), "UserAccountExists"),
      actions: {
        call: true
      }
    },
    {
      resource: Index("findUserByEmail"),
      actions: {
        unrestricted_read: false,
        read: true
      }
    },
    {
      resource: Index("eventProfile_user_by_user"),
      actions: {
        unrestricted_read: false,
        read: true
      }
    },
    {
      resource: Collection("EventProfile"),
      actions: {
        read: true,
        write: false,
        create: false,
        delete: false,
        history_read: false,
        history_write: false,
        unrestricted_read: false
      }
    },
    {
      resource: Ref(Ref("functions"), "UserEventExists"),
      actions: {
        call: true
      }
    },
    {
      resource: Ref(Ref("functions"), "UserEventPaymentExists"),
      actions: {
        call: true
      }
    },
    {
      resource: Ref(Ref("functions"), "CreateUserEventProfile"),
      actions: {
        call: true
      }
    },
    {
      resource: Ref(Ref("functions"), "UpdateUserEventProfile"),
      actions: {
        call: true
      }
    },
    {
      resource: Index("eventProfileByUserAndEvent"),
      actions: {
        unrestricted_read: false,
        read: true
      }
    }
  ],
  membership: [
    {
      resource: Collection("User")
    }
  ]
}

The corresponding Role in the dev database, which I also migrated to the prod database once it was working, looks like this:

role AuthUserFQL {
  privileges User {
    read
  }
  privileges EventProfile {
    read
    write
  }
  privileges UpdateUserEventProfileFQL {
    call
  }
  privileges UserExistsFQL {
    call
  }
  privileges ToggleEventAttendeeFQL {
    call
  }
  membership User
}

You’ll note I’m calling UDFs with the “FQL” suffix in the v10 Role; these are the new v10 functions I migrated to the prod database. I added the extra string so I wouldn’t have to overwrite my existing v4 functions.

Hope this gives sufficient context; happy to send along more code if it helps illuminate my issue!

Thanks again,

b

Sorry, added a reply with my UDF code but I think maybe the spam filter hid it!

Here’s the v4 function I used to create an EventProfile and associate it with a User (apologies in advance for the rubbish code, I’m learning as I go!):

Query(
  Lambda(
    ["email", "event", "payment"],
    Let(
      {
        ref: Select(0, Paginate(Match(Index("findUserByEmail"), Var("email")))),
        user: Get(Var("ref")),
        eventExists: Call("UserEventExists", [Var("email"), Var("event")]),
        update: If(
          Not(Equals(Var("eventExists"), -1)),
          Update(Var("eventExists"), {
            data: {
              event: Var("event"),
              payment: Var("payment"),
              user: Var("ref"),
              phone: "",
              pronouns: "",
              photo: false,
              diet: "",
              access: "",
              attending: true
            }
          }),
          Let(
            {
              newEvent: Create("EventProfile", {
                data: {
                  event: Var("event"),
                  payment: Var("payment"),
                  user: Var("ref"),
                  phone: "",
                  pronouns: "",
                  photo: false,
                  diet: "",
                  access: "",
                  attending: true
                }
              }),
              newArray: Append(
                Select("ref", Var("newEvent")),
                Select("events", Select("data", Var("user")))
              ),
              update: Update(Var("ref"), { data: { events: Var("newArray") } })
            },
            Var("user")
          )
        )
      },
      Var("user")
    )
  )
)

and here’s the corresponding v10 UDF

function CreateUserEventFQL(email, event, payment) {
  let user = User.byEmail(email).first();
  user?.update({events:user?.events.filter(doc=>doc.event != event)});
  DeleteEventAttendeeFQL(email, event);
  let newEvent = EventProfile.create({
    event: event,
    payment: payment,
    user: user,
    phone: "",
    pronouns: "",
    photo: false,
    diet: "",
    access: "",
    attending: true,
    how: -1
  })
  user?.update({events:user?.events.append(newEvent)});
  newEvent;
}

Thanks again!

b

Sorry about the spam filter. One of the metrics it uses is new accounts writing a lot of posts quickly. In this case, lots of engagement is a good thing! :smiling_face:

I can replicate the issue. It appears that when there is something about the v4 role that is preventing the v10 role from being used. I am forwarding the issue to our engineers.

Fauna Roles, whether created in v4 or v10 are (supposed to be) all additive. The default is “no permissions” and each Role essentially adds to one big allow-list. All that is to say, there should not be any conflicts between your v4 roles and v10 roles.

1 Like

No worries at all, and thanks again for the quick response. OK, good to know there may be an issue beyond my control. I appreciate you forwarding to engineering; I’ll let the folks I’m working for know and standby for an update!

b

Morning @ptpaterson! Any update on this issue? As an alternative short-term solution, is your sense that deleting the v4 roles will resolve the conflict with the new v10 roles?

Thanks so much!

b

Hi @ottomaddox. We have confirmed the issue and have an internal ticket to track and prioritize it. It’s on the list to get done, but I can’t say precisely when that would be.

I can confirm, however, that if you remove the v4 roles that share the same membership, the v10 roles should take effect immediately. You should also be able to add the v4 UDFs to the v10 Roles, so any workflows still using v4 can continue once the v4 Roles are removed.

1 Like

Great, thanks @ptpaterson , this is helpful to know! Being able to test with the v4 and v10 roles both in place is primarily a failsafe during migration, so I can probably make replacing the v4 roles outright work with a bit of database downtime.

Appreciate the help and follow-up; please do update if you can if/when the underlying issue is resolved.

b

Hi @ottomaddox This issue should now be fixed.

2 Likes

Could we please get an updated docker image version with this fix?

Thanks!

Confirming the issue is now fixed for my use case. Thanks again @ptpaterson for the support and followup!

bryan

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.