Пример #1
0
def update_notification(store,
                        request,
                        language=GLSetting.memory_copy.default_language):

    try:
        notif = store.find(Notification).one()
    except Exception as excep:
        log.err("Database error or application error: %s" % excep)
        raise excep

    mo = structures.Rosetta()
    mo.acquire_request(language, request, Notification)
    for attr in mo.get_localized_attrs():
        request[attr] = mo.get_localized_dict(attr)

    if request['security'] in Notification._security_types:
        notif.security = request['security']
    else:
        log.err("Invalid request: Security option not recognized")
        log.debug("Invalid Security value: %s" % request['security'])
        raise errors.InvalidInputFormat("Security selection not recognized")

    try:
        notif.update(request)
    except Exception as dberror:
        log.err("Unable to update Notification: %s" % dberror)
        raise errors.InvalidInputFormat(dberror)

    if request['disable'] != GLSetting.notification_temporary_disable:
        log.msg("Switching notification mode: was %s and now is %s" %
                ("DISABLE" if GLSetting.notification_temporary_disable else
                 "ENABLE", "DISABLE" if request['disable'] else "ENABLE"))
        GLSetting.notification_temporary_disable = request['disable']

    return admin_serialize_notification(notif, language)
Пример #2
0
def db_admin_serialize_node(store,
                            language=GLSetting.memory_copy.default_language):

    node = store.find(Node).one()

    mo = structures.Rosetta()
    mo.acquire_storm_object(node)

    # Contexts and Receivers relationship
    associated = store.find(models.ReceiverContext).count()

    node_dict = {
        "name": node.name,
        "presentation": node.presentation,
        "creation_date": datetime_to_ISO8601(node.creation_date),
        "last_update": datetime_to_ISO8601(node.last_update),
        "hidden_service": node.hidden_service,
        "public_site": node.public_site,
        "receipt_regexp": node.receipt_regexp,
        "receipt_example": generate_example_receipt(node.receipt_regexp),
        "stats_update_time": node.stats_update_time,
        "email": node.email,
        "version": GLSetting.version_string,
        "languages_supported": LANGUAGES_SUPPORTED,
        "languages_enabled": node.languages_enabled,
        "default_language": node.default_language,
        'maximum_filesize': node.maximum_filesize,
        'maximum_namesize': node.maximum_namesize,
        'maximum_textsize': node.maximum_textsize,
        'exception_email': node.exception_email,
        'tor2web_admin': GLSetting.memory_copy.tor2web_admin,
        'tor2web_submission': GLSetting.memory_copy.tor2web_submission,
        'tor2web_receiver': GLSetting.memory_copy.tor2web_receiver,
        'tor2web_unauth': GLSetting.memory_copy.tor2web_unauth,
        'postpone_superpower': node.postpone_superpower,
        'can_delete_submission': node.can_delete_submission,
        'ahmia': node.ahmia,
        'reset_css': False,
        'anomaly_checks': node.anomaly_checks,
        'allow_unencrypted': node.allow_unencrypted,
        'wizard_done': node.wizard_done,
        'receipt_regexp': node.receipt_regexp,
        'configured': True if associated else False,
        'password': u"",
        'old_password': u"",
    }

    for attr in mo.get_localized_attrs():
        node_dict[attr] = mo.dump_translated(attr, language)

    return node_dict
Пример #3
0
def admin_serialize_notification(
        notif, language=GLSetting.memory_copy.default_language):
    notification_dict = {
        'server': notif.server if notif.server else u"",
        'port': notif.port if notif.port else u"",
        'username': notif.username if notif.username else u"",
        'password': notif.password if notif.password else u"",
        'security': notif.security if notif.security else u"",
        'source_name': notif.source_name,
        'source_email': notif.source_email,
        'disable': GLSetting.notification_temporary_disable,
    }

    mo = structures.Rosetta()
    mo.acquire_storm_object(notif)
    for attr in mo.get_localized_attrs():
        notification_dict[attr] = mo.dump_translated(attr, language)

    return notification_dict
