Example #1
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])
Example #2
0
    def __init__(self, tokenlist, tid, type='submission'):
        self.tokenlist = tokenlist
        self.tid = tid
        self.id = generateRandomKey(42)
        self.type = type
        self.creation_date = datetime.utcnow()

        self.uploaded_files = []

        self.solved = False
        self.question = generateRandomKey(20)
Example #3
0
def signup_activation(session, state, tid, token, language):
    config = ConfigFactory(session, 1)

    if not config.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 = config.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, 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])
Example #4
0
def db_generate_password_reset_token(session, user):
    """
    Transaction for issuing password reset tokens

    :param session: An ORM session
    :param user: The user for which issuing a password reset token
    """
    user.reset_password_token = generateRandomKey()
    user.reset_password_date = datetime_now()

    if user.last_login > datetime_null():
        template = 'password_reset_validation'
    else:
        template = 'account_activation'

    user_desc = user_serialize_user(session, user, user.language)

    template_vars = {
        'type': template,
        'user': user_desc,
        'reset_token': user.reset_password_token,
        'node': db_admin_serialize_node(session, user.tid, user.language),
        'notification': db_get_notification(session, user.tid, user.language)
    }

    State.format_and_send_mail(session, user.tid, user_desc, template_vars)
Example #5
0
def db_generate_password_reset_token(session,
                                     state,
                                     tid,
                                     username_or_email,
                                     allow_admin_reset=False):
    from globaleaks.handlers.admin.notification import db_get_notification
    from globaleaks.handlers.admin.node import db_admin_serialize_node
    from globaleaks.handlers.user import user_serialize_user

    users = session.query(models.User).filter(
        or_(models.User.username == username_or_email,
            models.User.mail_address == username_or_email),
        models.UserTenant.user_id == models.User.id,
        models.UserTenant.tenant_id == tid).distinct()

    for user in users:
        if not allow_admin_reset and user.role == u'admin':
            continue

        user.reset_password_token = generateRandomKey(32)
        user.reset_password_date = datetime_now()

        user_desc = user_serialize_user(session, user, user.language)

        template_vars = {
            'type': 'password_reset_validation',
            'user': user_desc,
            'reset_token': user.reset_password_token,
            'node': db_admin_serialize_node(session, 1, user.language),
            'notification': db_get_notification(session, tid, user.language)
        }

        state.format_and_send_mail(session, tid, user_desc, template_vars)
Example #6
0
def get_dummy_file(content=None):
    filename = generateRandomKey()

    content_type = 'application/octet'

    if content is None:
        content = base64.b64decode(VALID_BASE64_IMG)

    temporary_file = SecureTemporaryFile(Settings.tmp_path)

    with temporary_file.open('w') as f:
        f.write(content)
        f.finalize_write()

    State.TempUploadFiles[os.path.basename(
        temporary_file.filepath)] = temporary_file

    return {
        'id': filename,
        'date': datetime_now(),
        'name': filename,
        'description': 'description',
        'body': temporary_file,
        'size': len(content),
        'filename': os.path.basename(temporary_file.filepath),
        'type': content_type,
        'submission': False
    }
Example #7
0
def generate_password_reset_token(session, state, tid, username_or_email, allow_admin_reset=False):
    from globaleaks.handlers.admin.notification import db_get_notification
    from globaleaks.handlers.admin.node import db_admin_serialize_node
    from globaleaks.handlers.user import user_serialize_user

    users = session.query(models.User).filter(
      or_(models.User.username == username_or_email,
          models.User.mail_address == username_or_email),
      models.UserTenant.user_id == models.User.id,
      models.UserTenant.tenant_id == tid
    ).distinct()

    for user in users:
        if not allow_admin_reset and user.role == u'admin':
            continue

        user.reset_password_token = generateRandomKey(32)
        user.reset_password_date = datetime_now()

        user_desc = user_serialize_user(session, user, user.language)

        template_vars = {
            'type': 'password_reset_validation',
            'user': user_desc,
            'reset_token': user.reset_password_token,
            'node': db_admin_serialize_node(session, 1, user.language),
            'notification': db_get_notification(session, tid, user.language)
        }

        state.format_and_send_mail(session, tid, user_desc, template_vars)
