7.2. Server#

The server has a central function in the vantage6 architecture. It stores in the database which organizations, collaborations, users, etc. exist. It allows the users and nodes to authenticate and subsequently interact through the API the server hosts. Finally, it also communicates with authenticated nodes and users via the socketIO server that is run here.

7.2.1. Main server class#

vantage6.server.ServerApp#

class ServerApp(ctx)#

Vantage6 server instance.

Variables:

ctx (ServerContext) – Context object that contains the configuration of the server.

configure_api()#

Define global API output and its structure.

Return type:

None

configure_flask()#

Configure the Flask settings of the vantage6 server.

Return type:

None

configure_jwt()#

Configure JWT authentication.

load_resources()#

Import the modules containing API resources.

Return type:

None

setup_socket_connection()#

Setup a socket connection. If a message queue is defined, connect the socket to the message queue. Otherwise, use the default socketio settings.

Returns:

SocketIO object

Return type:

SocketIO

start()#

Start the server.

Before server is really started, some database settings are checked and (re)set where appropriate.

Return type:

None

7.2.2. Starting the server#

vantage6.server.run_server#

run_server(config, system_folders=True)#

Run a vantage6 server.

Parameters:
  • config (str) – Configuration file path

  • system_folders (bool) – Whether to use system or user folders. Default is True.

Returns:

A running instance of the vantage6 server

Return type:

ServerApp

Warning

Note that the run_server function is normally not used directly to start the server, but is used as utility function in places that start the server. The recommended way to start a server is using uWSGI as is done in v6 server start.

vantage6.server.run_dev_server#

run_dev_server(server_app, *args, **kwargs)#

Run a vantage6 development server (outside of a Docker container).

Parameters:

server_app (ServerApp) – Instance of a vantage6 server

Return type:

None

7.2.3. Permission management#

vantage6.server.model.rule.Scope#

class Scope(value)#

Enumerator of all available scopes

COLLABORATION = 'col'#
GLOBAL = 'glo'#
ORGANIZATION = 'org'#
OWN = 'own'#

vantage6.server.model.rule.Operation#

class Operation(value)#

Enumerator of all available operations

CREATE = 'c'#
DELETE = 'd'#
EDIT = 'e'#
RECEIVE = 'r'#
SEND = 's'#
VIEW = 'v'#

vantage6.server.model.permission.RuleCollection#

class RuleCollection(name)#

Class that tracks a set of all rules for a certain resource name

Parameters:

name (str) – Name of the resource endpoint (e.g. node, organization, user)

add(scope, operation)#

Add a rule to the rule collection

Parameters:
  • scope (Scope) – Scope within which to apply the rule

  • operation (Operation) – What operation the rule applies to

Return type:

None

can_for_col(operation, collaboration_id)#

Check if the user or node can perform the operation on a certain collaboration

Parameters:
  • operation (Operation) – Operation to check if allowed

  • collaboration_id (int | str) – Collaboration id on which the operation should be allowed. If a string is given, it will be converted to an int

Return type:

bool

can_for_org(operation, subject_org_id)#

Check if an operation is allowed on a certain organization

Parameters:
  • operation (Operation) – Operation to check if allowed

  • subject_org_id (int | str) – Organization id on which the operation should be allowed. If a string is given, it will be converted to an int

Returns:

True if the operation is allowed on the organization, False otherwise

Return type:

bool

get_max_scope(operation)#

Get the highest scope that the entity has for a certain operation

Parameters:

operation (Operation) – Operation to check

Returns:

Highest scope that the entity has for the operation. None if the entity has no permission for the operation

Return type:

Scope | None

has_at_least_scope(scope, operation)#

Check if the entity has at least a certain scope for a certain operation

Parameters:
  • scope (Scope) – Scope to check if the entity has at least

  • operation (Operation) – Operation to check

Returns:

True if the entity has at least the scope, False otherwise

Return type:

bool

