Exemple #1
0
def db_gen_user_keys(session, tid, user, password):
    """
    Transaction generating and saving user keys

    :param session: An ORM session
    :param tid: A tenant ID
    :param user: A user object
    :param password: A user's password
    :return: A private key generated for the user
    """
    enc_key = GCE.derive_key(password.encode(), user.salt)
    crypto_prv_key, user.crypto_pub_key = GCE.generate_keypair()
    user.crypto_bkp_key, user.crypto_rec_key = GCE.generate_recovery_key(
        crypto_prv_key)
    user.crypto_prv_key = Base64Encoder.encode(
        GCE.symmetric_encrypt(enc_key, crypto_prv_key))

    # Create an escrow backup for the root tenant
    tid_1_escrow = config.ConfigFactory(session,
                                        1).get_val('crypto_escrow_pub_key')
    if tid_1_escrow:
        user.crypto_escrow_bkp1_key = Base64Encoder.encode(
            GCE.asymmetric_encrypt(tid_1_escrow, crypto_prv_key))

    # Create an escrow backup for the actual tenant
    tid_n_escrow = config.ConfigFactory(session,
                                        tid).get_val('crypto_escrow_pub_key')
    if tid_n_escrow:
        user.crypto_escrow_bkp2_key = Base64Encoder.encode(
            GCE.asymmetric_encrypt(tid_n_escrow, crypto_prv_key))

    return crypto_prv_key
Exemple #2
0
def signup(session, state, tid, request, language):
    node = config.ConfigFactory(session, 1, 'node')

    if not node.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    request['activation_token'] = generateRandomKey(32)
    request['language'] = language

    signup = models.Signup(request)

    session.add(signup)

    ret = {
        'signup': serialize_signup(signup),
        'activation_url': 'https://%s/#/activation?token=%s' % (node.get_val(u'rootdomain'), signup.activation_token),
        'expiration_date': datetime_to_ISO8601(signup.registration_date + timedelta(days=7))
    }

    template_vars = copy.deepcopy(ret)
    template_vars.update({
        'type': 'signup',
        'node': db_admin_serialize_node(session, 1, language),
        'notification': db_get_notification(session, 1, language),
    })

    state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars)

    return ret
Exemple #3
0
def signup_activation(session, state, tid, token, language):
    node = config.ConfigFactory(session, 1, 'node')

    if not node.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    signup = session.query(models.Signup).filter(
        models.Signup.activation_token == token).one_or_none()
    if signup is None:
        return {}

    if not session.query(
            models.Config).filter(models.Config.tid == signup.tid).count():
        tenant = session.query(
            models.Tenant).filter(models.Tenant.id == signup.tid).one()

        mode = node.get_val('mode')

        db_initialize_tenant(session, tenant, mode)

        password_admin = generateRandomKey(16)
        password_recipient = generateRandomKey(16)

        node_name = signup.organization_name if signup.organization_name else signup.subdomain

        wizard = {
            'node_language': signup.language,
            'node_name': node_name,
            'admin_name': signup.name + ' ' + signup.surname,
            'admin_password': password_admin,
            'admin_mail_address': signup.email,
            'receiver_name': signup.name + ' ' + signup.surname,
            'receiver_password': password_recipient,
            'receiver_mail_address': signup.email,
            'profile': 'default',
            'enable_developers_exception_notification': True
        }

        db_wizard(session, state, signup.tid, wizard, False, language)

        ids = [
            r[0] for r in session.query(models.User.id).filter(
                models.UserTenant.user_id == models.User.id,
                models.UserTenant.tenant_id == signup.tid)
        ]

        template_vars = {
            'type': 'activation',
            'node': db_admin_serialize_node(session, 1, language),
            'notification': db_get_notification(session, 1, language),
            'signup': serialize_signup(signup),
            'password_admin': password_admin,
            'password_recipient': password_recipient
        }

        state.format_and_send_mail(session, 1, {'mail_address': signup.email},
                                   template_vars)

    db_refresh_memory_variables(session, [1])