Example #8
0
def generate_password_reset_token(session, state, tid, username_or_email):
    from globaleaks.handlers.admin.notification import db_get_notification
    from globaleaks.handlers.admin.node import db_admin_serialize_node
    from globaleaks.handlers.user import user_serialize_user

    users = session.query(models.User).filter(
        or_(models.User.username == username_or_email,
            models.User.mail_address == username_or_email),
        models.User.tid == tid).distinct()

    for user in users:
        user.reset_password_token = generateRandomKey(32)
        user.reset_password_date = datetime_now()

        user_desc = user_serialize_user(session, user, user.language)

        template_vars = {
            'type': 'password_reset_validation',
            'user': user_desc,
            'reset_token': user.reset_password_token,
            'node': db_admin_serialize_node(session, tid, user.language),
            'notification': db_get_notification(session, tid, user.language)
        }

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

        return {'redirect': '/login/passwordreset/requested'}
Example #9
0
 def __init__(self, tokenlist, tid):
     self.tokenlist = tokenlist
     self.tid = tid
     self.id = generateRandomKey()
     self.creation_date = datetime_now()
     self.uploaded_files = []
     self.solved = False
Example #10
0
 def __init__(self, tid, user_id, user_role, pcn, cc):
     self.id = generateRandomKey(42)
     self.tid = tid
     self.user_id = user_id
     self.user_role = user_role
     self.pcn = pcn
     self.cc = cc
     self.expireCall = None
Example #11
0
 def __init__(self, tid, user_id, user_role, pcn, cc):
     self.id = generateRandomKey(42)
     self.tid = tid
     self.user_id = user_id
     self.user_role = user_role
     self.pcn = pcn
     self.cc = cc
     self.expireCall = None
Example #12
0
def db_user_update_user(session, tid, user_session, request):
    """
    Transaction for updating an existing user

    :param session: An ORM session
    :param tid: A tenant ID
    :param user_session: A session of the user invoking the transaction
    :param request: A user request data
    :return: A user model
    """
    from globaleaks.handlers.admin.notification import db_get_notification
    from globaleaks.handlers.admin.node import db_admin_serialize_node

    user = models.db_get(session, models.User,
                         models.User.id == user_session.user_id)

    user.language = request.get('language',
                                State.tenant_cache[tid].default_language)
    user.name = request['name']
    user.public_name = request['public_name'] if request[
        'public_name'] else request['name']

    if request['password']:
        if user.password_change_needed:
            user.password_change_needed = False
        else:
            if not GCE.check_password(user.hash_alg, request['old_password'],
                                      user.salt, user.password):
                raise errors.InvalidOldPassword

        user_session.cc = set_user_password(tid, user, request['password'],
                                            user_session.cc)

    # If the email address changed, send a validation email
    if request['mail_address'] != user.mail_address:
        user.change_email_address = request['mail_address']
        user.change_email_date = datetime_now()
        user.change_email_token = generateRandomKey()

        user_desc = user_serialize_user(session, user, user.language)

        user_desc['mail_address'] = request['mail_address']

        template_vars = {
            'type': 'email_validation',
            'user': user_desc,
            'new_email_address': request['mail_address'],
            'validation_token': user.change_email_token,
            'node': db_admin_serialize_node(session, tid, user.language),
            'notification': db_get_notification(session, tid, user.language)
        }

        State.format_and_send_mail(session, tid, user_desc, template_vars)

    parse_pgp_options(user, request)

    return user
