Backend Introduction

Overall System Architecture

1515

overall design link - same as above

Session concept

In general, a session refers to a database session. A user or auth session is also sometimes available in some contexts, but most of the time session means an SQL Alchemy session.

Backend data objects

For example consider a user object
Each thing is an SQL Alchemy object.
for example you can do user = User.get(session) or something like that (check exact syntax)

When possible use python annotations on method arguments to specify the specific class like user : User

Current User assumptions

Getting the current user is handled automatically by abstractions, like the user = User.get(session).
If the user's auth is invalid then this will return None.

Mocking objects

If you are using something like postman, then for a user you need to mock the cookie.

The two Auth mechanisms.

  1. For The API & SDK. We use Basic Auth, In this case the username password is the api token and api secret key.
  2. Now for the normal frontend user requests we use a cookie session, which is created in the login route. You can see the code for that in login.py file, specifically setSecureCookie

The cookie based approach helps us set a secure value so the password is never stored as plain text. It also works smoothly with normal flask concepts.

Getting objects

Most objects implement a .get_by_id() method or similar.
Always consider the permission context anytime you are getting an object. Many internal functions assume auth has already been validated.

❗️

Always consider the permission context anytime you are getting an object.

Many internal functions assume auth has already been validated.

In some cases there are dedicated permissions concepts built in to get() methods.

Permissions

See data scope intro this diagram talks about the permissions. The project permission is the most well developed and used. The job permission is also fairly extensive. The permission cascade hierarchy is:

Org > Project > Job > Task

Most of the permissions use API route level decorators.

🚧

Beware - even a properly decorated route does not guarantee child objects are valid

For example, I send a valid project ID, but then in a JSON payload include an invalid job/label/file id. Usually at a high level this means that things we build based strictly on the project id are valid. But any other objects a user supplies are untrusted until verified. A good example is File.get_by_id_and_project() which has the Security model that if the file matches the project (assumes that project_id is trusted), then the file has permission to return. Practically this means a new route can be constructed by using the project decorator, and then this function called easily.

πŸ“˜

Serialize() methods must never jump a permissions scope

For example, job.serialize() must not include sensitive information from project. Imagine for example job.serialize() having a project key, which then calls job_list, and would inadvertently serialize all jobs in the project hidden inside the original job.