Routing new users to either Admin form or User Form

** I created two different forms (form1admin for admin, and form2users for regular users). How do I route newly create users to the right form? Is there a proper way of doing this? **

Here is an example:
A new user creates a login and I enable it as Admin from my end in the data tables.
Another user creates a login and I enabled their account as a User. How do I tell the system to show one form to USER and a different view/form to Admin?

I am really looking for guidance and direction here.

Clone link:
https://anvil.works/build#clone:7PQA74TNYLACI2ZV=DB3SWYS2PG3AIG6UCPAWNU64

The basic idea is you use the information in your data tables to make the decision. For example, I have a boolean column in my Users table named admin. So when I need to make the decision, I use something like:

user = anvil.users.get_user()

if user['admin']:
  show_admin_form()
else:
  show_user_form()

That makes sense. Thank you for the idea.

show_user_form() Is that how you reference the form? Part of the problem for me was that I didn’t know how to reference a specific form.

My mind into all sorts of routing situations which was the complex.

Your simple if statement will work

This is where it starts to get a little more complicated. The easy, plain Anvil, answer is the open_form function described in the docs: Anvil Docs | Navigation

The more complicated answer is to use the Anvil Extras routing module to do your routing. It has a ton of features, including giving each form a distinct URL, so users can bookmark a particular form, automatic caching of forms, near-automatic handling of making sure users are logged in with the correct permissions, etc.

But setting up an app for Anvil Extras routing is more complicated. Here’s a sample app that uses it: Anvil | Login

You can get more information about Anvil Extras at the github page: GitHub - anvilistas/anvil-extras

1 Like

Morning,

If you are a bit security conscious like me, you’ll bury part of the redirect in server code.

So, you can add a role column to your Users table, then on your client side something like:

a = anvil.server.call('vet')`
open_form(a)

Then over in your server code:

@anvil.server.callable
def vet():
   role = anvil.users.get_user()['role']
   if role == "Admin":
      a = "AdminForm"
   elif role == "User":
      a = "UserForm"
   else:
      a = "NoCredsForm"
   return a

At least that’s what my brain has done, I can’t vouch for the underlying sanity.

1 Like

Unfortunately this won’t offer any additional security. Any determined person can get through this easily. An additional server call will also slow down your app.

As has been discussed many times on the forum, there’s simply no way for you to prevent access to a particular form. Instead validate all calls to server.

2 Likes

So I used your example to create a boolean in my data table named “Admin” (true/false).

I used the code below. I placed a checkmark under my user so I should be admin. So, in theory, its suppose to only show the admin page, however, it is showing first the admin page, then the employee page. What am I missing?

 user = anvil.users.get_user()
    if user['Admin']:
        open_form('admin_haga_system')
    else:
        open_form('employee_haga_system')

Clone link:

Anvil | Login

It’s been a long day, but do you not need: if user[‘Admin’] is True:

Thank you James. But that makes me even more confused. How will it check the data table without
if user[‘Admin’] is true

If I comment that out, it won’t be an if/else statement right? Sorry, it might be a dumb question, but I am still new at this.

Python is fine with if user['Admin']:, you do not need to specifically compare it to True or False. The use in a conditional implies a comparison with True.

Also, be careful when copying code from the forum. Anything not between backticks will have quotes messed up, which is what happened with your syntax error.

You have the code to change the form inside the __init__ method. open_form doesn’t work well inside __init__. Try putting the code into a form_show event handler instead.

Edit: or, you can put the code into a startup module, instead of a startup form. That way no form gets initially shown.

It still shows the admin page first and then users for me, so it did not fix the issue.

At a loss for you, never had the issue and can’t see a logical reason why it would happen. Looked at your clone link and can only think you should use a form_show event as @jshaffstall says. Over time I’ve developed an uncouth preference for roles rather than bools for admin, so tend to stick to explicit truths in code - makes it easier to deal with “Truthy” values but drives other devs to distraction when they see it.

1 Like

You have the code to change the form inside the __init__ method. open_form doesn’t work well inside __init__ . Try putting the code into a form_show event handler instead.

I think this is what you meant right?

image

If so, I added the code in the function form_show

  def form_show(self, **event_args):
    user = anvil.users.get_user()
    if user['Admin']:
      open_form('admin_haga_system')
    else:
      open_form('employee_haga_system')

At this point though, it shows the correct form page ‘admin_haga_system’ only after it shows ‘employee_haga_system’ . I think it is because the form_show() is in my main form. Do you agree? How do I make it run this argument right after the login and before the main app loads? I think that might be the issue.

Thank you for trying to help :slight_smile: Appreciate you taking a look at it.

Just use a blank landing as your start form, triggering form show after the login and that ought to do it.

Since Anvil added the ability to have startup modules, you could also use one of those instead of having a blank form whose only purpose is to be shown briefly. Either a startup module or blank startup form will have the same effect.

3 Likes

in case it would be 3 roles, using a text type colum instead of a boolean colum in the users table with the ‘admin’ ‘office’ and ‘user’ roles, how should i do it?

Exactly the same way? Use an if statement in a startup module/form that opens the appropriate other form based on the contents of the text column.

I have 3 forms for the 3 type of users, so i made an admin colum and an office colum, should i do something like this?

user = anvil.users.get_user()
if user[‘admin’]:
open_form(‘registro_listocar’)
else:
if user[‘office’]:
open_form(‘registro_listocar_office’)
else:
open_form(‘registro_listocar_user’)

Put your code between backticks, e.g. ``` and it will preserve the indentation that is critical to understanding Python code.

But in general, yes, that’s what you want to do.