Example #13
0
def process_receiverfiles(state, files_maps):
    """
    Function that process uploaded receiverfiles

    :param state: A reference to the application state
    :param files_maps: descriptos of whistleblower files to be processed
    """
    for _, receiverfiles_map in files_maps.items():
        key = receiverfiles_map['crypto_tip_pub_key']
        filename = receiverfiles_map['filename']
        filecode = filename.split('.')[0]
        plaintext_name = "%s.plain" % filecode
        encrypted_name = "%s.encrypted" % filecode
        plaintext_path = os.path.abspath(
            os.path.join(Settings.attachments_path, plaintext_name))
        encrypted_path = os.path.abspath(
            os.path.join(Settings.attachments_path, encrypted_name))

        receiverfiles_map[
            'filename'] = encrypted_name if key else plaintext_name

        sf = state.get_tmp_file_by_name(filename)

        for rcounter, rf in enumerate(receiverfiles_map['rfiles']):
            if key:
                rf['filename'] = encrypted_name
            else:
                rf['filename'] = plaintext_path

            try:
                with sf.open('rb') as encrypted_file:
                    if not rf['receiver']['pgp_key_public']:
                        receiverfiles_map[
                            'pgp_encrypted_for_everybody'] = False
                        continue

                    pgp_name = "%s.pgp" % generateRandomKey()
                    pgp_path = os.path.abspath(
                        os.path.join(Settings.attachments_path, pgp_name))
                    encrypt_file_with_pgp(
                        state, encrypted_file,
                        rf['receiver']['pgp_key_public'],
                        rf['receiver']['pgp_key_fingerprint'], pgp_path)
                    rf['filename'] = pgp_name
                    rf['status'] = 'encrypted'

            except Exception as excep:
                log.err(
                    "%d# Unable to complete PGP encrypt for %s on %s: %s. marking the file as unavailable.",
                    rcounter, rf['receiver']['name'], rf['filename'], excep)
                rf['status'] = 'unavailable'

        if not receiverfiles_map['pgp_encrypted_for_everybody']:
            if key:
                write_encrypted_file(key, sf, encrypted_path)
            else:
                write_plaintext_file(sf, plaintext_path)
Example #14
0
def process_receiverfiles(state, receiverfiles_maps):
    """
    @param receiverfiles_maps: the mapping of ifile/rfiles to be created on filesystem
    @return: return None
    """
    for id, receiverfiles_map in receiverfiles_maps.items():
        key = receiverfiles_map['crypto_tip_pub_key']
        filename = receiverfiles_map['filename']
        filecode = filename.split('.')[0]
        plaintext_name = "%s.plain" % filecode
        encrypted_name = "%s.encrypted" % filecode
        plaintext_path = os.path.abspath(
            os.path.join(Settings.attachments_path, plaintext_name))
        encrypted_path = os.path.abspath(
            os.path.join(Settings.attachments_path, encrypted_name))

        sf = state.get_tmp_file_by_name(filename)

        if key:
            receiverfiles_map['filename'] = encrypted_name
            write_encrypted_file(key, sf, encrypted_path)
            for rf in receiverfiles_map['rfiles']:
                rf['filename'] = encrypted_name
        else:
            for rcounter, rfileinfo in enumerate(receiverfiles_map['rfiles']):
                with sf.open('rb') as encrypted_file:
                    if rfileinfo['receiver']['pgp_key_public']:
                        try:
                            pgp_name = "pgp_encrypted-%s" % generateRandomKey(
                                16)
                            pgp_path = os.path.abspath(
                                os.path.join(Settings.attachments_path,
                                             pgp_name))
                            encrypt_file_with_pgp(
                                state, encrypted_file,
                                rfileinfo['receiver']['pgp_key_public'],
                                rfileinfo['receiver']['pgp_key_fingerprint'],
                                pgp_path)
                            rfileinfo['filename'] = pgp_name
                            rfileinfo['status'] = u'encrypted'
                        except Exception as excep:
                            log.err(
                                "%d# Unable to complete PGP encrypt for %s on %s: %s. marking the file as unavailable.",
                                rcounter, rfileinfo['receiver']['name'],
                                rfileinfo['filename'], excep)
                            rfileinfo['status'] = u'unavailable'
                    elif state.tenant_cache[
                            receiverfiles_map['tid']].allow_unencrypted:
                        receiverfiles_map['plaintext_file_needed'] = True
                        rfileinfo['filename'] = plaintext_name
                        rfileinfo['status'] = u'reference'
                    else:
                        rfileinfo['status'] = u'nokey'

        if receiverfiles_map['plaintext_file_needed']:
            write_plaintext_file(sf, plaintext_path)
Example #15
0
 def __init__(self, tid, user_id, user_tid, user_role, pcn, two_factor, cc,
              ek):
     self.id = generateRandomKey(42)
     self.tid = tid
     self.user_id = user_id
     self.user_tid = user_tid
     self.user_role = user_role
     self.pcn = pcn
     self.two_factor = two_factor
     self.cc = cc
     self.ek = ek
     self.expireCall = None