Exemple #4
0
        def transaction(session):
            # Rename 'name' variable with the effect of:
            # - simuulating missing variable
            # - simulating the presence of a variable not anymore defined
            session.query(models.Config).filter(models.Config.tid == 1, models.Config.var_name==u'name').one().var_name=u'removed'

            # Delete a variable that requires initialization via a constructor
            session.query(models.Config).filter(models.Config.tid == 1, models.Config.var_name==u'receipt_salt').delete()

            config.ConfigFactory(session, 1).update_defaults()
Exemple #5
0
def signup_activation(session, state, tid, token, language):
    node = config.ConfigFactory(session, 1, 'node')

    if not node.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    signup = session.query(models.Signup).filter(models.Signup.activation_token == token).one_or_none()
    if signup is None:
        return {}

    if signup.tid is None:
        signup.tid = db_create_tenant(session, {'label': signup.subdomain,
                                                'subdomain': signup.subdomain}).id

        wizard = {
            'node_name': signup.subdomain,
            'admin_name': signup.name + ' ' + signup.surname,
            'admin_password': '',
            'admin_mail_address': signup.email,
            'receiver_name': signup.name + ' ' + signup.surname,
            'receiver_mail_address': signup.email,
            'profile': 'default',
            'enable_developers_exception_notification': True
        }

        db_wizard(session, state, signup.tid, wizard, False, language)

        template_vars = {
            'type': 'activation',
            'node': db_admin_serialize_node(session, 1, language),
            'notification': db_get_notification(session, 1, language),
            'signup': serialize_signup(signup),
            'activation_url': '',
            'expiration_date': datetime_to_ISO8601(signup.registration_date + timedelta(days=7))
        }

        state.format_and_send_mail(session, 1, {'mail_address': signup.email}, template_vars)

    if session.query(models.Tenant).filter(models.Tenant.id == signup.tid).one_or_none() is not None:
        admin = session.query(models.User).filter(models.User.tid == signup.tid, models.User.role == u'admin').one()
        admin.password_change_needed = False

        recipient = session.query(models.User).filter(models.User.tid == signup.tid, models.User.role == u'receiver').one()
        recipient.password_change_needed = False

        return {
            'platform_url': 'https://%s.%s' % (signup.subdomain, node.get_val(u'rootdomain')),
            'login_url': 'https://%s.%s/#/login' % (signup.subdomain, node.get_val(u'rootdomain')),
            'admin_login_url': 'https://%s.%s/#/login?token=%s' % (signup.subdomain, node.get_val(u'rootdomain'), admin.auth_token),
            'recipient_login_url': 'https://%s.%s/#/login?token=%s' % (signup.subdomain, node.get_val(u'rootdomain'), recipient.auth_token),
            'expiration_date': datetime_to_ISO8601(signup.registration_date + timedelta(days=7))
        }
    else:
        return {}
Exemple #6
0
def signup(session, state, tid, request, language):
    node = config.ConfigFactory(session, 1, 'node')

    if not node.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    request['activation_token'] = generateRandomKey(32)
    request['language'] = language

    tenant_id = db_preallocate_tenant(session, {
        'label': request['subdomain'],
        'subdomain': request['subdomain']
    }).id

    signup = models.Signup(request)

    signup.tid = tenant_id

    session.add(signup)

    # We need to send two emails
    #
    # The first one is sent to the platform owner with the activation email.
    #
    # The second goes to the instance administrators notifying them that a new
    # platform has been added.

    signup_dict = serialize_signup(signup)

    # Email 1 - Activation Link
    template_vars = {
        'type': 'signup',
        'node': db_admin_serialize_node(session, 1, language),
        'notification': db_get_notification(session, 1, language),
        'signup': signup_dict
    }

    state.format_and_send_mail(session, 1, {'mail_address': signup.email},
                               template_vars)

    # Email 2 - Admin Notification
    for user_desc in db_get_admin_users(session, 1):
        template_vars = {
            'type': 'admin_signup_alert',
            'signup': serialize_signup(signup),
            'node': db_admin_serialize_node(session, 1, user_desc['language']),
            'notification': db_get_notification(session, 1,
                                                user_desc['language']),
            'user': user_desc,
            'signup': signup_dict
        }

        state.format_and_send_mail(session, 1, user_desc, template_vars)