Пример #4
0
def admin_serialize_receiver(receiver,
                             language=GLSetting.memory_copy.default_language):

    mo = structures.Rosetta()
    mo.acquire_storm_object(receiver)

    receiver_dict = {
        "id": receiver.id,
        "name": receiver.name,
        "creation_date": datetime_to_ISO8601(receiver.creation_date),
        "last_update": datetime_to_ISO8601(receiver.last_update),
        "receiver_level": receiver.receiver_level,
        "can_delete_submission": receiver.can_delete_submission,
        "postpone_superpower": receiver.postpone_superpower,
        "username": receiver.user.username,
        "user_id": receiver.user.id,
        'mail_address': receiver.mail_address,
        "password": u"",
        # list is needed because .values returns a generator
        "contexts": list(receiver.contexts.values(models.Context.id)),
        "tags": receiver.tags,
        "gpg_key_info": receiver.gpg_key_info,
        "gpg_key_armor": receiver.gpg_key_armor,
        "gpg_key_remove": False,
        "gpg_key_fingerprint": receiver.gpg_key_fingerprint,
        "gpg_key_status": receiver.gpg_key_status,
        "gpg_enable_notification":
        True if receiver.gpg_enable_notification else False,
        "comment_notification":
        True if receiver.comment_notification else False,
        "tip_notification": True if receiver.tip_notification else False,
        "file_notification": True if receiver.file_notification else False,
        "message_notification":
        True if receiver.message_notification else False,
        "presentation_order": receiver.presentation_order,
    }

    # only 'description' at the moment is a localized object here
    for attr in mo.get_localized_attrs():
        receiver_dict[attr] = mo.dump_translated(attr, language)

    return receiver_dict
Пример #5
0
def admin_serialize_context(context,
                            language=GLSetting.memory_copy.default_language):

    mo = structures.Rosetta()
    mo.acquire_storm_object(context)
    fo = structures.Fields(context.localized_fields, context.unique_fields)

    context_dict = {
        "id": context.id,
        "creation_date": datetime_to_ISO8601(context.creation_date),
        "last_update": datetime_to_ISO8601(context.last_update),
        "selectable_receiver": context.selectable_receiver,
        "tip_max_access": context.tip_max_access,
        "file_max_download": context.file_max_download,
        "escalation_threshold": context.escalation_threshold,
        # list is needed because .values returns a generator
        "receivers": list(context.receivers.values(models.Receiver.id)),
        "tags": context.tags if context.tags else [],
        "file_required": context.file_required,
        # tip expressed in day, submission in hours
        "tip_timetolive": context.tip_timetolive / (60 * 60 * 24),
        "submission_timetolive": context.submission_timetolive / (60 * 60),
        "select_all_receivers": context.select_all_receivers,
        "postpone_superpower": context.postpone_superpower,
        "can_delete_submission": context.can_delete_submission,
        "require_file_description": context.require_file_description,
        "delete_consensus_percentage": context.delete_consensus_percentage,
        "maximum_selectable_receivers": context.maximum_selectable_receivers,
        "require_pgp": context.require_pgp,
        "show_small_cards": context.show_small_cards,
        "presentation_order": context.presentation_order,
        "fields": fo.dump_fields(language)
    }

    for attr in mo.get_localized_attrs():
        context_dict[attr] = mo.dump_translated(attr, language)

    return context_dict