Example #16
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)
Example #17
0
 def __init__(self, filesdir):
     """
     Create the AES Key to encrypt the uploaded file and initialize the cipher
     """
     self.key = os.urandom(32)
     self.key_id = generateRandomKey(16)
     self.key_counter_nonce = os.urandom(16)
     self.cipher = Cipher(algorithms.AES(self.key),
                          modes.CTR(self.key_counter_nonce),
                          backend=crypto_backend)
     self.filepath = os.path.join(filesdir, "%s.aes" % self.key_id)
     self.enc = self.cipher.encryptor()
     self.dec = None
Example #18
0
def process_receiverfiles(state, receiverfiles_maps):
    """
    @param receiverfiles_maps: the mapping of ifile/rfiles to be created on filesystem
    @return: return None
    """
    for id, receiverfiles_map in receiverfiles_maps.items():
        key = receiverfiles_map['crypto_tip_pub_key']
        filename = receiverfiles_map['filename']
        filecode = filename.split('.')[0]
        plaintext_name = "%s.plain" % filecode
        encrypted_name = "%s.encrypted" % filecode
        plaintext_path = os.path.abspath(os.path.join(Settings.attachments_path, plaintext_name))
        encrypted_path = os.path.abspath(os.path.join(Settings.attachments_path, encrypted_name))

        sf = state.get_tmp_file_by_name(filename)

        if key:
            receiverfiles_map['filename'] = encrypted_name
            write_encrypted_file(key, sf, encrypted_path)
            for rf in receiverfiles_map['rfiles']:
                rf['filename'] = encrypted_name
        else:
            for rcounter, rfileinfo in enumerate(receiverfiles_map['rfiles']):
                with sf.open('rb') as encrypted_file:
                    if rfileinfo['receiver']['pgp_key_public']:
                        try:
                            pgp_name = "pgp_encrypted-%s" % generateRandomKey(16)
                            pgp_path = os.path.abspath(os.path.join(Settings.attachments_path, pgp_name))
                            encrypt_file_with_pgp(state,
                                                  encrypted_file,
                                                  rfileinfo['receiver']['pgp_key_public'],
                                                  rfileinfo['receiver']['pgp_key_fingerprint'],
                                                  pgp_path)
                            rfileinfo['filename'] = pgp_name
                            rfileinfo['status'] = u'encrypted'
                        except Exception as excep:
                            log.err("%d# Unable to complete PGP encrypt for %s on %s: %s. marking the file as unavailable.",
                                    rcounter, rfileinfo['receiver']['name'], rfileinfo['filename'], excep)
                            rfileinfo['status'] = u'unavailable'
                    elif state.tenant_cache[receiverfiles_map['tid']].allow_unencrypted:
                        receiverfiles_map['plaintext_file_needed'] = True
                        rfileinfo['filename'] = plaintext_name
                        rfileinfo['status'] = u'reference'
                    else:
                        rfileinfo['status'] = u'nokey'

        if receiverfiles_map['plaintext_file_needed']:
            write_plaintext_file(sf, plaintext_path)
Example #19
0
def signup(session, state, tid, request, language):
    config = ConfigFactory(session, 1)

    if not config.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',
            '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)
Example #20
0
 def regenerate(self, session_id):
     session = self.pop(session_id)
     session.id = generateRandomKey()
     self[session.id] = session
     return session
