Exemple #1
0
def db_update_enabled_languages(session, tid, languages, default_language):
    """
    Transaction for updating the enabled languages for a tenant

    :param session: An ORM session
    :param tid: A tenant id
    :param languages_enabled: The list of enabled languages
    :param default_language: The language to be set as default
    """
    cur_enabled_langs = db_get_languages(session, tid)

    if len(languages) < 1:
        raise errors.InputValidationError("No languages enabled!")

    # get sure that the default language is included in the enabled languages
    languages = set(languages + [default_language])

    appdata = None
    for lang_code in languages:
        if lang_code not in LANGUAGES_SUPPORTED_CODES:
            raise errors.InputValidationError("Invalid lang code: %s" % lang_code)

        if lang_code not in cur_enabled_langs:
            if appdata is None:
                appdata = load_appdata()
            log.debug("Adding a new lang %s" % lang_code)
            models.config.add_new_lang(session, tid, lang_code, appdata)

    to_remove = list(set(cur_enabled_langs) - set(languages))
    if to_remove:
        session.query(models.User).filter(models.User.tid == tid, models.User.language.in_(to_remove)).update({'language': default_language}, synchronize_session=False)
        db_del(session, models.EnabledLanguage, (models.EnabledLanguage.tid == tid, models.EnabledLanguage.name.in_(to_remove)))
Exemple #2
0
def db_associate_context_receivers(session, context, receiver_ids):
    """
    Transaction for associating receivers to a context

    :param session: An ORM session
    :param context: The context on which associate the specified receivers
    :param receiver_ids: A list of receivers ids to be associated to the context
    """
    db_del(session, models.ReceiverContext,
           models.ReceiverContext.context_id == context.id)

    if not receiver_ids:
        return

    if not session.query(models.Context).filter(
            models.Context.id == context.id, models.Context.tid
            == models.User.tid, models.User.id.in_(receiver_ids)).count():
        raise errors.InputValidationError()

    for i, receiver_id in enumerate(receiver_ids):
        session.add(
            models.ReceiverContext({
                'context_id': context.id,
                'receiver_id': receiver_id,
                'order': i
            }))
Exemple #3
0
    def clean(self, session):
        self.db_clean_expired_itips(session)

        # delete emails older than two weeks
        db_del(session, models.Mail,
               models.Mail.creation_date < datetime_now() - timedelta(7))

        # delete stats older than 1 year
        db_del(session, models.Stats,
               models.Stats.start < datetime_now() - timedelta(365))

        # delete anomalies older than 1 year
        db_del(session, models.Anomalies,
               models.Anomalies.date < datetime_now() - timedelta(365))

        # delete archived questionnaire schemas not used by any existing submission
        subquery = session.query(
            models.InternalTipAnswers.questionnaire_hash).subquery()
        db_del(session, models.ArchivedSchema,
               not_(models.ArchivedSchema.hash.in_(subquery)))

        # delete the tenants created via signup that has not been completed in 24h
        subquery = session.query(models.Tenant.id).filter(models.Subscriber.activation_token != '',
                                                          models.Subscriber.tid == models.Tenant.id,
                                                          models.Tenant.id == models.Config.tid,
                                                          models.Tenant.creation_date < datetime.timestamp(datetime_now() - timedelta(days=1))) \
                                                  .subquery()
        db_del(session, models.Tenant, models.Tenant.id.in_(subquery))
Exemple #4
0
def db_delete_step(session, tid, step_id):
    subquery = session.query(models.Questionnaire.id).filter(
        models.Questionnaire.tid == tid).subquery()

    db_del(session, models.Step,
           (models.Step.id
            == step_id, models.Step.questionnaire_id.in_(subquery)))
Exemple #5
0
def db_delete_itip(session, itip_id):
    """
    Transaction for deleting a submission

    :param session: An ORM session
    :param itip_id: A submission ID
    """
    db_del(session, models.InternalTip, models.InternalTip.id == itip_id)
Exemple #6
0
def db_delete_itips(session, itips_ids):
    """
    Transaction for deleting a list of submissions

    :param session: An ORM session
    :param itips_ids: A list of submissions ID
    """
    db_del(session, models.InternalTip, models.InternalTip.id.in_(itips_ids))