Exemple #7
0
def perform_data_update(db_file):
    """
    Update the database including up-to-date application data
    :param db_file: The database file path
    """
    now = datetime_now()

    appdata = load_appdata()

    session = get_session(make_db_uri(db_file), foreign_keys=False)

    enabled_languages = [
        lang.name for lang in session.query(models.EnabledLanguage)
    ]

    removed_languages = list(
        set(enabled_languages) - set(LANGUAGES_SUPPORTED_CODES))

    if removed_languages:
        removed_languages.sort()
        removed_languages = ', '.join(removed_languages)
        raise Exception(
            "FATAL: cannot complete the upgrade because the support for some of the enabled languages is currently incomplete (%s)\n"
            % removed_languages)

    try:
        if config.ConfigFactory(session, 1).get_val('version') != __version__:
            session.query(models.Config).filter_by(var_name = 'version') \
                   .update({'value': __version__, 'update_date': now})

            session.query(models.Config).filter_by(var_name = 'latest_version') \
                   .update({'value': __version__, 'update_date': now})

            session.query(models.Config).filter_by(var_name = 'version_db') \
                   .update({'value': DATABASE_VERSION, 'update_date': now})

            for tid in [t[0] for t in session.query(models.Tenant.id)]:
                config.update_defaults(session, tid, appdata)

            db_load_defaults(session)

        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()
Exemple #8
0
def perform_data_update(db_file):
    """
    Update the database including up-to-date application data
    :param db_file: The database file path
    """
    session = get_session(make_db_uri(db_file), foreign_keys=False)

    enabled_languages = [
        lang.name for lang in session.query(models.EnabledLanguage)
    ]

    removed_languages = list(
        set(enabled_languages) - set(LANGUAGES_SUPPORTED_CODES))

    if removed_languages:
        removed_languages.sort()
        removed_languages = ', '.join(removed_languages)
        raise Exception(
            "FATAL: cannot complete the upgrade because the support for some of the enabled languages is currently incomplete (%s)\n"
            "Read about how to handle this condition at: https://github.com/globaleaks/GlobaLeaks/wiki/Upgrade-Guide#lang-drop"
            % removed_languages)

    try:
        cfg = config.ConfigFactory(session, 1)

        stored_ver = cfg.get_val('version')

        if stored_ver != __version__:
            # The below commands can change the current store based on the what is
            # currently stored in the DB.
            for tid in [t[0] for t in session.query(models.Tenant.id)]:
                appdata = load_appdata()
                config.update_defaults(session, tid, appdata)

            db_load_defaults(session)

            cfg.set_val('version', __version__)
            cfg.set_val('latest_version', __version__)
            cfg.set_val('version_db', DATABASE_VERSION)

        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()
def get_salt(session, tid):
    return config.ConfigFactory(session, tid, 'node').get_val(u'receipt_salt')
def enable_signup(session):
    config.ConfigFactory(session, 1, 'node').set_val(u'enable_signup', True)