Пример #6
0
def update_receiver(store,
                    receiver_id,
                    request,
                    language=GLSetting.memory_copy.default_language):
    """
    Updates the specified receiver with the details.
    raises :class:`globaleaks.errors.ReceiverIdNotFound` if the receiver does
    not exist.
    """
    receiver = store.find(Receiver, Receiver.id == unicode(receiver_id)).one()

    if not receiver:
        raise errors.ReceiverIdNotFound

    mo = structures.Rosetta()
    mo.acquire_request(language, request, Receiver)
    for attr in mo.get_localized_attrs():
        request[attr] = mo.get_localized_dict(attr)

    mail_address = request['mail_address']

    homonymous = store.find(User, User.username == mail_address).one()
    if homonymous and homonymous.id != receiver.user_id:
        log.err(
            "Update error: already present receiver with the requested username: %s"
            % mail_address)
        raise errors.ExpectedUniqueField('mail_address', mail_address)

    receiver.mail_address = mail_address
    receiver.tags = request['tags']

    # the email address it's also the username, stored in User
    receiver.user.username = mail_address

    # The various options related in manage GPG keys are used here.
    gpg_options_parse(receiver, request)

    password = request['password']
    if len(password):
        security.check_password_format(password)
        receiver.user.password = security.hash_password(
            password, receiver.user.salt)

    contexts = request.get('contexts', [])

    for context in receiver.contexts:
        receiver.contexts.remove(context)

    for context_id in contexts:
        context = store.find(Context, Context.id == context_id).one()
        if not context:
            log.err("Update error: unexistent context can't be associated")
            raise errors.ContextIdNotFound
        receiver.contexts.add(context)

    receiver.last_update = datetime_now()
    try:
        receiver.update(request)
    except Exception as dberror:
        log.err("Unable to update receiver %s: %s" % (receiver.name, dberror))
        raise errors.InvalidInputFormat(dberror)

    return admin_serialize_receiver(receiver, language)
Пример #7
0
def db_create_receiver(store,
                       request,
                       language=GLSetting.memory_copy.default_language):
    """
    Creates a new receiver.
    Returns:
        (dict) the configured receiver
    """

    mo = structures.Rosetta()
    mo.acquire_request(language, request, Receiver)
    for attr in mo.get_localized_attrs():
        request[attr] = mo.get_localized_dict(attr)

    mail_address = request['mail_address']

    # Pretend that username is unique:
    homonymous = store.find(User, User.username == mail_address).count()
    if homonymous:
        log.err(
            "Creation error: already present receiver with the requested username: %s"
            % mail_address)
        raise errors.ExpectedUniqueField('mail_address', mail_address)

    password = request.get('password')

    security.check_password_format(password)
    receiver_salt = security.get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    receiver_password = security.hash_password(password, receiver_salt)

    receiver_user_dict = {
        'username': mail_address,
        'password': receiver_password,
        'salt': receiver_salt,
        'role': u'receiver',
        'state': u'enabled',
    }

    receiver_user = models.User(receiver_user_dict)
    receiver_user.last_login = datetime_null()
    store.add(receiver_user)

    receiver = Receiver(request)
    receiver.user = receiver_user

    receiver.mail_address = mail_address
    receiver.tags = request['tags']

    # The various options related in manage GPG keys are used here.
    gpg_options_parse(receiver, request)

    log.debug("Creating receiver %s" % receiver.user.username)

    store.add(receiver)

    create_random_receiver_portrait(receiver.id)

    contexts = request.get('contexts', [])
    for context_id in contexts:
        context = store.find(Context, Context.id == context_id).one()
        if not context:
            log.err("Creation error: invalid Context can't be associated")
            raise errors.ContextIdNotFound
        context.receivers.add(receiver)

    return admin_serialize_receiver(receiver, language)
