View Source VacEngine.Account (Vac Engine v1.1.1)

Rsponsible for the management of a role-based permission system.

Roles

Primary entities to which permissions can be attached. Identification to a specific role can be done by using either a full authentication or through a token passed with the request.

Roles can be acquired by two access types: users and api-keys.

Users

User access allow people to access the web interface of the application.

A user can access the application by using a multi-factor authentication with:

  • an email login
  • a password
  • a one-time password provided by an authenticator

User is attached to a single role, to which a set of permissions is granted.

Api-keys

Api-keys accesses are used by api consumers to call the application api.

A api-key can access the application by using a token that contain a password and a reference to the role. If an existing token is provided with an api request in the authentication header, the request is automatically associated with the related role and permissions are granted accordingly.

Curl example of api call with key:

curl https://example.com/api/p/8/run -X POST       -H "Authorization: Bearer api_1234567_123456789012345678901234567890"

Permissions

Granting permission

Permissions are rights to do certain actions in the system. A permission is granted to a role to perform a given in a given scope, by using the grant_permission/3 (or toggle_permission/3) function:

VacEngine.Account.grant_permission(target_role, :list_blueprints_action, :global)

Checking permission

When a piece of code should only be accessed by roles with defined permission, an conditional block containing the can?/3 function should be added.

if can?(role, :access, :editor) do
  ...
end

The function will return true if and only if the current role has the corresponding permission therefore granting access or not to the included code.

Actions

Actions are atoms describing a specific action. The exact content of the action is defined by the places where can?/3 functions use it as an argument.

Scopes

A scope determines a context in which a permission is granted. There is three types of scope in the application, the global scope, the worspace scopes and the custom.

Global scope

The global scope correspond to the whole application. Therefore permissions granted in the global scope are technically "unscoped".

Global scope is designated by the :global atom.

Workspace scope

A workspace scope is determined by the id of a workspace and grants the rights in the context of this workspace. For example, an :access action permission in the workspace with :id = 1 will grant access only to this workspace.

Workspace scopes are designated a tuple containing the :workspace atom and the id of the workspace, e.g.:

{:workspace, 2}

Custom scope

Other scopes can be created using a custom atom.

Schemas

Below, the list of the schemas described in the Account module.

AccessToken

Access tokens can be:

  • API key
  • link token (not implemented yet)
  • oauth refresh token (not implemented yet)
  • oauth access token (not implemented yet)

Secret format vary depending of the type

BlueprintPermission

A blueprint permission gives a permission on a blueprint to a role.

GlobalPermission

A global permission gives a site wide permission to a role.

WorkspacePermission

A workspace permissions give a workspace wide permission to a role.

Role

A role is the representation of an actor (user, api request...) to which permissions can be attached.

Session

A session is created every time a user log in and bears the user's permissions.

If the permissions change, the session must be recreated for the change to take effect.

User

A user is a login method for a role of type "user".

Workspace

The general container for blueprints and portals.

Security design

The Account module implements the following principe in order to ensure security of the system:

  • Users are authenticated using MFA (login/password + authentication).
  • Treatment of wrong login/password pairs are treated in constant time.
  • Sessions linked to role of all types (api-keys, users, tokens) can be revocated by admin at any time.
  • Only admins have the right to publish a blueprint on a portal so that no simple editor can influence the behaviour of the api.

Link to this section Summary

Functions

Activate a role

Bust role cache

Check action against role with scope.

Cast attributes into a changeset

Cast attributes into a changeset

Cast attributes into a changeset

Check a email/password and return the user if both are valid (used for login)

Create an access token as API for a given role

Create permissions for scope

Create a role with attributes

Create a session with attributes

Create a user with attributes

Create a workspace with attributes

Desactivate a role.

Delete all permissions for scope

Delete role

Delete workspace.

Try to find a session with given token

Filter available workspaces for a given role

Filter active role

Filter inactive since n seconds

Filter role by type

Generate a new TOTP url for the given user. Return a {url, secret} tuple.

Generate a secret with a prefix and id.

Generates a human friendly secret of length bytes long.

Get a role with id, raise if not found.

Get a session with id, raise if not found.

Get a user with id, raise if not found.

Get a workspace with id, raise if not found.

Grant permission with an action and scope

Check action against role with scope.

Check permission directly without infer

List API keys with portal access for cached API access

Return all API tokens

Return all users with last_login_at and last_active_at virtual fields populated

List all workspaces

Load te api_tokens assoc of a given role

Load all permission assoc with scope (workspace, portal, blueprint)

Load all permission assoc

Load session assoc

Preload user activity

Load role assoc

Load blueprints assoc

Load blueprint_count and active_publication_count

Revoke permission with an action and scope

Revoke session

Toggle permission with an action and scope

Set session last activity time to now

Update role with attributes