Exemple #11
0
def db_wizard(session, state, tid, request, client_using_tor, language):
    node = config.ConfigFactory(session, tid, 'node')

    if node.get_val(u'wizard_done'):
        log.err("DANGER: Wizard already initialized!", tid=tid)
        raise errors.ForbiddenOperation

    db_update_enabled_languages(session, tid, [language], language)

    tenant = models.db_get(session, models.Tenant, models.Tenant.id == tid)
    tenant.label = request['node_name']

    node.set_val(u'name', request['node_name'])
    node.set_val(u'default_language', language)
    node.set_val(u'wizard_done', True)
    node.set_val(u'enable_developers_exception_notification',
                 request['enable_developers_exception_notification'])

    # Guess Tor configuration from thee media used on first configuration and
    # if the user is using Tor preserve node anonymity and perform outgoing connections via Tor
    node.set_val(u'reachable_via_web', not client_using_tor)
    node.set_val(u'allow_unencrypted', not client_using_tor)
    node.set_val(u'anonymize_outgoing_connections', client_using_tor)
    node.set_val(u'disable_encryption_warnings', not client_using_tor)

    node_l10n = config.NodeL10NFactory(session, tid)
    node_l10n.set_val(u'header_title_homepage', language, request['node_name'])

    profiles.load_profile(session, tid, request['profile'])

    receiver_desc = models.User().dict(language)
    receiver_desc['name'] = request['receiver_name']
    receiver_desc['username'] = u'recipient'
    receiver_desc['name'] = request['receiver_name']
    receiver_desc['mail_address'] = request['receiver_mail_address']
    receiver_desc['language'] = language
    receiver_desc['role'] = u'receiver'
    receiver_desc['deletable'] = True
    receiver_desc['pgp_key_remove'] = False

    _, receiver = db_create_receiver_user(session, state, tid, receiver_desc,
                                          language)

    context_desc = models.Context().dict(language)
    context_desc['name'] = u'Default'
    context_desc['receivers'] = [receiver.id]

    db_create_context(session, state, tid, context_desc, language)

    admin_desc = models.User().dict(language)
    admin_desc['name'] = request['admin_name']
    admin_desc['username'] = u'admin'
    admin_desc['password'] = request['admin_password']
    admin_desc['name'] = request['admin_name']
    admin_desc['mail_address'] = request['admin_mail_address']
    admin_desc['language'] = language
    admin_desc['role'] = u'admin'
    admin_desc['deletable'] = False
    admin_desc['pgp_key_remove'] = False
    admin_desc['password_change_needed'] = False

    db_create_user(session, state, tid, admin_desc, language)

    db_refresh_memory_variables(session, [tid])