Пример #8
0
def update_context(store,
                   context_id,
                   request,
                   language=GLSetting.memory_copy.default_language):
    """
    Updates the specified context. If the key receivers is specified we remove
    the current receivers of the Context and reset set it to the new specified
    ones.
    If no such context exists raises :class:`globaleaks.errors.ContextIdNotFound`.

    Args:
        context_id:

        request:
            (dict) the request to use to set the attributes of the Context

    Returns:
            (dict) the serialized object updated
    """
    context = store.find(Context, Context.id == unicode(context_id)).one()

    if not context:
        raise errors.ContextIdNotFound

    mo = structures.Rosetta()
    mo.acquire_request(language, request, Context)
    for attr in mo.get_localized_attrs():
        request[attr] = mo.get_localized_dict(attr)

    for receiver in context.receivers:
        context.receivers.remove(receiver)

    receivers = request.get('receivers', [])
    for receiver_id in receivers:
        receiver = store.find(Receiver,
                              Receiver.id == unicode(receiver_id)).one()
        if not receiver:
            log.err("Update error: unexistent receiver can't be associated")
            raise errors.ReceiverIdNotFound
        context.receivers.add(receiver)

    # tip_timetolive and submission_timetolive need to be converted in seconds since hours and days
    (context.submission_timetolive,
     context.tip_timetolive) = acquire_context_timetolive(request)

    if request['select_all_receivers']:
        if request['maximum_selectable_receivers']:
            log.debug(
                "Resetting maximum_selectable_receivers (%d) because 'select_all_receivers' is True"
                % request['maximum_selectable_receivers'])
        request['maximum_selectable_receivers'] = 0

    try:
        fo = structures.Fields(context.localized_fields, context.unique_fields)
        fo.update_fields(language, request['fields'])
        fo.context_import(context)
    except Exception as excep:
        log.err("Unable to update fields: %s" % excep)
        raise excep

    context.last_update = datetime_now()

    try:
        context.update(request)
    except Exception as dberror:
        log.err("Unable to update context %s: %s" % (context.name, dberror))
        raise errors.InvalidInputFormat(dberror)

    return admin_serialize_context(context, language)
Пример #9
0
def db_create_context(store,
                      request,
                      language=GLSetting.memory_copy.default_language):
    """
    Creates a new context from the request of a client.

    We associate to the context the list of receivers and if the receiver is
    not valid we raise a ReceiverIdNotFound exception.

    Args:
        (dict) the request containing the keys to set on the model.

    Returns:
        (dict) representing the configured context
    """
    receivers = request.get('receivers', [])

    mo = structures.Rosetta()
    mo.acquire_request(language, request, Context)
    for attr in mo.get_localized_attrs():
        request[attr] = mo.get_localized_dict(attr)

    context = Context(request)

    try:
        fo = structures.Fields(context.localized_fields, context.unique_fields)
        # When a new context is created, if no fields has been assigned assigns defaults
        # fields are treated as missing in 3 cases: key missing, != list, list empty
        if 'fields' not in request or \
            not isinstance(request['fields'], list) or \
            not request['fields']:

            try:
                appdata = store.find(ApplicationData).one()
                fo.default_fields(appdata.fields)
            except Exception as excep:
                log.err("Invalid initialization of ApplicationData [for %s]!" %
                        context.name)
                log.err(excep)
                raise excep

        else:
            # print "?? :( Fields supply by the source", request['fields'], "in lang:", language
            fo.update_fields(language, request['fields'])

        fo.context_import(context)

    except Exception as excep:
        log.err("Unable to create fields: %s" % excep)
        raise excep

    # Integrity checks related on name (need to exists, need to be unique)
    # are performed only using the default language at the moment (XXX)
    try:
        context_name = request['name'][language]
    except Exception as excep:
        raise errors.InvalidInputFormat("language %s do not provide name: %s" %
                                        (language, excep))
    if len(context_name) < 1:
        log.err("Invalid request: name is an empty string")
        raise errors.InvalidInputFormat(
            "Context name is missing (1 char required)")

    if context.escalation_threshold and context.selectable_receiver:
        log.err("Parameter conflict in context creation")
        raise errors.ContextParameterConflict

    if request['select_all_receivers']:
        if request['maximum_selectable_receivers']:
            log.debug(
                "Resetting maximum_selectable_receivers (%d) because 'select_all_receivers' is True"
                % request['maximum_selectable_receivers'])
        request['maximum_selectable_receivers'] = 0

    # tip_timetolive and submission_timetolive need to be converted in seconds since hours and days
    (context.submission_timetolive,
     context.tip_timetolive) = acquire_context_timetolive(request)

    c = store.add(context)

    for receiver_id in receivers:
        receiver = store.find(Receiver,
                              Receiver.id == unicode(receiver_id)).one()
        if not receiver:
            log.err("Creation error: unexistent context can't be associated")
            raise errors.ReceiverIdNotFound
        c.receivers.add(receiver)

    log.debug("Created context %s (using %s)" % (context_name, language))
    return admin_serialize_context(context, language)
