Anvil Documentation Suggestions [ON-GOING]

1 Like

I think the code suggests this usage is actually deprecated, but I could be wrong:

Thanks! I’ll refrain from making such calls, then, until we get an official statement one way or the other.

I think there needs to be a big disclaimer on the User Management page that explains that any data retrievable by the anvil.users.get_user() method is ALWAYS readable on the client side. Essentially, any authenticated user can access all data in and linked from their user row.

This is regardless of the permissions set for the Users table.

Perhaps a starting point:

Security

The built in method anvil.users.get_user() makes an authenticated server side call to the users table and returns their row to the client. Because of this, any data stored in, or linked from, the users table should always be considered accessible by the authenticated user.

Anything that is accessible from anvil.server.get_user() is always accessible on the client side regardless of the table’s Client code access permission.

When adding columns or linking to other tables from the users table, consider what you are exposing to a bad actor.

Example:

You are building a messaging app that allows user’s to select friends and also block other users. You setup two additional columns in your users table for blocked and friends that allow multiple linked rows to the users table.

Our bad actor starts looking at their row and notices the blocked and friends fields. Perhaps they can add a user Jeff to their blocked list and now have access to this examples entire users table by traversing the linked rows.

Here is the example of data leaking client side:
User Table Data Leakage

4 Likes

Determining Published vs Debug Environments

There seems to be some bad information on how to determine if an environment is running as a debug environment or published environment. From the information in the docs as well as the IDE documentation helper:

determining if the code is executed in the published environment should be app.branch == 'published'. However, this is only true if:

  1. You create a published branch
  2. You select the Publish 'published' branch option
    • Note: You can not use the Publish this commit option
  3. You never use the published branch for development.

This matches the documentation in production-vs-development (looks like maybe a legacy page?):

if app.branch != 'published':
    print("Dev version of the app has been accessed")

which is also wrong in most cases.

The documentation in Environments and Code is different and may need some additional information added for non-business versions which seem to use Published rather than Production in app.environment.name. But someone would need to verify that as I’m not on a business account (yet).

1 Like

Hi @racersmith,

The production-vs-development page you’ve linked to is part of the Classic Editor docs and so is not valid for the new Editor. The Classic Editor will be deprecated soon and those docs will go away too, which should hopefully remove some confusion. I will add an issue internally to make the Environments and Code page more clear.

2 Likes

Please redesign the search engine for the documentation.

I knew that searching the documentation for words with an underscore like in_designer doesn’t work, which is a pretty big problem when you deal with software APIs.

I now found out that searching for normal English words that appear in the title doesn’t work either. For example, searching for custom components doesn’t find this page that has the two words in the title and it’s the main documentation for custom components: Creating Custom Components

5 Likes

Also, searching the “Need help? Find answers here” from the Help page inside an app and the field inside the docs page need a filter to search for type of content.

More often than not I see myself scrolling down the results a lot so I can find the answer I want because pages for API, Blog or Tutorial keep getting precedence instead of Docs or Forum.

2 Likes
2 Likes

[Minor] Model Classes

Table name

In the To Do example in the Create Model Classes page, the server module code uses app_tables.todos.search(... rather than app_tables.todo_items.search(...

from . import Module1

class TodoItem(Module1.TodoItem):
  @server_method(require_user=True)
  @classmethod
  def get_my_todos(cls):
    me = anvil.users.get_user()
-   return app_tables.todos.search(assigned_user=me)
                      ^^^^^
+   return app_tables.todo_items.search(assigned_user=me)

Method name

On the Making a model client-writable page,

- ... you’ll want to override `do_update()` to check ...
                               ^
+ ... you’ll want to override `_do_update()` to check ...

(self, …) to (row, …)?

With how Model Classes work, I wonder if using row rather than self would make usage more clear?

Throws a missing column error:
self._last_value = 123 … Odd
row._last_value = 123 … Duh

@server_method is required for:
self.datetime = now … What, why?
row.datetime = now … Client does not have permission to write to tables.

self['datetime'] … What Tomfoolery is this?
row['datetime'] … Did not bat an eye

class TodoItem(app_tables.todo_items.Row):
  @property
  def is_overdue(self):
    return datetime.now() > self["due_date"]

vs.

class TodoItem(app_tables.todo_items.Row):
  @property
  def is_overdue(row):
    return datetime.now() > row["due_date"]

Nothing looks concerning here at first glance:

class TodoItem(app_tables.todo_items.Row, attrs=True):
  @anvil.server.server_method
  def enable_magic(self):
    self.magic = True

While if I got an error here about magic not being a column, it makes sense:

class TodoItem(app_tables.todo_items.Row, attrs=True):
  @anvil.server.server_method
  def enable_magic(row):
    row.magic = True

What do smarter people think?

1 Like