Exemple #12
0
def db_wizard(session, tid, hostname, request):
    """
    Transaction for the handling of wizard request

    :param session: An ORM session
    :param tid: A tenant ID
    :param request: A user request
    """
    language = request['node_language']

    node = config.ConfigFactory(session, tid)

    if tid == 1:
        root_tenant_node = node
        encryption = True
    else:
        root_tenant_node = node
        encryption = root_tenant_node.get_val('encryption')

    if node.get_val('wizard_done'):
        log.err("DANGER: Wizard already initialized!", tid=tid)
        raise errors.ForbiddenOperation

    db_update_enabled_languages(session, tid, [language], language)

    node.set_val('encryption', encryption)
    node.set_val('name', request['node_name'])
    node.set_val('default_language', language)
    node.set_val('wizard_done', True)
    node.set_val('enable_developers_exception_notification',
                 request['enable_developers_exception_notification'])
    node.set_val('hostname', hostname)

    node_l10n = config.ConfigL10NFactory(session, tid)
    node_l10n.set_val('header_title_homepage', language, request['node_name'])

    profiles.load_profile(session, tid, request['profile'])

    if encryption:
        crypto_escrow_prv_key, crypto_escrow_pub_key = GCE.generate_keypair()
        node.set_val('crypto_escrow_pub_key', crypto_escrow_pub_key)

    admin_desc = models.User().dict(language)
    admin_desc['username'] = request['admin_username']
    admin_desc['name'] = request['admin_name']
    admin_desc['password'] = request['admin_password']
    admin_desc['name'] = request['admin_name']
    admin_desc['mail_address'] = request['admin_mail_address']
    admin_desc['language'] = language
    admin_desc['role'] = 'admin'
    admin_desc['pgp_key_remove'] = False

    admin_user = db_create_user(session, tid, admin_desc, language)
    admin_user.password = GCE.hash_password(request['admin_password'],
                                            admin_user.salt)
    admin_user.password_change_needed = False
    admin_user.password_change_date = datetime_now()

    if encryption:
        db_gen_user_keys(session, tid, admin_user, request['admin_password'])
        admin_user.crypto_escrow_prv_key = Base64Encoder.encode(
            GCE.asymmetric_encrypt(admin_user.crypto_pub_key,
                                   crypto_escrow_prv_key))

    receiver_user = None
    if not request['skip_recipient_account_creation']:
        receiver_desc = models.User().dict(language)
        receiver_desc['username'] = request['receiver_username']
        receiver_desc['name'] = request['receiver_name']
        receiver_desc['password'] = request['receiver_password']
        receiver_desc['mail_address'] = request['receiver_mail_address']
        receiver_desc['language'] = language
        receiver_desc['role'] = 'receiver'
        receiver_desc['pgp_key_remove'] = False
        receiver_desc['send_account_activation_link'] = receiver_desc[
            'password'] == ''
        receiver_user = db_create_user(session, tid, receiver_desc, language)

        if receiver_desc['password']:
            receiver_user.password = GCE.hash_password(
                receiver_desc['password'], receiver_user.salt)

            if encryption:
                db_gen_user_keys(session, tid, receiver_user,
                                 receiver_desc['password'])

    context_desc = models.Context().dict(language)
    context_desc['name'] = 'Default'
    context_desc['status'] = 'enabled'

    context_desc['receivers'] = [receiver_user.id] if receiver_user else []

    context = db_create_context(session, tid, context_desc, language)

    # Root tenants initialization terminates here

    if tid == 1:
        db_refresh_memory_variables(session, [tid])
        return

    # Secondary tenants initialization starts here

    tenant = models.db_get(session, models.Tenant, models.Tenant.id == tid)
    tenant.label = request['node_name']

    mode = node.get_val('mode')

    if mode not in ['default', 'demo']:
        node.set_val(
            'hostname',
            tenant.subdomain + '.' + root_tenant_node.get_val('rootdomain'))

        for varname in [
                'reachable_via_web', 'enable_receipt_hint',
                'disable_privacy_badge', 'simplified_login',
                'can_delete_submission', 'can_postpone_expiration',
                'anonymize_outgoing_connections', 'frame_ancestors',
                'password_change_period', 'default_questionnaire',
                'enable_password_reset'
        ]:
            node.set_val(varname, root_tenant_node.get_val(varname))

        context.questionnaire_id = root_tenant_node.get_val(
            'default_questionnaire')

        # Set data retention policy to 18 months
        context.tip_timetolive = 540

        # Delete the admin user
        request['admin_password'] = ''
        session.delete(admin_user)

        if receiver_user is not None:
            # Enable the recipient user to configure platform general settings
            receiver_user.can_edit_general_settings = True

            # Set the recipient name equal to the node name
            receiver_user.name = receiver_user.public_name = request[
                'node_name']

    # Apply the specific fixes related to whistleblowing.it projects
    if mode == 'whistleblowing.it':
        node.set_val('simplified_login', True)
        node.set_val('tor', False)

    db_refresh_memory_variables(session, [tid])