Example #21
0
def db_user_update_user(session, state, tid, user_session, request):
    """
    Updates the specified user.
    This version of the function is specific for users that with comparison with
    admins can change only few things:
      - real name
      - email address
      - preferred language
      - the password (with old password check)
      - pgp key
    raises: globaleaks.errors.ResourceNotFound` if the receiver does not exist.
    """
    from globaleaks.handlers.admin.notification import db_get_notification
    from globaleaks.handlers.admin.node import db_admin_serialize_node

    user = models.db_get(session, models.User,
                         models.User.id == user_session.user_id)

    user.language = request.get('language',
                                State.tenant_cache[tid].default_language)
    user.name = request['name']
    new_password = request['password']
    old_password = request['old_password']

    if new_password:
        if user.password_change_needed:
            user.password_change_needed = False
        else:
            if not GCE.check_password(user.hash_alg, old_password, user.salt,
                                      user.password):
                raise errors.InvalidOldPassword

        user.hash_alg = GCE.HASH
        user.salt = GCE.generate_salt()
        user.password = GCE.hash_password(new_password, user.salt)
        user.password_change_date = datetime_now()

        if State.tenant_cache[1].encryption:
            enc_key = GCE.derive_key(request['password'].encode(), user.salt)
            if not user_session.cc:
                user_session.cc, user.crypto_pub_key = GCE.generate_keypair()

            user.crypto_prv_key = GCE.symmetric_encrypt(
                enc_key, user_session.cc)

    # If the email address changed, send a validation email
    if request['mail_address'] != user.mail_address:
        user.change_email_address = request['mail_address']
        user.change_email_date = datetime_now()
        user.change_email_token = generateRandomKey(32)

        user_desc = user_serialize_user(session, user, user.language)

        template_vars = {
            'type': 'email_validation',
            'user': user_desc,
            'new_email_address': request['mail_address'],
            'validation_token': user.change_email_token,
            'node': db_admin_serialize_node(session, 1, user.language),
            'notification': db_get_notification(session, tid, user.language)
        }

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

    # If the platform allows users to change PGP keys, process it
    if State.tenant_cache[tid]['enable_user_pgp_key_upload'] is True:
        parse_pgp_options(state, user, request)

    return user
Example #22
0
 def regenerate(self, session_id):
     session = self.pop(session_id)
     session.id = generateRandomKey(42)
     self.set(session.id, session)
     return session
Example #23
0
def signup(session, request, language):
    """
    Transact handling the registration of a new signup

    :param session: An ORM session
    :param request: A user request
    :param language: A language of the request
    """
    config = ConfigFactory(session, 1)

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

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

    # Delete the tenants created for the same subdomain that have still not been activated
    # Ticket reference: https://github.com/globaleaks/GlobaLeaks/issues/2640
    subquery = session.query(models.Tenant.id) \
                      .filter(models.Signup.subdomain == request['subdomain'],
                              not_(models.Signup.activation_token.is_(None)),
                              models.Tenant.id == models.Signup.tid,
                              models.Tenant.subdomain == models.Signup.subdomain) \
                      .subquery()

    session.query(models.Tenant).filter(
        models.Tenant.id.in_(subquery)).delete(synchronize_session=False)

    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_users(session, 1, 'admin'):
        template_vars = {
            'type': 'admin_signup_alert',
            '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)
Example #24
0
def signup_activation(session, token, hostname, language):
    """
    Transaction registering the activation of a platform registered via signup

    :param session: An ORM session
    :param token: A activation token
    :param language: A language of the request
    """
    config = ConfigFactory(session, 1)

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

    ret = session.query(models.Signup, models.Tenant) \
                 .filter(models.Signup.activation_token == token,
                         models.Tenant.id == models.Signup.tid).one_or_none()

    if ret is None:
        return {}

    signup, tenant = ret[0], ret[1]

    signup.activation_token = None

    mode = config.get_val('mode')

    db_initialize_tenant(session, tenant, mode)

    password_admin = generateRandomKey(16)
    password_receiver = generateRandomKey(16)

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

    wizard = {
        'node_language': signup.language,
        'node_name': node_name,
        'admin_username': '******',
        'admin_name': signup.name + ' ' + signup.surname,
        'admin_password': password_admin,
        'admin_mail_address': signup.email,
        'receiver_username': '******',
        'receiver_name': signup.name + ' ' + signup.surname,
        'receiver_password': password_receiver,
        'receiver_mail_address': signup.email,
        'profile': 'default',
        'skip_recipient_account_creation': False,
        'enable_developers_exception_notification': True
    }

    db_wizard(session, signup.tid, hostname, wizard)

    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': wizard['admin_password'],
        'password_recipient': wizard['receiver_password']
    }

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

    db_refresh_memory_variables(session, [signup.tid])
Example #25
0
def get_random_password():
    return text_type(generateRandomKey(16))