Update session with attributes

Update user with attributes. This will cast all user attributes and should only be called from an admin context.

Update workspace with attributes

Link to this section Functions

Activate a role

Bust role cache

Link to this function

can?(role, action, scope \\ :global)

View Source

Check action against role with scope.

Link to this function

change_role(role, attrs \\ %{})

View Source

Cast attributes into a changeset

Link to this function

change_user(data, attrs \\ %{})

View Source

Cast attributes into a changeset

Link to this function

change_workspace(data, attrs \\ %{})

View Source

Cast attributes into a changeset

Link to this function

check_user(email, password)

View Source

Check a email/password and return the user if both are valid (used for login)

If the password is nil or wrong or the user not found, the time for the check will be constant.

Link to this function

create_api_token(role, test \\ false)

View Source

Create an access token as API for a given role

Link to this function

create_permissions(role, scope)

View Source

Create permissions for scope

Link to this function

create_role(type, attrs \\ %{})

View Source

Create a role with attributes

Link to this function

create_session(role, attrs)

View Source

Create a session with attributes

Create a user with attributes

This will also create the "role" for the user and set it as active

Create a workspace with attributes

Desactivate a role.

Will revoke all sessions.

This will NOT disconnect live views, this is the responsibility of the web layer.

Link to this function

delete_permissions(role, scope)

View Source

Delete all permissions for scope

Delete role

Delete workspace.

This will fail is the workspace has any blueprint or portal

Link to this function

explode_composite_secret(secret)

View Source

Explode a secret.

iex> sec = generate_composite_secret(:role, 23)
...> %{id: 23, prefix: "role", secret: _} = explode_composite_secret(sec)

Try to find a session with given token

Link to this function

filter_accessible_workspaces(query, role)

View Source

Filter available workspaces for a given role

Link to this function

filter_active_roles(query)

View Source

Filter active role

Link to this function

filter_inactive_sessions(query, duration_sec)

View Source

Filter inactive since n seconds

Link to this function

filter_roles_by_type(query, type)

View Source

Filter role by type

Generate a new TOTP url for the given user. Return a {url, secret} tuple.

Link to this function

generate_composite_secret(prefix, id)

View Source

Generate a secret with a prefix and id.

Link to this function

generate_secret(length \\ 16)

View Source

Generates a human friendly secret of length bytes long.

Length must be multiple of 4.

Crypto secure.

Link to this function

get_role!(id, queries \\ &(&1))

View Source

Get a role with id, raise if not found.

Get a session with id, raise if not found.

Link to this function

get_user!(uid, queries \\ &(&1))

View Source

Get a user with id, raise if not found.

Link to this function

get_workspace!(id, queries \\ &(&1))

View Source

Get a workspace with id, raise if not found.

Link to this function

grant_permission(role, action, scope \\ :global)

View Source

Grant permission with an action and scope

Link to this function

has?(role, action, scope \\ :global)

View Source

Check action against role with scope.

Link to this function

has_permission?(role, action, scope \\ :global)

View Source

Check permission directly without infer

List API keys with portal access for cached API access

Link to this function

list_api_tokens(queries \\ &(&1))

View Source

Return all API tokens

Link to this function

list_roles(queries \\ &(&1))

View Source

List roles

Link to this function

list_sessions(queries \\ &(&1))

View Source

List sessions

Link to this function

list_users(queries \\ &(&1))

View Source

Return all users with last_login_at and last_active_at virtual fields populated

Link to this function

list_workspaces(queries \\ &(&1))

View Source

List all workspaces

Load te api_tokens assoc of a given role

Link to this function

load_role_permission_scopes(query)

View Source

Load all permission assoc with scope (workspace, portal, blueprint)

Link to this function

load_role_permissions(query)

View Source

Load all permission assoc

Link to this function

load_role_sessions(query)

View Source

Load session assoc

Link to this function

load_user_activity(query)

View Source

Preload user activity

Will load role, all sessions and populate is_active, last_login_at and last_active_at virtual fields.

Load role assoc

Link to this function

load_workspace_blueprints(query)

View Source

Load blueprints assoc

Link to this function

load_workspace_stats(query)

View Source

Load blueprint_count and active_publication_count

Link to this function

revoke_permission(role, action, scope \\ :global)

View Source

Revoke permission with an action and scope

Revoke session

Link to this function

toggle_permission(role, action, scope \\ :global)

View Source

Toggle permission with an action and scope

Set session last activity time to now

Link to this function

update_role(role, attrs \\ %{})

View Source

Update role with attributes

Link to this function

update_session(session, attrs)

View Source

Update session with attributes

Link to this function

update_user(data, attrs)

View Source

Update user with attributes. This will cast all user attributes and should only be called from an admin context.

Link to this function

update_workspace(data, attrs)

View Source

Update workspace with attributes