Exemple #13
0
def db_wizard(session, tid, request, client_using_tor, language):
    language = request['node_language']

    node = config.ConfigFactory(session, tid)

    if tid != 1:
        root_tenant_node = config.ConfigFactory(session, 1)
    else:
        root_tenant_node = node

    if node.get_val(u'wizard_done'):
        log.err("DANGER: Wizard already initialized!", tid=tid)
        raise errors.ForbiddenOperation

    db_update_enabled_languages(session, tid, [language], language)

    node.set_val(u'name', request['node_name'])
    node.set_val(u'default_language', language)
    node.set_val(u'wizard_done', True)
    node.set_val(u'enable_developers_exception_notification',
                 request['enable_developers_exception_notification'])

    # Guess Tor configuration from thee media used on first configuration and
    # if the user is using Tor preserve node anonymity and perform outgoing connections via Tor
    node.set_val(u'reachable_via_web', not client_using_tor)
    node.set_val(u'allow_unencrypted', not client_using_tor)
    node.set_val(u'anonymize_outgoing_connections', client_using_tor)

    node_l10n = config.ConfigL10NFactory(session, tid)
    node_l10n.set_val(u'header_title_homepage', language, request['node_name'])

    profiles.load_profile(session, tid, request['profile'])

    admin_desc = models.User().dict(language)
    admin_desc['name'] = request['admin_name']
    admin_desc['username'] = u'admin'
    admin_desc['password'] = request['admin_password']
    admin_desc['name'] = request['admin_name']
    admin_desc['mail_address'] = request['admin_mail_address']
    admin_desc['language'] = language
    admin_desc['role'] = u'admin'
    admin_desc['deletable'] = False
    admin_desc['pgp_key_remove'] = False

    admin_user = db_create_user(session, tid, admin_desc, language)
    admin_user.password_change_needed = False
    admin_user.password_change_date = datetime_now()

    receiver_desc = models.User().dict(language)
    receiver_desc['name'] = request['receiver_name']
    receiver_desc['username'] = u'recipient'
    receiver_desc['password'] = request['receiver_password']
    receiver_desc['name'] = request['receiver_name']
    receiver_desc['mail_address'] = request['receiver_mail_address']
    receiver_desc['language'] = language
    receiver_desc['role'] = u'receiver'
    receiver_desc['deletable'] = True
    receiver_desc['pgp_key_remove'] = False

    receiver_user = db_create_user(session, tid, receiver_desc, language)

    context_desc = models.Context().dict(language)
    context_desc['status'] = 1
    context_desc['name'] = u'Default'
    context_desc['receivers'] = [receiver_user.id]

    context = db_create_context(session, tid, context_desc, language)

    # Root tenants initialization terminates here

    if tid == 1:
        db_refresh_memory_variables(session, [tid])
        return

    # Secondary tenants initialization starts here

    tenant = models.db_get(session, models.Tenant, models.Tenant.id == tid)
    tenant.label = request['node_name']

    mode = node.get_val(u'mode')

    if mode != u'default':
        node.set_val(
            u'hostname',
            tenant.subdomain + '.' + root_tenant_node.get_val(u'rootdomain'))

        for varname in [
                'reachable_via_web', 'disable_key_code_hint',
                'disable_privacy_badge', 'disable_donation_panel',
                'simplified_login', 'can_delete_submission',
                'can_postpone_expiration', 'enable_user_pgp_key_upload',
                'allow_unencrypted', 'anonymize_outgoing_connections',
                'allow_iframes_inclusion', 'password_change_period',
                'default_questionnaire'
        ]:
            node.set_val(varname, root_tenant_node.get_val(varname))

        context.questionnaire_id = root_tenant_node.get_val(
            u'default_questionnaire')

    # Apply the general settings to apply on all mode != default
    if mode != u'default':
        # Enable the recipient user to configure platform general settings
        receiver_user.can_edit_general_settings = True

        # Set data retention policy to 18 months
        context.tip_timetolive = 540

    # Apply the specific fixes related to whistleblowing.it projects
    if mode == u'whistleblowing.it':
        node.set_val(u'simplified_login', True)
        node.set_val(u'tor', False)

        # Enable recipients to load files to the whistleblower
        context.enable_rc_to_wb_files = True

        # Set the recipient name equal to the node name
        receiver_user.name = request['node_name']

        # Delete the admin user
        session.delete(admin_user)

    db_refresh_memory_variables(session, [tid])
Exemple #14
0
def signup(session, state, tid, request, language):
    node = config.ConfigFactory(session, 1, 'node')

    if not node.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    request['activation_token'] = generateRandomKey(32)
    request['language'] = language

    signup = models.Signup(request)

    session.add(signup)

    session.flush()

    ret = {
        'signup':
        serialize_signup(signup),
        'activation_url':
        'https://%s/#/activation?token=%s' %
        (node.get_val(u'rootdomain'), signup.activation_token),
        'expiration_date':
        datetime_to_ISO8601(signup.registration_date + timedelta(days=30))
    }

    # We need to send two emails
    #
    # The first one is sent to the platform owner with the activation email.
    #
    # The second goes to the instance administrators notifying them that a new
    # platform has been added.

    # Email 1 - Activation Link
    template_vars = copy.deepcopy(ret)
    template_vars.update({
        'type':
        'signup',
        'node':
        db_admin_serialize_node(session, 1, language),
        'notification':
        db_get_notification(session, 1, language),
    })

    state.format_and_send_mail(session, 1, {'mail_address': signup.email},
                               template_vars)

    # Email 2 - Admin Notification
    for user_desc in db_get_admin_users(session, 1):
        template_vars = copy.deepcopy(ret)
        template_vars.update({
            'type':
            'admin_signup_alert',
            'signup':
            serialize_signup(signup),
            'node':
            db_admin_serialize_node(session, 1, user_desc['language']),
            'notification':
            db_get_notification(session, 1, user_desc['language']),
            'user':
            user_desc
        })

        state.format_and_send_mail(session, 1, user_desc, template_vars)

    return ret