Example #26
0
def db_user_update_user(session, tid, user_session, request):
    """
    Updates the specified user.
    This version of the function is specific for users that with comparison with
    admins can change only few things:
      - real name
      - email address
      - preferred language
      - the password (with old password check)
      - pgp key
    raises: globaleaks.errors.ResourceNotFound` if the receiver does not exist.
    """
    from globaleaks.handlers.admin.notification import db_get_notification
    from globaleaks.handlers.admin.node import db_admin_serialize_node

    user = models.db_get(session, models.User,
                         models.User.id == user_session.user_id)

    user.language = request.get('language',
                                State.tenant_cache[tid].default_language)
    user.name = request['name']
    new_password = request['password']
    old_password = request['old_password']

    if new_password:
        if user.password_change_needed:
            user.password_change_needed = False
        else:
            if not GCE.check_password(user.hash_alg, old_password, user.salt,
                                      user.password):
                raise errors.InvalidOldPassword

        # Regenerate the password hash only if different from the best choice on the platform
        if user.hash_alg != GCE.HASH:
            user.hash_alg = GCE.HASH
            user.salt = GCE.generate_salt()

        password_hash = GCE.hash_password(new_password, user.salt)

        # Check that the new password is different form the current password
        if user.password == password_hash:
            raise errors.PasswordReuseError

        user.password = password_hash
        user.password_change_date = datetime_now()

        if State.tenant_cache[tid].encryption:
            enc_key = GCE.derive_key(request['password'].encode(), user.salt)
            if not user_session.cc:
                # Th First first password change triggers the generation
                # of the user encryption private key and its backup
                user_session.cc, user.crypto_pub_key = GCE.generate_keypair()
                user.crypto_bkp_key, user.crypto_rec_key = GCE.generate_recovery_key(
                    user_session.cc)

                # If the user had already enabled two factor before encryption was not enable
                # encrypt the two factor secret
                if user.two_factor_secret:
                    user.two_factor_secret = GCE.asymmetric_encrypt(
                        user.crypto_pub_key, user.two_factor_secret)

            user.crypto_prv_key = GCE.symmetric_encrypt(
                enc_key, user_session.cc)

    # If the email address changed, send a validation email
    if request['mail_address'] != user.mail_address:
        user.change_email_address = request['mail_address']
        user.change_email_date = datetime_now()
        user.change_email_token = generateRandomKey(32)

        user_desc = user_serialize_user(session, user, user.language)

        user_desc['mail_address'] = request['mail_address']

        template_vars = {
            'type': 'email_validation',
            'user': user_desc,
            'new_email_address': request['mail_address'],
            'validation_token': user.change_email_token,
            'node': db_admin_serialize_node(session, tid, user.language),
            'notification': db_get_notification(session, tid, user.language)
        }

        State.format_and_send_mail(session, tid, user_desc, template_vars)

    # If the platform allows users to change PGP keys, process it
    if State.tenant_cache[tid]['enable_user_pgp_key_upload'] is True:
        parse_pgp_options(user, request)

    return user
Example #27
0
def db_user_update_user(session, tid, user_session, request):
    """
    Updates the specified user.
    This version of the function is specific for users that with comparison with
    admins can change only few things:
      - real name
      - email address
      - preferred language
      - the password (with old password check)
      - pgp key
    raises: globaleaks.errors.ResourceNotFound` if the receiver does not exist.
    """
    from globaleaks.handlers.admin.notification import db_get_notification
    from globaleaks.handlers.admin.node import db_admin_serialize_node

    user = models.db_get(session,
                         models.User,
                         models.User.id == user_session.user_id)

    user.language = request.get('language', State.tenant_cache[tid].default_language)
    user.name = request['name']
    new_password = request['password']
    old_password = request['old_password']

    if new_password:
        if user.password_change_needed:
            user.password_change_needed = False
        else:
            if not GCE.check_password(user.hash_alg,
                                      old_password,
                                      user.salt,
                                      user.password):
                raise errors.InvalidOldPassword

        user.hash_alg = GCE.HASH
        user.salt = GCE.generate_salt()
        user.password = GCE.hash_password(new_password, user.salt)
        user.password_change_date = datetime_now()

        if State.tenant_cache[1].encryption:
            enc_key = GCE.derive_key(request['password'].encode(), user.salt)
            if not user_session.cc:
                user_session.cc, user.crypto_pub_key = GCE.generate_keypair()

            user.crypto_prv_key = GCE.symmetric_encrypt(enc_key, user_session.cc)

    # If the email address changed, send a validation email
    if request['mail_address'] != user.mail_address:
        user.change_email_address = request['mail_address']
        user.change_email_date = datetime_now()
        user.change_email_token = generateRandomKey(32)

        user_desc = user_serialize_user(session, user, user.language)

        template_vars = {
            'type': 'email_validation',
            'user': user_desc,
            'new_email_address': request['mail_address'],
            'validation_token': user.change_email_token,
            'node': db_admin_serialize_node(session, 1, user.language),
            'notification': db_get_notification(session, tid, user.language)
        }

        State.format_and_send_mail(session, tid, user_desc, template_vars)

    # If the platform allows users to change PGP keys, process it
    if State.tenant_cache[tid]['enable_user_pgp_key_upload'] is True:
        parse_pgp_options(user, request)

    return user