vantage6.server.permission.PermissionManager#

class PermissionManager#

Loads the permissions and syncs rules in database with rules defined in the code

appender(name)#

Add a module’s rules to the rule collection

Parameters:

name (str) – The name of the module whose rules are to be registered

Returns:

A callable register_rule function

Return type:

Callable

assign_rule_to_container(resource, scope, operation)#

Assign a rule to the container role.

Parameters:
  • resource (str) – Resource that the rule applies to

  • scope (Scope) – Scope that the rule applies to

  • operation (Operation) – Operation that the rule applies to

Return type:

None

static assign_rule_to_fixed_role(fixedrole, resource, scope, operation)#

Attach a rule to a fixed role (not adjustable by users).

Parameters:
  • fixedrole (str) – Name of the fixed role that the rule should be added to

  • resource (str) – Resource that the rule applies to

  • scope (Scope) – Scope that the rule applies to

  • operation (Operation) – Operation that the rule applies to

Return type:

None

assign_rule_to_node(resource, scope, operation)#

Assign a rule to the Node role.

Parameters:
  • resource (str) – Resource that the rule applies to

  • scope (Scope) – Scope that the rule applies to

  • operation (Operation) – Operation that the rule applies to

Return type:

None

assign_rule_to_root(name, scope, operation)#

Assign a rule to the root role.

Return type:

None

resource: str

Resource that the rule applies to

scope: Scope

Scope that the rule applies to

operation: Operation

Operation that the rule applies to

check_user_rules(rules)#

Check if a user, node or container has all the rules in a list

Parameters:

rules (list[Rule]) – List of rules that user is checked to have

Returns:

Dict with a message which rule is missing, else None

Return type:

dict | None

collection(name)#

Get a RuleCollection object. If it doesn’t exist yet, it will be created.

Parameters:

name (str) – Name of the module whose RuleCollection is to be obtained or created

Returns:

The collection of rules belonging to the module name

Return type:

RuleCollection

load_rules_from_resources()#

Collect all permission rules from all registered API resources

Return type:

None

register_rule(resource, scope, operation, description=None, assign_to_node=False, assign_to_container=False)#

Register a permission rule in the database.

If a rule already exists, nothing is done. This rule can be used in API endpoints to determine if a user, node or container can do a certain operation in a certain scope.

Parameters:
  • resource (str) – API resource that the rule applies to

  • scope (Scope) – Scope of the rule

  • operation (Operation) – Operation of the rule

  • description (String, optional) – Human readable description where the rule is used for, by default None

  • assign_to_node (bool, optional) – Whether rule should be assigned to the node role or not. Default False

  • assign_to_container (bool, optional) – Whether rule should be assigned to the container role or not. Default False

Return type:

None

static rule_exists_in_db(name, scope, operation)#

Check if the rule exists in the DB.

Parameters:
  • name (str) – Name of the rule

  • scope (Scope) – Scope of the rule

  • operation (Operation) – Operation of the rule

Returns:

Whenever this rule exists in the database or not

Return type:

bool

7.2.4. Socket functionality#

vantage6.server.websockets.DefaultSocketNamespace#

class DefaultSocketNamespace(namespace=None)#

This is the default SocketIO namespace. It is used for all the long-running socket communication between the server and the clients. The clients of the socket connection are nodes and users.

When socket communication is received from one of the clients, the functions in this class are called to execute the corresponding action.

on_algorithm_status_change(data)#

An algorithm container has changed its status. This status change may be that the algorithm has finished, crashed, etc. Here we notify the collaboration of the change.

Parameters:

data (Dict) –

Dictionary containing parameters on the updated algorithm status. It should look as follows:

{
    # node_id where algorithm container was running
    "node_id": 1,
    # new status of algorithm container
    "status": "active",
    # result_id for which the algorithm was running
    "result_id": 1,
    # collaboration_id for which the algorithm was running
    "collaboration_id": 1
}