Exemple #15
0
def signup_activation(session, state, tid, token, language):
    node = config.ConfigFactory(session, 1, 'node')

    if not node.get_val(u'enable_signup'):
        raise errors.ForbiddenOperation

    signup = session.query(models.Signup).filter(
        models.Signup.activation_token == token).one_or_none()
    if signup is None:
        return {}

    if not session.query(
            models.Config).filter(models.Config.tid == signup.tid).count():
        db_initialize_tenant(session, signup.tid)

        create_admin = not node.get_val(u'signup_no_admin_user')

        if create_admin:
            signup.password_admin = generateRandomKey(16)

        signup.password_recipient = generateRandomKey(16)

        wizard = {
            'node_language': signup.language,
            'node_name': signup.subdomain,
            'admin_name': signup.name + ' ' + signup.surname,
            'admin_password': signup.password_admin,
            'admin_mail_address': signup.email,
            'receiver_name': signup.name + ' ' + signup.surname,
            'receiver_password': signup.password_recipient,
            'receiver_mail_address': signup.email,
            'profile': 'default',
            'enable_developers_exception_notification': True
        }

        db_wizard(session, state, signup.tid, wizard, create_admin, False,
                  language)

        ids = [
            r[0] for r in session.query(models.User.id).filter(
                models.UserTenant.user_id == models.User.id,
                models.UserTenant.tenant_id == signup.tid)
        ]

        session.query(models.User).filter(models.User.id.in_(ids)).update(
            {'password_change_needed': False}, synchronize_session='fetch')

        template_vars = {
            'type':
            'activation',
            'node':
            db_admin_serialize_node(session, 1, language),
            'notification':
            db_get_notification(session, 1, language),
            'signup':
            serialize_signup(signup),
            'activation_url':
            '',
            'expiration_date':
            datetime_to_ISO8601(signup.registration_date + timedelta(days=30))
        }

        state.format_and_send_mail(session, 1, {'mail_address': signup.email},
                                   template_vars)

    if session.query(models.Tenant).filter(
            models.Tenant.id == signup.tid).one_or_none() is not None:
        admin = session.query(models.User).filter(
            models.User.role == u'admin', models.User.username == u'admin',
            models.UserTenant.user_id == models.User.id,
            models.UserTenant.tenant_id == signup.tid).one_or_none()

        recipient = session.query(models.User).filter(
            models.User.role == u'receiver',
            models.User.username == u'recipient',
            models.UserTenant.user_id == models.User.id,
            models.UserTenant.tenant_id == signup.tid).one_or_none()

        ret_dict = {
            'platform_url':
            'https://%s.%s' % (signup.subdomain, node.get_val(u'rootdomain')),
            'login_url':
            'https://%s.%s/#/login' %
            (signup.subdomain, node.get_val(u'rootdomain')),
            'expiration_date':
            datetime_to_ISO8601(signup.registration_date + timedelta(days=7))
        }

        if admin is not None:
            ret_dict['login_url_admin'] = 'https://%s.%s/#/login?token=%s' % (
                signup.subdomain, node.get_val(u'rootdomain'),
                admin.auth_token)
            ret_dict['password_admin'] = signup.password_admin

        if recipient is not None:
            ret_dict[
                'login_url_recipient'] = 'https://%s.%s/#/login?token=%s' % (
                    signup.subdomain, node.get_val(u'rootdomain'),
                    recipient.auth_token)
            ret_dict['password_recipient'] = signup.password_recipient

        return ret_dict

    return {}