[App Server] Inject a user at deployment time

Hello all.

I am deploying my Anvil App to Azure using the OS runtime.

My app requires login, but it won’t allow people to sign up because of data privileges. I am wondering what is the easiest way to inject an admin user/password at deployment to ensure the new DB has at least one user, and then I can log in and start adding user from the admin CRUD app.

I assume using the psql command line, but the DB schema is quite unique.

Thank you in advance.

Best. Anders.

One possibility might be to have a server side module that is run when the app is booted up for the first time, and injects a user specified with secrets module.

I am thinking something along these lines — in a startup.py server module:

import anvil.server
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables

if app_tables.users.search() is None:
    app_tables.users.add_row(username = anvil.secrets.get_secret("admin_username"), password = anvil.secrets.get_secret("admin_password")

I would suggest setting an --uplink-key when launching the App Server, and having your startup script connect and run its initialisation via the Uplink.

You can find a reference for the uplink-key option, plus the URL to pass to anvil.server.connect(), in that section of the App Server docs :slight_smile:

3 Likes

Thank you @meredydd. I will give that a go… Seems like a sensible idea.

Right now, I am struggling with getting the Users table to be generated (https://github.com/anvil-works/anvil-runtime/issues/9). I am sure I am missing something obvious.

I’ll report back as soon as I have something working.

Now that I have the users table working, the following has worked for me by including it it as a Server module:

import anvil.server
import anvil.tables as tables
import anvil.tables.query as q
from anvil.tables import app_tables
import anvil.users
import bcrypt

print("Starting up TestApp")
if len(app_tables.users.search()) == 0:
    print("Adding admin user")
    password = bcrypt.hashpw("my_password".encode(), bcrypt.gensalt()).decode('utf-8')
    app_tables.users.add_row(email="my_email@example.com", password_hash=password, enabled=True, role='admin', organisation='my_org')
    #quick test to see if it is possible to login. i would remove this from production
    user = anvil.users.login_with_email("my_email@example.com", "my_password")

It runs when I first try to load up the page.

I’ll now re-factor it to your suggestion, @meredydd, and use an uplink.

Thank you.