Exemple #7
0
def db_reset_option_triggers(session, type, object_id):
    """
    Transaction for resetting every option trigger set on the specified object

    :param session: An ORM session
    :param type: The type of trigger to be reset
    :param object_id: The object on which reset the triggers
    """
    m = trigger_map[type]
    db_del(session, m, m.object_id == object_id)
Exemple #8
0
def reset_submissions(session, tid, user_id):
    """
    Transaction to reset the submissions of the specified tenant

    :param session: An ORM session
    :param tid: A tenant ID
    """
    session.query(Config).filter(Config.tid == tid, Config.var_name == 'counter_submissions').update({'value': 0})

    db_del(session, InternalTip, InternalTip.tid==tid)

    State.log(tid=tid, type='reset_reports', user_id=user_id)
Exemple #9
0
 def db_clean_expired_itips(self, session):
     """
     This function, checks all the InternalTips and their expiration date.
     if expired InternalTips are found, it removes that along with
     all the related DB entries comment and tip related.
     """
     itips_ids = [
         id[0] for id in session.query(models.InternalTip.id).filter(
             models.InternalTip.expiration_date < datetime_now())
     ]
     if itips_ids:
         db_del(session, models.InternalTip,
                models.InternalTip.id.in_(itips_ids))
Exemple #10
0
def perform_tips_operation(session, tid, receiver_id, operation, rtips_ids):
    """
    Transaction for performing operation on submissions (postpone/delete)

    :param session: An ORM session
    :param tid: A tenant ID
    :param receiver_id: A recipient ID
    :param operation: An operation command (postpone/delete)
    :param rtips_ids: The set of submissions on which performing the specified operation
    """
    receiver = db_get(session, models.User, models.User.id == receiver_id)

    can_postpone_expiration = State.tenant_cache[
        tid].can_postpone_expiration or receiver.can_postpone_expiration
    can_delete_submission = State.tenant_cache[
        tid].can_delete_submission or receiver.can_delete_submission

    itips = session.query(models.InternalTip) \
                   .filter(models.ReceiverTip.receiver_id == receiver_id,
                           models.ReceiverTip.id.in_(rtips_ids),
                           models.InternalTip.id == models.ReceiverTip.internaltip_id,
                           models.InternalTip.tid == tid)

    if operation == 'postpone' and can_postpone_expiration:
        for itip in itips:
            db_postpone_expiration(session, itip)

    elif operation == 'delete' and can_delete_submission:
        itip_ids = [itip.id for itip in itips]

        for itip_id in itip_ids:
            State.log(tid=tid,
                      type='delete_report',
                      user_id=receiver_id,
                      object_id=itip_id)

        db_del(session, models.InternalTip,
               models.InternalTip.id.in_(itip_ids))

    else:
        raise errors.ForbiddenOperation
Exemple #11
0
def db_load_default_questionnaires(session):
    """
    Transaction for loading default questionnaires
    :param session: An ORM session
    """
    qfiles = [
        os.path.join(Settings.questionnaires_path, path)
        for path in os.listdir(Settings.questionnaires_path)
    ]
    questionnaires = []
    qids = []

    for qfile in qfiles:
        questionnaires.append(read_json_file(qfile))
        qids.append(questionnaires[-1]['id'])

    db_del(session, models.Questionnaire, models.Questionnaire.id.in_(qids))
    db_del(session, models.Step, models.Step.questionnaire_id.in_(qids))

    for questionnaire in questionnaires:
        db_create_questionnaire(session, 1, questionnaire, None)
Exemple #12
0
def db_update_fieldoptions(session, field_id, options, language):
    """
    Transaction to update a set of options at once

    :param session: An ORM session
    :param field_id: The field on which the options are set
    :param options: The list of options to be updated
    :param language: The language of the request
    """
    options_ids = [db_update_fieldoption(session, field_id, option['id'], option, language, idx) for idx, option in enumerate(options)]

    if not options_ids:
        return

    subquery = session.query(models.FieldOption.id) \
                      .filter(models.FieldOption.field_id == field_id,
                              not_(models.FieldOption.id.in_(options_ids))) \
                      .subquery()

    db_del(session,
           models.FieldOption,
           models.FieldOption.id.in_(subquery))