Example #28
0
def file_delivery(session):
    """
    This function roll over the InternalFile uploaded, extract a path, id and
    receivers associated, one entry for each combination. representing the
    ReceiverFile that need to be created.
    """
    receiverfiles_maps = {}
    whistleblowerfiles_maps = {}

    for ifile, itip in session.query(models.InternalFile, models.InternalTip) \
                              .filter(models.InternalFile.new.is_(True),
                                      models.InternalTip.id == models.InternalFile.internaltip_id) \
                              .order_by(models.InternalFile.creation_date) \
                              .limit(20):
        ifile.new = False
        src = ifile.filename
        filecode = src.split('.')[0]

        if itip.crypto_tip_pub_key:
            itip.filename = "%s.encrypted" % filecode
        else:
            itip.filename = "%s.plain" % filecode

        for rtip, user in session.query(models.ReceiverTip, models.User) \
                                 .filter(models.ReceiverTip.internaltip_id == ifile.internaltip_id,
                                         models.User.id == models.ReceiverTip.receiver_id):
            receiverfile = models.ReceiverFile()
            receiverfile.internalfile_id = ifile.id
            receiverfile.receivertip_id = rtip.id

            # https://github.com/globaleaks/GlobaLeaks/issues/444
            # avoid to mark the receiverfile as new if it is part of a submission
            # this way we avoid to send unuseful messages
            receiverfile.new = not ifile.submission

            session.add(receiverfile)

            if ifile.id not in receiverfiles_maps:
                receiverfiles_maps[ifile.id] = {
                    'src': src,
                    'key': itip.crypto_tip_pub_key,
                    'rfiles': []
                }

            if user.pgp_key_public:
                receiverfile.filename = "%s.pgp" % generateRandomKey()
                receiverfile.status = 'encrypted'
            else:
                receiverfile.filename = itip.filename
                receiverfile.status = 'reference'

            receiverfiles_maps[ifile.id]['rfiles'].append({
                'dst': os.path.abspath(os.path.join(Settings.attachments_path, receiverfile.filename)),
                'pgp_key_public': user.pgp_key_public,
                'pgp_key_fingerprint': user.pgp_key_fingerprint
            })

    for wbfile, itip in session.query(models.WhistleblowerFile, models.InternalTip)\
                               .filter(models.WhistleblowerFile.new.is_(True),
                                       models.ReceiverTip.id == models.WhistleblowerFile.receivertip_id,
                                       models.InternalTip.id == models.ReceiverTip.internaltip_id) \
                               .order_by(models.WhistleblowerFile.creation_date) \
                               .limit(20):
        wbfile.new = False
        src = wbfile.filename
        filecode = src.split('.')[0]

        if itip.crypto_tip_pub_key:
            wbfile.filename = "%s.encrypted" % filecode
        else:
            wbfile.filename = "%s.plain" % filecode

        whistleblowerfiles_maps[wbfile.id] = {
            'key': itip.crypto_tip_pub_key,
            'src': src,
            'dst': os.path.abspath(os.path.join(Settings.attachments_path, wbfile.filename)),
        }

    return receiverfiles_maps, whistleblowerfiles_maps
Example #29
0
 def regenerate(self, session_id):
     session = self.pop(session_id)
     session.id = generateRandomKey(42)
     self.set(session.id, session)
     return session