Return type:

None

on_connect()#

A new incoming connection request from a client.

New connections are authenticated using their JWT authorization token which is obtained from the REST API. A session is created for each connected client, and lives as long as the connection is active. Each client is assigned to rooms based on their permissions.

Nodes that are connecting are also set to status ‘online’.

Return type:

None

Note

Note that reconnecting clients are treated the same as new clients.

on_disconnect()#

Client that disconnects is removed from all rooms they were in.

If nodes disconnect, their status is also set to offline and users may be alerted to that. Also, any information on the node (e.g. configuration) is removed from the database.

Return type:

None

on_error(e)#

An receiving an error from a client, log it.

Parameters:

e (str) – Error message that is being displayed in the server log

Return type:

None

on_message(message)#

On receiving a message from a client, log it.

Parameters:

message (str) – Message that is going to be displayed in the server log

Return type:

None

on_node_info_update(node_config)#

A node sends information about its configuration and other properties. Store this in the database for the duration of the node’s session.

Parameters:

node_config (dict) – Dictionary containing the node’s configuration.

Return type:

None

on_ping()#

A client sends a ping to the server. The server detects who sent the ping and sets them as online.

Return type:

None

7.2.5. API endpoints#

Warning

The API endpoints are also documented on the /apidocs endpoint of the server (e.g. https://cotopaxi.vantage6.ai/apidocs). That documentation requires a different format than the one used here. We are therefore not including the API documentation here. Instead, we merely list the supporting functions and classes.

vantage6.server.resource#

class ServicesResources(socketio, mail, api, permissions, config)#

Flask resource base class.

Adds functionality like mail, socket, permissions and the api itself. Also adds common helper functions.

Variables:
  • socketio (SocketIO) – SocketIO instance

  • mail (Mail) – Mail instance

  • api (Api) – Api instance

  • permissions (PermissionManager) – Instance of class that manages permissions

  • config (dict) – Configuration dictionary

dump(page, schema)#

Dump based on the request context (to paginate or not)

Parameters:
  • page (Page) – Page object to dump

  • schema (HATEOASModelSchema) – Schema to use for dumping

Returns:

Dumped page

Return type:

dict

static is_included(field)#

Check that a field is included in the request argument context.

Parameters:

field (str) – Name of the field to check

Returns:

True if the field is included, False otherwise

Return type:

bool

static obtain_auth()#

Read authenticatable object or dict from the flask global context.

Returns:

Authenticatable object or dict. Authenticatable object is either a user or node. Dict is for a container.

Return type:

Union[db.Authenticatable, dict]

static obtain_auth_collaborations()#

Obtain the collaborations that the auth is part of.

Returns:

List of collaborations

Return type:

list[db.Collaboration]

classmethod obtain_auth_organization()#

Obtain the organization model from the auth that is logged in.

Returns:

Organization model

Return type:

db.Organization

static obtain_organization_id()#

Obtain the organization id from the auth that is logged in.

Returns:

Organization id

Return type:

int

response(page, schema)#

Prepare a valid HTTP OK response from a page object

Parameters:
  • page (Page) – Page object to dump

  • schema (HATEOASModelSchema) – Schema to use for dumping

Returns:

Tuple of (dumped page, HTTPStatus.OK, headers of the page)

Return type:

tuple

get_and_update_authenticatable_info(auth_id)#

Get user or node from ID and update last time seen online.

Parameters:

auth_id (int) – ID of the user or node

Returns:

User or node database model

Return type:

db.Authenticatable

get_org_ids_from_collabs(auth, collab_id=None)#

Get all organization ids from the collaborations the user or node is in.

Parameters:
  • auth (Authenticatable) – User or node

  • collab_id (int, optional) – Collaboration id. If given, only return the organization ids of this collaboration. If not given, return all organization ids of all collaborations the user or node is in.

Returns:

List of organization ids

Return type:

list[int]

only_for(types=('user', 'node', 'container'))#

JWT endpoint protection decorator

Parameters:

types (list[str]) – List of types that are allowed to access the endpoint. Possible types are ‘user’, ‘node’ and ‘container’.

Returns:

Decorator function that can be used to protect endpoints

Return type:

function

parse_datetime(dt=None, default=None)#

Utility function to parse a datetime string.

Parameters:
  • dt (str) – Datetime string

  • default (datetime) – Default datetime to return if dt is None

Returns:

Datetime object

Return type:

datetime

vantage6.server.resource.common.output_schema#

class HATEOASModelSchema(*args, **kwargs)#

This class is used to convert foreign-key fields to HATEOAS specification.

create_hateoas(name, obj, endpoint=None)#

Create a HATEOAS link to a related object.

Parameters:
  • name (str) – Name of the related resource

  • obj (Base) – SQLAlchemy resource to which the link is created

  • endpoint (str, optional) – Name of the endpoint to which the link is created, by default None. If None, the endpoint is assumed to be the same as the name of the related resource.

Returns:

HATEOAS link to the related object, or None if the related object does not exist.

Return type:

dict | None

meta_dump(pagination)#

Dump paginated database resources to a dictionary that has links to additional pages.

Parameters:

pagination (Pagination) – Paginated database resources

Returns:

Dictionary with paginated database resources and links to additional pages.

Return type:

dict

Create an API link to get objects related to a given object.

Parameters:
  • obj (Base) – Object to which the link is created

  • link_to (str) – Name of the resource to which the link is created

  • link_from (str) – Name of the resource from which the link is created

Returns:

API link

Return type:

str

Examples

>>> create_one_to_many_link(obj, "node", "organization_id")
"/api/node?organization_id=<obj.id>"

vantage6.server.resource.common.auth_helper#

create_qr_uri(user)#

Create the URI to generate a QR code for authenticator apps

Parameters:

user (User) – User for whom two-factor authentication is to be set up

Returns:

Dictionary with information on the TOTP secret required to generate a QR code or to enter it manually in an authenticator app

Return type:

dict

user_login(config, username, password, mail)#

Returns user a message in case of failed login attempt.

config: dict

Dictionary with configuration settings

username: str

Username of user to be logged in

password: str

Password of user to be logged in

mail: flask_mail.Mail

An instance of the Flask mail class. Used to send email to user in case of too many failed login attempts.

Return type:

tuple[dict | User, HTTPStatus]

Returns:

  • User or dict – User SQLAlchemy model if user is logged in, otherwise dictionary with error message

  • HTTPStatus – Status code that the current request should return

vantage6.server.resource.common.swagger_template#

This module contains the template for the OAS3 documentation of the API.

7.2.6. SQLAlchemy models#

vantage6.server.model.base#

This module contains a few base classes that are used by the other models.

class Database(*args, **kwargs)#

Database class that is used to connect to the database and create the database session.

The database is created as a singleton, so that it can be destroyed (as opposed to a module). This is especially useful when creating unit tests in which we want fresh databases every now and then.

add_col_to_table(column, table_cls)#

Database operation to add column to Table

Parameters:
  • column (Column) – The SQLAlchemy model column that is to be added

  • table_cls (Table) – The SQLAlchemy table to which the column is to be added

Return type:

None

add_missing_columns()#

Check database tables to see if columns are missing that are described in the SQLAlchemy models, and add the missing columns

Return type:

None

clear_data()#

Clear all data from the database.

close()#

Delete all tables and close the database connection. Only used for unit testing.

connect(uri='sqlite:////tmp/test.db', allow_drop_all=False)#

Connect to the database.

Parameters:
  • uri (str) – URI of the database. Defaults to a sqlite database in /tmp.

  • allow_drop_all (bool, optional) – If True, the database can be dropped. Defaults to False.

drop_all()#

Drop all tables in the database.

get_non_existing_columns(table_cls, table_name)#

Return a list of columns that are defined in the SQLAlchemy model, but are not present in the database

Parameters:
  • table_cls (Table) – The table that is evaluated

  • table_name (str) – The name of the table

Returns:

List of SQLAlchemy Column objects that are present in the model, but not in the database

Return type:

list[Column]

static is_column_missing(column, column_names, table_name)#

Check if column is missing in the table

Parameters:
  • column (Column) – The column that is evaluated

  • column_names (List[str]) – A list of all column names in the table

  • table_name (str) – The name of the table the column resides in

Returns:

True if column is not in the table or a parent table

Return type:

boolean

class DatabaseSessionManager#

Class to manage DB sessions.

There are 2 different ways a session can be obtained. Either a session used within a request or a session used elsewhere (e.g. socketIO event, iPython or within the application itself).

In case of the Flask request, the session is stored in the flask global g. Then, it can be accessed in every endpoint.

In all other cases the session is attached to the db module.

static clear_session()#

Clear the session. If we are in a flask request, the session is cleared from the flask global g. Otherwise, the session is removed from the db module.

Return type:

None

static get_session()#

Get a session. Creates a new session if none exists.

Returns:

A database session

Return type:

Session

static in_flask_request()#

Check if we are in a flask request.

Returns:

True if we are in a flask request, False otherwise

Return type:

boolean

static new_session()#

Create a new session. If we are in a flask request, the session is stored in the flask global g. Otherwise, the session is stored in the db module.

Return type:

None

class ModelBase#

Declarative base that defines default attributes. All data models inherit from this class.

delete()#

Delete the object from the database.

Return type:

None

classmethod exists(field, value)#

Check if a value exists for a given field in the database model.

Parameters:
  • field (str) – The field to check

  • value (Any) – The value to check

Returns:

True if the value exists, False otherwise

Return type:

bool

classmethod get(id_=None)#

Get a single object by its id, or a list of objects when no id is specified.

Parameters:

id (int, optional) – The id of the object to get. If not specified, return all.

classmethod help()#

Print a help message for the class.

Return type:

None

save()#

Save the object to the database.

Return type:

None

Database models for the API resources#

vantage6.server.model.algorithm_port.AlgorithmPort#

class AlgorithmPort(**kwargs)#

Table that describes which algorithms are reachable via which ports

Each algorithm with a VPN connection can claim multiple ports via the Dockerfile EXPOSE and LABEL commands. These claims are saved in this table. Each algorithm container belongs to a single Result.

Variables:
  • port (int) – The port number that is claimed by the algorithm

  • result_id (int) – The id of the Result that this port belongs to

  • label (str) – The label that is claimed by the algorithm

  • result (Result) – The Result that this port belongs to

vantage6.server.model.authenticatable.Authenticatable#

class Authenticatable(**kwargs)#

Parent table of database entities that can authenticate.

Entities that can authenticate are nodes and users. Containers can also authenticate but these are authenticated indirectly through the nodes.

static hash(secret)#

Hash a secret using bcrypt.

Parameters:

secret (str) – Secret to be hashed

Returns:

Hashed secret

Return type:

str

vantage6.server.model.collaboration.Collaboration#

class Collaboration(**kwargs)#

Table that describes which collaborations are available.

Collaborations are combinations of one or more organizations that do studies together. Each Organization has a Node for each collaboration that it is part of. Within a collaboration multiple Task can be executed.

Variables:
  • name (str) – Name of the collaboration

  • encrypted (bool) – Whether the collaboration is encrypted or not

  • organizations – list[Organization] List of organizations that are part of this collaboration

  • nodes (list[Node]) – List of nodes that are part of this collaboration

  • tasks (list[Task]) – List of tasks that are part of this collaboration

classmethod find_by_name(name)#

Find Collaboration by its name.

Parameters:

name (str) – Name of the collaboration

Returns:

Collaboration with the given name, or None if no collaboration with the given name exists.

Return type:

Union[Collaboration, None]

get_node_from_organization(organization)#

Returns the node that is part of the given Organization.

Parameters:

organization (Organization) – Organization to get node from

Returns:

Node for the given organization for this collaboration, or None if there is no node for the given organization.

Return type:

Node | None

get_nodes_from_organizations(ids)#

Returns a subset of nodes that are part of the given organizations.

Parameters:

ids (list[int]) – List of organization ids

Returns:

List of nodes that are part of the given organizations

Return type:

list[Node]

get_organization_ids()#

Returns a list of organization ids that are part of this collaboration.

Returns:

List of organization ids

Return type:

list[int]

get_task_ids()#

Returns a list of task ids that are part of this collaboration.

Returns:

List of task ids

Return type:

list[int]

vantage6.server.model.node.Node#

class Node(**kwargs)#

Bases: Authenticatable

Table that contains all registered nodes.

Variables:
  • id (int) – Primary key

  • name (str) – Name of the node

  • api_key (str) – API key of the node

  • collaboration (Collaboration) – Collaboration that the node belongs to

  • organization (Organization) – Organization that the node belongs to

check_key(key)#

Checks if the provided key matches the stored key.

Parameters:

key (str) – The key to check

Returns:

True if the provided key matches the stored key, False otherwise

Return type:

bool

classmethod exists_by_id(organization_id, collaboration_id)#

Check if a node exists for the given organization and collaboration.

Parameters:
  • organization_id (int) – The id of the organization

  • collaboration_id (int) – The id of the collaboration

Returns:

True if a node exists for the given organization and collaboration, False otherwise.

Return type:

bool

classmethod get_by_api_key(api_key)#

Returns Node based on the provided API key.

Parameters:

api_key (str) – The API key of the node to search for

Returns:

Returns the node if a node is associated with api_key, None if no node is associated with api_key.

Return type:

Node | None

classmethod get_online_nodes()#

Return nodes that currently have status ‘online’

Returns:

List of node models that are currently online

Return type:

list[Node]

vantage6.server.model.organization.Organization#

class Organization(**kwargs)#

Table that describes which organizations are available.

An organization is the legal entity that plays a central role in managing distributed tasks. Each organization contains a public key which other organizations can use to send encrypted messages that only this organization can read.

Variables:
  • name (str) – Name of the organization

  • domain (str) – Domain of the organization

  • address1 (str) – Address of the organization

  • address2 (str) – Address of the organization

  • zipcode (str) – Zipcode of the organization

  • country (str) – Country of the organization

  • _public_key (bytes) – Public key of the organization

  • collaborations – list[Collaboration] List of collaborations that this organization is part of

  • results (list[Run]) – List of results that are part of this organization

  • nodes (list[Node]) – List of nodes that are part of this organization

  • users (list[User]) – List of users that are part of this organization

  • tasks (list[Task]) – List of tasks that are created by this organization

  • roles (list[Role]) –

classmethod get_by_name(name)#

Returns the organization with the given name.

Parameters:

name (str) – Name of the organization

Returns:

Organization with the given name if it exists, otherwise None

Return type:

Organization | None

public_key#

Returns the public key of the organization.

Returns:

Public key of the organization. Empty string if no public key is set.

Return type:

str

vantage6.server.model.run.Run#

class Run(**kwargs)#

A Run is the description of a Task as executed by a Node.

The input and result fields will be encrypted and can be only read by the intended receiver of the message.

Variables:
  • input (str) – Input data of the task

  • task_id (int) – Id of the task that was executed

  • organization_id (int) – Id of the organization that executed the task

  • result (str) – Result of the task

  • assigned_at (datetime) – Time when the task was assigned to the node

  • started_at (datetime) – Time when the task was started

  • finished_at (datetime) – Time when the task was finished

  • status (str) – Status of the task

  • log (str) – Log of the task

  • task (Task) – Task that was executed

  • organization (Organization) – Organization that executed the task

  • ports (list[AlgorithmPort]) – List of ports that are part of this result

property node: Node#

Returns the node that is associated with this result.

Returns:

The node that is associated with this result.

Return type:

model.node.Node

vantage6.server.model.role.Role#

class Role(**kwargs)#

Collection of Rule permissions

Variables:
  • name (str) – Name of the role

  • description (str) – Description of the role

  • organization_id (int) – Id of the organization this role belongs to

  • rules (list[Rule]) – List of rules that belong to this role

  • organization (Organization) – Organization this role belongs to

  • users (list[User]) – List of users that belong to this role

classmethod get_by_name(name)#

Get a role by its name.

Parameters:

name (str) – Name of the role

Returns:

Role with the given name or None if no role with the given name exists

Return type:

Role | None

vantage6.server.model.rule.Rule#

class Rule(**kwargs)#

Rules to determine permissions in an API endpoint.

A rule gives access to a single type of action with a given operation, scope and resource on which it acts. Note that rules are defined on startup of the server, based on permissions defined in the endpoints. You cannot edit the rules in the database.

Variables:
  • name (str) – Name of the rule

  • operation (Operation) – Operation of the rule

  • scope (Scope) – Scope of the rule

  • description (str) – Description of the rule

  • roles (list[Role]) – Roles that have this rule

  • users (list[User]) – Users that have this rule

classmethod get_by_(name, scope, operation)#

Get a rule by its name, scope and operation.

Parameters:
  • name (str) – Name of the resource on which the rule acts, e.g. ‘node’

  • scope (str) – Scope of the rule, e.g. ‘organization’

  • operation (str) – Operation of the rule, e.g. ‘view’

Returns:

Rule with the given name, scope and operation or None if no rule with the given name, scope and operation exists

Return type:

Rule | None

vantage6.server.model.task.Task#

class Task(**kwargs)#

Table that describes all tasks.

A Task can create algorithm Runs for multiple organizations. The input of the task is different for each organization (due to the encryption). Therefore the input for the task is encrypted for each organization separately. The task originates from an organization to which the Runs need to be encrypted, therefore the originating organization is also logged

Variables:
  • name (str) – Name of the task

  • description (str) – Description of the task

  • image (str) – Name of the docker image that needs to be executed

  • collaboration_id (int) – Id of the collaboration that this task belongs to

  • run_id (int) – Run id of the task

  • parent_id (int) – Id of the parent task (if any)

  • database (str) – Name of the database that needs to be used for this task

  • init_org_id (int) – Id of the organization that created this task

  • init_user_id (int) – Id of the user that created this task

  • collaboration (Collaboration) – Collaboration that this task belongs to

  • parent (Task) – Parent task (if any)

  • results (list[Result]) – List of results that are part of this task

  • init_org (Organization) – Organization that created this task

  • init_user (User) – User that created this task

finished_at#

Determine the time at which a task was completed. This is the time at which the last algorithm run was completed.

Returns:

Time at which task was completed, None if task is not completed

Return type:

datetime.datetime | None

classmethod next_job_id()#

Get the next available run id for a new task.

Returns:

Next available run id

Return type:

int

vantage6.server.model.user.User#

class User(**kwargs)#

Bases: Authenticatable

Table to keep track of Users (persons) that can access the system.

Users always belong to an organization and can have certain rights within an organization.

Variables:
  • username (str) – Username of the user

  • password (str) – Password of the user

  • firstname (str) – First name of the user

  • lastname (str) – Last name of the user

  • email (str) – Email address of the user

  • organization_id (int) – Foreign key to the organization to which the user belongs

  • failed_login_attempts (int) – Number of failed login attempts

  • last_login_attempt (datetime.datetime) – Date and time of the last login attempt

  • otp_secret (str) – Secret key for one time passwords

  • organization (Organization) – Organization to which the user belongs

  • roles (list[Role]) – Roles that the user has

  • rules (list[Rule]) – Rules that the user has

  • created_tasks (list[Task]) – Tasks that the user has created

can(resource, scope, operation)#

Check if user is allowed to execute a certain action

Parameters:
  • resource (str) – The resource type on which the action is to be performed

  • scope (Scope) – The scope within which the user wants to perform an action

  • operation (Operation) – The operation a user wants to execute

Returns:

Whether or not user is allowed to execute the requested operation on the resource

Return type:

bool

check_password(pw)#

Check if the password is correct

Parameters:

pw (str) – Password to check

Returns:

Whether or not the password is correct

Return type:

bool

classmethod get_by_email(email)#

Get a user by their email

Parameters:

email (str) – Email of the user

Returns:

User with the given email

Return type:

User

Raises:

NoResultFound – If no user with the given email exists

classmethod get_by_username(username)#

Get a user by their username

Parameters:

username (str) – Username of the user

Returns:

User with the given username

Return type:

User

Raises:

NoResultFound – If no user with the given username exists

classmethod get_first_user()#

Get a random user by their username.

This function is used to prevent an attacker from finding out which usernames exist.

Returns:

A random user that is in the database

Return type:

User

is_blocked(max_failed_attempts, inactivation_in_minutes)#

Check if user can login or if they are temporarily blocked because they entered a wrong password too often

Parameters:
  • max_failed_attempts (int) – Maximum number of attempts to login before temporary deactivation

  • inactivation_in_minutes (int) – How many minutes an account is deactivated

Return type:

tuple[bool, Optional[int]]

Returns:

  • bool – Whether or not user is blocked temporarily

  • int | None – How many minutes user is still blocked for

set_password(pw)#

Set the password of the current user. This function doesn’t save the new password to the database

Parameters:

pw (str) – The new password

Returns:

If the new password fails to pass the checks, a message is returned. Else, none is returned

Return type:

str | None

classmethod username_exists(username)#

Check if a user with the given username exists

Parameters:

username (str) – Username to check

Returns:

Whether or not a user with the given username exists

Return type:

bool

7.2.7. Database utility functions#

vantage6.server.db#

jsonable(value)#

Convert a (list of) SQLAlchemy instance(s) to native Python objects.

Parameters:

value (list[Base] | Base) – A single SQLAlchemy instance or a list of SQLAlchemy instances

Returns:

A single Python object or a list of Python objects

Return type:

list | dict

Raises:

Exception – If the value is not an instance of db.Base or a list of db.Base

7.2.8. Mail service#

vantage6.server.mail_service#

class MailService(app, mail)#

Send emails from the service email account

Parameters:
  • app (flask.Flask) – The vantage6 flask application

  • mail (flask_mail.Mail) – An instance of the Flask mail class

send_email(subject, sender, recipients, text_body, html_body)#

Send an email.

This is used for service emails, e.g. to help users reset their password.

Parameters:
  • subject (str) – Subject of the email

  • sender (str) – Email address of the sender

  • recipients (List[str]) – List of email addresses of recipients

  • text_body (str) – Email body in plain text

  • html_body (str) – Email body in HTML

Return type:

None

7.2.9. Default roles#

vantage6.server.default_roles#

get_default_roles(db)#

Get a list containing the default roles and their rules, so that they may be created in the database

Parameters:

db – The vantage6.server.db module

Returns:

A list with dictionaries that each describe one of the roles. Each role dictionary contains the following:

name: str

Name of the role

description: str

Description of the role

rules: List[int]

A list of rule id’s that the role contains

Return type:

List[Dict]

7.2.10. Custom server exceptions#

vantage6.server.exceptions#

exception VPNConfigException#

Exception raised when the server admin provides invalid VPN configuration.

exception VPNPortalAuthException#

Exception raised when the authentication with the VPN portal fails.