Exemple #13
0
def db_update_fieldattrs(session, field_id, field_attrs, language):
    """
    Transaction to update a set of fieldattrs at once

    :param session: An ORM session
    :param field_id: The field on which the fieldattrs are set
    :param field_attrs: The list of fieldattrs to be updated
    :param language: The language of the request
    """
    attrs_ids = [db_update_fieldattr(session, field_id, attr_name, attr, language) for attr_name, attr in field_attrs.items()]

    if not attrs_ids:
        return

    subquery = session.query(models.FieldAttr.id) \
                      .filter(models.FieldAttr.field_id == field_id,
                              not_(models.FieldAttr.id.in_(attrs_ids))) \
                      .subquery()

    db_del(session,
           models.FieldAttr,
           models.FieldAttr.id.in_(subquery))
Exemple #14
0
def db_fix_fields_attrs(session):
    """
    Ensures that questions loaded into the database have the same structure of field_attrs.json

    :param session: An ORM session
    """
    field_attrs = read_json_file(Settings.field_attrs_file)

    std_lst = [
        'inputbox', 'textarea', 'checkbox', 'selectbox', 'fieldgroup', 'tos',
        'date', 'daterange', 'map'
    ]

    for field_type, attrs_dict in field_attrs.items():
        attrs_to_keep_for_type = attrs_dict.keys()
        if field_type in std_lst:
            # Ensure that the standard field attrs do not have extra attr rows
            _filter = not_(models.FieldAttr.name.in_(attrs_to_keep_for_type)), \
                      models.FieldAttr.field_id == models.Field.id, \
                      models.Field.type == field_type, \
                      models.Field.template_id.is_(None)
        else:
            # Look for dropped attrs in non-standard field_groups like whistleblower_identity
            _filter = not_(models.FieldAttr.name.in_(attrs_to_keep_for_type)), \
                      models.FieldAttr.field_id == models.Field.id, \
                      models.Field.template_id == field_type

        subquery = session.query(
            models.FieldAttr.id).filter(*_filter).subquery()

        db_del(models.FieldAttr, models.FieldAttr.id.in_(subquery))

    # Add keys to the db that have been added to field_attrs
    for field in session.query(models.Field):
        type = field.type if field.template_id is None else field.template_id
        attrs = field_attrs.get(type, {})
        db_update_fieldattrs(session, field.id, attrs, None)
Exemple #15
0
def db_load_default_fields(session):
    """
    Transaction for loading default questions
    :param session: An ORM session
    """
    ffiles = [
        os.path.join(Settings.questions_path, path)
        for path in os.listdir(Settings.questions_path)
    ]
    questions = []
    qids = []

    for ffile in ffiles:
        questions.append(read_json_file(ffile))
        qids.append(questions[-1]['id'])

    db_del(session, models.Field, models.Field.id.in_(qids))
    db_del(session, models.Field, models.Field.fieldgroup_id.in_(qids))
    db_del(session, models.FieldAttr, models.FieldAttr.field_id.in_(qids))
    db_del(session, models.FieldOption, models.FieldOption.field_id.in_(qids))

    for question in questions:
        db_create_field(session, 1, question, None)
Exemple #16
0
def delete(session, tid):
    db_del(session, models.Tenant, models.Tenant.id == tid)
    db_refresh_memory_variables(session, [tid])
Exemple #17
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()
    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.Subscriber.subdomain == request['subdomain'],
                              not_(models.Subscriber.activation_token.is_(None)),
                              models.Tenant.id == models.Subscriber.tid) \
                      .subquery()

    db_del(session, models.Tenant, models.Tenant.id.in_(subquery))

    tenant = db_create_tenant(
        session, {
            'active': False,
            'name': request['subdomain'],
            'subdomain': request['subdomain'],
            'mode': config.get_val('mode')
        })

    signup = models.Subscriber(request)

    signup.tid = tenant.id

    session.add(signup)

    session.flush()

    # 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)