Пример #10
0
def db_update_node(store,
                   request,
                   wizard_done=True,
                   language=GLSetting.memory_copy.default_language):
    """
    Update the node, setting the last update time on it.

    Password:
        If old_password and password are present, password update is performed

    URLs:
        If one url is present, is properly validated

    Returns:
        the last update time of the node as a :class:`datetime.datetime`
        instance
    """
    node = store.find(Node).one()

    mo = structures.Rosetta()
    mo.acquire_request(language, request, Node)
    for attr in mo.get_localized_attrs():
        request[attr] = mo.get_localized_dict(attr)

    password = request.get('password', None)
    old_password = request.get('old_password', None)

    if password and old_password and len(password) and len(old_password):
        admin = store.find(User, (User.username == unicode('admin'))).one()
        admin.password = security.change_password(admin.password, old_password,
                                                  password, admin.salt)
    try:
        receipt_example = generate_example_receipt(request['receipt_regexp'])

        if len(receipt_example) != 16:
            raise Exception

    except Exception as excep:
        log.err(
            "Only receipt returning 16 bytes are accepted. Sets to default: [0-9]{16}"
        )
        request['receipt_regexp'] = u"[0-9]{16}"
        receipt_example = generate_example_receipt(request['receipt_regexp'])

    # check the 'reset_css' boolean option: remove an existent custom CSS
    if request['reset_css']:
        custom_css_path = os.path.join(GLSetting.static_path,
                                       "%s.css" % GLSetting.reserved_names.css)

        if os.path.isfile(custom_css_path):
            try:
                os.remove(custom_css_path)
                log.debug("Reset on custom CSS done.")
            except Exception as excep:
                log.err("Unable to remove custom CSS: %s: %s" %
                        (custom_css_path, excep))
                raise errors.InternalServerError(excep)
        else:
            log.err("Requested CSS Reset, but custom CSS do not exists")

    # verify that the languages enabled are valid 'code' in the languages supported
    node.languages_enabled = []
    for lang_code in request['languages_enabled']:
        if lang_code in LANGUAGES_SUPPORTED_CODES:
            node.languages_enabled.append(lang_code)
        else:
            raise errors.InvalidInputFormat("Invalid lang code enabled: %s" %
                                            lang_code)

    if not len(node.languages_enabled):
        raise errors.InvalidInputFormat("Missing enabled languages")

    # enforcing of default_language usage (need to be set, need to be _enabled)
    if request['default_language']:

        if request['default_language'] not in LANGUAGES_SUPPORTED_CODES:
            raise errors.InvalidInputFormat("Invalid lang code as default")

        if request['default_language'] not in node.languages_enabled:
            raise errors.InvalidInputFormat("Invalid lang code as default")

        node.default_language = request['default_language']

    else:
        node.default_language = node.languages_enabled[0]
        log.err("Default language not set!? fallback on %s" %
                node.default_language)

    # default False in creation, default False in the option.
    if wizard_done:
        if node.wizard_done:
            log.err("wizard completed more than one time!?")
        else:
            log.debug("wizard completed: Node initialized")
            node.wizard_done = True

    # name, description tor2web boolean value are acquired here
    try:
        node.update(request)
    except Exception as dberror:
        log.err("Unable to update Node: %s" % dberror)
        raise errors.InvalidInputFormat(dberror)

    node.last_update = datetime_now()
    return db_admin_serialize_node(store, language)