示例#1
0
class InternalTip_v_34(models.ModelWithID):
    __storm_table__ = 'internaltip'
    creation_date = DateTime(default_factory=datetime_now)
    update_date = DateTime(default_factory=datetime_now)
    context_id = Unicode()
    questionnaire_hash = Unicode()
    preview = JSON()
    progressive = Int(default=0)
    tor2web = Bool(default=False)
    total_score = Int(default=0)
    expiration_date = DateTime()
    identity_provided = Bool(default=False)
    identity_provided_date = DateTime(default_factory=datetime_null)
    enable_two_way_comments = Bool(default=True)
    enable_two_way_messages = Bool(default=True)
    enable_attachments = Bool(default=True)
    enable_whistleblower_identity = Bool(default=False)
    wb_last_access = DateTime(default_factory=datetime_now)
示例#2
0
class Receiver_v_19(Model):
    __storm_table__ = 'receiver'
    user_id = Unicode()
    name = Unicode()
    description = JSON()
    configuration = Unicode()
    gpg_key_info = Unicode()
    gpg_key_fingerprint = Unicode()
    gpg_key_armor = Unicode()
    gpg_key_expiration = DateTime()
    gpg_key_status = Unicode()
    mail_address = Unicode()
    ping_mail_address = Unicode()
    can_delete_submission = Bool()
    postpone_superpower = Bool()
    last_update = DateTime()
    tip_notification = Bool()
    comment_notification = Bool()
    file_notification = Bool()
    message_notification = Bool()
    ping_notification = Bool()
    presentation_order = Int()
示例#3
0
class SprintAttendance(StormBase):
    """A record of the attendance of a person at a sprint."""

    __storm_table__ = 'SprintAttendance'

    id = Int(primary=True)

    sprint_id = Int(name='sprint')
    sprint = Reference(sprint_id, 'Sprint.id')

    attendeeID = Int(name='attendee', validator=validate_public_person)
    attendee = Reference(attendeeID, 'Person.id')

    time_starts = UtcDateTimeCol(notNull=True)
    time_ends = UtcDateTimeCol(notNull=True)
    _is_physical = Bool(name='is_physical', default=True)

    def __init__(self, sprint, attendee):
        self.sprint = sprint
        self.attendee = attendee

    @property
    def is_physical(self):
        return self.sprint.is_physical and self._is_physical
示例#4
0
class ConfigL10N(models.Model):
    __storm_table__ = 'config_l10n'
    __storm_primary__ = ('lang', 'var_group', 'var_name')

    lang = Unicode()
    var_group = Unicode()
    var_name = Unicode()
    value = Unicode()
    customized = Bool(default=False)

    def __init__(self, lang_code=None, group=None, var_name=None, value='', migrate=False):
        if migrate:
            return

        self.lang = unicode(lang_code)
        self.var_group = unicode(group)
        self.var_name = unicode(var_name)
        self.value = unicode(value)

    def set_v(self, value):
        value = unicode(value)
        if self.value != value:
            self.value = value
            self.customized = True
示例#5
0
class ConfigL10N(Storm):
    __storm_table__ = 'config_l10n'
    __storm_primary__ = ('lang', 'var_group', 'var_name')

    lang = Unicode()
    var_group = Unicode()
    var_name = Unicode()
    value = Unicode()
    customized = Bool(default=False)

    def __init__(self,
                 lang_code=None,
                 group=None,
                 var_name=None,
                 value='',
                 migrate=False):
        if migrate:
            return
        self.lang = unicode(lang_code)
        self.var_group = unicode(group)
        self.var_name = unicode(var_name)
        self.value = unicode(value)

    def __repr__(self):
        return "<ConfigL10N %s::%s.%s::'%s'>" % (self.lang, self.var_group,
                                                 self.var_name, self.value[:5])

    def set_v(self, value):
        value = unicode(value)
        if self.value != value:
            self.value = value
            self.customized = True

    def reset(self, new_value):
        self.set_v(new_value)
        self.customized = False
示例#6
0
class RevisionCache(Storm):
    """A cached version of a recent revision."""

    __storm_table__ = 'RevisionCache'

    id = Int(primary=True)

    revision_id = Int(name='revision', allow_none=False)
    revision = Reference(revision_id, 'Revision.id')

    revision_author_id = Int(name='revision_author', allow_none=False)
    revision_author = Reference(revision_author_id, 'RevisionAuthor.id')

    revision_date = UtcDateTimeCol(notNull=True)

    product_id = Int(name='product', allow_none=True)
    product = Reference(product_id, 'Product.id')

    distroseries_id = Int(name='distroseries', allow_none=True)
    distroseries = Reference(distroseries_id, 'DistroSeries.id')

    sourcepackagename_id = Int(name='sourcepackagename', allow_none=True)
    sourcepackagename = Reference(
        sourcepackagename_id, 'SourcePackageName.id')

    private = Bool(allow_none=False, default=False)

    def __init__(self, revision):
        # Make the revision_author assignment first as traversing to the
        # revision_author of the revision does a query which causes a store
        # flush.  If an assignment has been done already, the RevisionCache
        # object would have been implicitly added to the store, and failes
        # with an integrity check.
        self.revision_author = revision.revision_author
        self.revision = revision
        self.revision_date = revision.revision_date
示例#7
0
class Context(Model):
    """
    This model keeps track of specific contexts settings.
    """
    show_small_cards = Bool(default=False)
    show_receivers = Bool(default=True)
    maximum_selectable_receivers = Int(default=0)
    select_all_receivers = Bool(default=False)
    enable_comments = Bool(default=True)
    enable_private_messages = Bool(default=False)

    tip_timetolive = Int()

    # localized strings
    name = JSON(validator=shortlocal_v)
    description = JSON(validator=longlocal_v)

    # receivers = ReferenceSet(
    #                         Context.id,
    #                         ReceiverContext.context_id,
    #                         ReceiverContext.receiver_id,
    #                         Receiver.id)

    steps_arrangement = Unicode(default=u'horizontal')

    show_receivers_in_alphabetical_order = Bool(default=False)

    presentation_order = Int(default=0)

    unicode_keys = ['steps_arrangement']

    localized_strings = ['name', 'description']

    int_keys = [
        'maximum_selectable_receivers', 'show_receivers_in_alphabetical_order',
        'presentation_order'
    ]

    bool_keys = [
        'select_all_receivers', 'show_small_cards', 'show_receivers',
        'enable_comments', 'enable_private_messages'
    ]
示例#8
0
class Context(Model):
    """
    This model keeps track of specific contexts settings.
    """
    show_small_cards = Bool()
    show_receivers = Bool()
    maximum_selectable_receivers = Int()
    select_all_receivers = Bool()
    enable_private_messages = Bool()

    tip_max_access = Int()
    file_max_download = Int()
    tip_timetolive = Int()
    submission_timetolive = Int()
    last_update = DateTime()

    # localized strings
    name = JSON(validator=shortlocal_v)
    description = JSON(validator=longlocal_v)
    receiver_introduction = JSON(validator=longlocal_v)

    # receivers = ReferenceSet(
    #                         Context.id,
    #                         ReceiverContext.context_id,
    #                         ReceiverContext.receiver_id,
    #                         Receiver.id)

    postpone_superpower = Bool()
    can_delete_submission = Bool()

    presentation_order = Int()

    unicode_keys = []
    localized_strings = ['name', 'description', 'receiver_introduction']
    int_keys = [
        'tip_max_access', 'file_max_download', 'maximum_selectable_receivers',
        'presentation_order'
    ]
    bool_keys = [
        'select_all_receivers', 'postpone_superpower', 'can_delete_submission',
        'show_small_cards', 'show_receivers', "enable_private_messages"
    ]
示例#9
0
class InternalTip(ModelWithID):
    """
    This is the internal representation of a Tip that has been submitted to the
    GlobaLeaks node.

    It has a not associated map for keep track of Receivers, Tips,
    Comments and WhistleblowerTip.
    All of those element has a Storm Reference with the InternalTip.id,
    never vice-versa
    """
    creation_date = DateTime(default_factory=datetime_now)
    update_date = DateTime(default_factory=datetime_now)

    context_id = Unicode()

    questionnaire_hash = Unicode()
    preview = JSON()
    progressive = Int(default=0)
    tor2web = Bool(default=False)
    total_score = Int(default=0)
    expiration_date = DateTime()

    identity_provided = Bool(default=False)
    identity_provided_date = DateTime(default_factory=datetime_null)

    enable_two_way_comments = Bool(default=True)
    enable_two_way_messages = Bool(default=True)
    enable_attachments = Bool(default=True)
    enable_whistleblower_identity = Bool(default=False)

    wb_last_access = DateTime(default_factory=datetime_now)
    wb_access_counter = Int(default=0)

    def wb_revoke_access_date(self):
        revoke_date = self.wb_last_access + timedelta(
            days=GLSettings.memory_copy.wbtip_timetolive)
        return revoke_date

    def is_wb_access_revoked(self):
        return self.whistleblowertip is None
示例#10
0
class Context_v_26(ModelWithID):
    __storm_table__ = 'context'
    show_small_cards = Bool()
    show_context = Bool()
    show_receivers = Bool()
    maximum_selectable_receivers = Int()
    select_all_receivers = Bool()
    enable_comments = Bool()
    enable_messages = Bool()
    enable_two_way_comments = Bool()
    enable_two_way_messages = Bool()
    enable_attachments = Bool()
    enable_whistleblower_identity = Bool()
    tip_timetolive = Int()
    name = JSON()
    description = JSON()
    recipients_clarification = JSON()
    questionnaire_layout = Unicode()
    show_receivers_in_alphabetical_order = Bool()
    presentation_order = Int()
class DistributionSourcePackageInDatabase(Storm):
    """Temporary class to allow access to the database."""

    # XXX: allenap 2008-11-13 bug=297736: This is a temporary measure
    # while DistributionSourcePackage is not yet hooked into the
    # database but we need access to some of the fields in the
    # database.

    __storm_table__ = 'DistributionSourcePackage'

    id = Int(primary=True)

    distribution_id = Int(name='distribution')
    distribution = Reference(distribution_id, 'Distribution.id')

    sourcepackagename_id = Int(name='sourcepackagename')
    sourcepackagename = Reference(sourcepackagename_id, 'SourcePackageName.id')

    bug_reporting_guidelines = Unicode()
    bug_reported_acknowledgement = Unicode()

    bug_count = Int()
    po_message_count = Int()
    is_upstream_link_allowed = Bool()
    enable_bugfiling_duplicate_search = Bool()

    @property
    def currentrelease(self):
        """See `IDistributionSourcePackage`."""
        releases = self.distribution.getCurrentSourceReleases(
            [self.sourcepackagename])
        return releases.get(self)

    # This is a per-thread LRU cache of mappings from (distribution_id,
    # sourcepackagename_id)) to dsp_id. See get() for how this cache helps to
    # avoid database hits without causing consistency issues.
    _cache = ThreadLocalLRUCache(1000, 700)
    # Synchronize the mapping cache with transactions. The mapping is not
    # especially useful after a tranaction completes because Storm invalidates
    # its caches, and leaving the mapping cache in place causes difficult to
    # understand test interactions.
    transaction.manager.registerSynch(_cache)

    @classmethod
    def get(cls, distribution, sourcepackagename):
        """Get a DSP given distribution and source package name.

        Attempts to use a cached `(distro_id, spn_id) --> dsp_id` mapping to
        avoid hitting the database.
        """
        # Check for a cached mapping from (distro_id, spn_id) to dsp_id.
        dsp_cache_key = distribution.id, sourcepackagename.id
        dsp_id = cls._cache.get(dsp_cache_key)
        # If not, fetch from the database.
        if dsp_id is None:
            return cls.getDirect(distribution, sourcepackagename)
        # Try store.get(), allowing Storm to answer from cache if it can.
        store = Store.of(distribution)
        dsp = store.get(DistributionSourcePackageInDatabase, dsp_id)
        # If it's not found, query the database; the mapping might be stale.
        if dsp is None:
            return cls.getDirect(distribution, sourcepackagename)
        # Check that the mapping in the cache was correct.
        if distribution.id != dsp.distribution_id:
            return cls.getDirect(distribution, sourcepackagename)
        if sourcepackagename.id != dsp.sourcepackagename_id:
            return cls.getDirect(distribution, sourcepackagename)
        # Cache hit, phew.
        return dsp

    @classmethod
    def getDirect(cls, distribution, sourcepackagename):
        """Get a DSP given distribution and source package name.

        Caches the `(distro_id, spn_id) --> dsp_id` mapping, but does not
        otherwise use the cache; it always goes to the database.
        """
        dsp = Store.of(distribution).find(
            DistributionSourcePackageInDatabase,
            DistributionSourcePackageInDatabase.sourcepackagename ==
            sourcepackagename, DistributionSourcePackageInDatabase.distribution
            == distribution).one()
        dsp_cache_key = distribution.id, sourcepackagename.id
        if dsp is None:
            pass  # No way to eject things from the cache!
        else:
            cls._cache[dsp_cache_key] = dsp.id
        return dsp

    @classmethod
    def new(cls,
            distribution,
            sourcepackagename,
            is_upstream_link_allowed=False):
        """Create a new DSP with the given parameters.

        Caches the `(distro_id, spn_id) --> dsp_id` mapping.
        """
        dsp = DistributionSourcePackageInDatabase()
        dsp.distribution = distribution
        dsp.sourcepackagename = sourcepackagename
        dsp.is_upstream_link_allowed = is_upstream_link_allowed
        Store.of(distribution).add(dsp)
        Store.of(distribution).flush()
        dsp_cache_key = distribution.id, sourcepackagename.id
        cls._cache[dsp_cache_key] = dsp.id
        return dsp
示例#12
0
class FieldAnswer_v_29(ModelWithID):
    __storm_table__ = 'fieldanswer'
    internaltip_id = Unicode()
    key = Unicode(default=u'')
    is_leaf = Bool(default=True)
    value = Unicode(default=u'')
示例#13
0
class Node_v_26(ModelWithID):
    __storm_table__ = 'node'
    version = Unicode()
    version_db = Unicode()
    name = Unicode()
    public_site = Unicode()
    hidden_service = Unicode()
    receipt_salt = Unicode()
    languages_enabled = JSON()
    default_language = Unicode()
    default_timezone = Int()
    description = JSON()
    presentation = JSON()
    footer = JSON()
    security_awareness_title = JSON()
    security_awareness_text = JSON()
    context_selector_label = JSON()
    maximum_namesize = Int()
    maximum_textsize = Int()
    maximum_filesize = Int()
    tor2web_admin = Bool()
    tor2web_custodian = Bool()
    tor2web_whistleblower = Bool()
    tor2web_receiver = Bool()
    tor2web_unauth = Bool()
    allow_unencrypted = Bool()
    allow_iframes_inclusion = Bool()
    submission_minimum_delay = Int()
    submission_maximum_ttl = Int()
    can_postpone_expiration = Bool()
    can_delete_submission = Bool()
    can_grant_permissions = Bool()
    ahmia = Bool()
    wizard_done = Bool()
    disable_privacy_badge = Bool()
    disable_security_awareness_badge = Bool()
    disable_security_awareness_questions = Bool()
    disable_key_code_hint = Bool()
    disable_donation_panel = Bool()
    enable_captcha = Bool()
    enable_proof_of_work = Bool()
    whistleblowing_question = JSON()
    whistleblowing_button = JSON()
    simplified_login = Bool()
    enable_custom_privacy_badge = Bool()
    custom_privacy_badge_tor = JSON()
    custom_privacy_badge_none = JSON()
    header_title_homepage = JSON()
    header_title_submissionpage = JSON()
    header_title_receiptpage = JSON()
    header_title_tippage = JSON()
    widget_comments_title = JSON()
    widget_messages_title = JSON()
    widget_files_title = JSON()
    landing_page = Unicode()
    show_contexts_in_alphabetical_order = Bool()
    threshold_free_disk_megabytes_high = Int()
    threshold_free_disk_megabytes_medium = Int()
    threshold_free_disk_megabytes_low = Int()
    threshold_free_disk_percentage_high = Int()
    threshold_free_disk_percentage_medium = Int()
    threshold_free_disk_percentage_low = Int()
示例#14
0
class Context(ModelWithID):
    """
    This model keeps track of contexts settings.
    """
    show_small_receiver_cards = Bool(default=False)
    show_context = Bool(default=True)
    show_recipients_details = Bool(default=False)
    allow_recipients_selection = Bool(default=False)
    maximum_selectable_receivers = Int(default=0)
    select_all_receivers = Bool(default=True)

    enable_comments = Bool(default=True)
    enable_messages = Bool(default=False)
    enable_two_way_comments = Bool(default=True)
    enable_two_way_messages = Bool(default=True)
    enable_attachments = Bool(
        default=True)  # Lets WB attach files to submission
    enable_rc_to_wb_files = Bool(default=False)  # The name says it all folks

    tip_timetolive = Int(validator=range_v(-1, 5 * 365),
                         default=15)  # in days, -1 indicates no expiration

    # localized strings
    name = JSON(validator=shortlocal_v)
    description = JSON(validator=longlocal_v)
    recipients_clarification = JSON(validator=longlocal_v)

    status_page_message = JSON(validator=longlocal_v)

    show_receivers_in_alphabetical_order = Bool(default=False)

    presentation_order = Int(default=0)

    questionnaire_id = Unicode()

    img_id = Unicode()

    unicode_keys = ['questionnaire_id']

    localized_keys = [
        'name', 'description', 'recipients_clarification',
        'status_page_message'
    ]

    int_keys = [
        'tip_timetolive', 'maximum_selectable_receivers', 'presentation_order',
        'steps_navigation_requires_completion'
    ]

    bool_keys = [
        'select_all_receivers', 'show_small_receiver_cards', 'show_context',
        'show_recipients_details', 'show_receivers_in_alphabetical_order',
        'allow_recipients_selection', 'enable_comments', 'enable_messages',
        'enable_two_way_comments', 'enable_two_way_messages',
        'enable_attachments', 'enable_rc_to_wb_files'
    ]
示例#15
0
class Notification_v_33(models.ModelWithID):
    __storm_table__ = 'notification'

    server = Unicode(validator=shorttext_v, default=u'demo.globaleaks.org')
    port = Int(default=9267)
    username = Unicode(validator=shorttext_v,
                       default=u'hey_you_should_change_me')
    password = Unicode(validator=shorttext_v,
                       default=u'yes_you_really_should_change_me')
    source_name = Unicode(
        validator=shorttext_v,
        default=u'GlobaLeaks - CHANGE EMAIL ACCOUNT USED FOR NOTIFICATION')
    source_email = Unicode(validator=shorttext_v,
                           default=u'*****@*****.**')
    security = Unicode(validator=shorttext_v, default=u'TLS')
    admin_pgp_alert_mail_title = JSON(validator=longlocal_v)
    admin_pgp_alert_mail_template = JSON(validator=longlocal_v)
    admin_anomaly_mail_template = JSON(validator=longlocal_v)
    admin_anomaly_mail_title = JSON(validator=longlocal_v)
    admin_anomaly_disk_low = JSON(validator=longlocal_v)
    admin_anomaly_disk_medium = JSON(validator=longlocal_v)
    admin_anomaly_disk_high = JSON(validator=longlocal_v)
    admin_anomaly_activities = JSON(validator=longlocal_v)
    admin_test_static_mail_template = JSON(validator=longlocal_v)
    admin_test_static_mail_title = JSON(validator=longlocal_v)
    tip_mail_template = JSON(validator=longlocal_v)
    tip_mail_title = JSON(validator=longlocal_v)
    file_mail_template = JSON(validator=longlocal_v)
    file_mail_title = JSON(validator=longlocal_v)
    comment_mail_template = JSON(validator=longlocal_v)
    comment_mail_title = JSON(validator=longlocal_v)
    message_mail_template = JSON(validator=longlocal_v)
    message_mail_title = JSON(validator=longlocal_v)
    tip_expiration_mail_template = JSON(validator=longlocal_v)
    tip_expiration_mail_title = JSON(validator=longlocal_v)
    pgp_alert_mail_title = JSON(validator=longlocal_v)
    pgp_alert_mail_template = JSON(validator=longlocal_v)
    receiver_notification_limit_reached_mail_template = JSON(
        validator=longlocal_v)
    receiver_notification_limit_reached_mail_title = JSON(
        validator=longlocal_v)
    export_template = JSON(validator=longlocal_v)
    export_message_recipient = JSON(validator=longlocal_v)
    export_message_whistleblower = JSON(validator=longlocal_v)
    identity_access_authorized_mail_template = JSON(validator=longlocal_v)
    identity_access_authorized_mail_title = JSON(validator=longlocal_v)
    identity_access_denied_mail_template = JSON(validator=longlocal_v)
    identity_access_denied_mail_title = JSON(validator=longlocal_v)
    identity_access_request_mail_template = JSON(validator=longlocal_v)
    identity_access_request_mail_title = JSON(validator=longlocal_v)
    identity_provided_mail_template = JSON(validator=longlocal_v)
    identity_provided_mail_title = JSON(validator=longlocal_v)
    disable_admin_notification_emails = Bool(default=False)
    disable_custodian_notification_emails = Bool(default=False)
    disable_receiver_notification_emails = Bool(default=False)
    send_email_for_every_event = Bool(default=True)
    tip_expiration_threshold = Int(validator=natnum_v, default=72)
    notification_threshold_per_hour = Int(validator=natnum_v, default=20)
    notification_suspension_time = Int(validator=natnum_v, default=(2 * 3600))
    exception_email_address = Unicode(
        validator=shorttext_v,
        default=u'*****@*****.**')
    exception_email_pgp_key_fingerprint = Unicode(default=u'')
    exception_email_pgp_key_public = Unicode(default=u'')
    exception_email_pgp_key_expiration = DateTime(
        default_factory=datetime_null)

    localized_keys = [
        'admin_anomaly_mail_title', 'admin_anomaly_mail_template',
        'admin_anomaly_disk_low', 'admin_anomaly_disk_medium',
        'admin_anomaly_disk_high', 'admin_anomaly_activities',
        'admin_pgp_alert_mail_title', 'admin_pgp_alert_mail_template',
        'admin_test_static_mail_template', 'admin_test_static_mail_title',
        'pgp_alert_mail_title', 'pgp_alert_mail_template', 'tip_mail_template',
        'tip_mail_title', 'file_mail_template', 'file_mail_title',
        'comment_mail_template', 'comment_mail_title', 'message_mail_template',
        'message_mail_title', 'tip_expiration_mail_template',
        'tip_expiration_mail_title',
        'receiver_notification_limit_reached_mail_template',
        'receiver_notification_limit_reached_mail_title',
        'identity_access_authorized_mail_template',
        'identity_access_authorized_mail_title',
        'identity_access_denied_mail_template',
        'identity_access_denied_mail_title',
        'identity_access_request_mail_template',
        'identity_access_request_mail_title',
        'identity_provided_mail_template', 'identity_provided_mail_title',
        'export_template', 'export_message_whistleblower',
        'export_message_recipient'
    ]
class SourcePackageRecipe(Storm):
    """See `ISourcePackageRecipe` and `ISourcePackageRecipeSource`."""

    __storm_table__ = 'SourcePackageRecipe'

    def __str__(self):
        return '%s/%s' % (self.owner.name, self.name)

    implements(ISourcePackageRecipe)

    classProvides(ISourcePackageRecipeSource)

    delegates(ISourcePackageRecipeData, context='_recipe_data')

    id = Int(primary=True)

    daily_build_archive_id = Int(name='daily_build_archive', allow_none=True)
    daily_build_archive = Reference(daily_build_archive_id, 'Archive.id')

    date_created = UtcDateTimeCol(notNull=True)
    date_last_modified = UtcDateTimeCol(notNull=True)

    owner_id = Int(name='owner', allow_none=True)
    owner = Reference(owner_id, 'Person.id')

    registrant_id = Int(name='registrant', allow_none=True)
    registrant = Reference(registrant_id, 'Person.id')

    distroseries = ReferenceSet(
        id, _SourcePackageRecipeDistroSeries.sourcepackagerecipe_id,
        _SourcePackageRecipeDistroSeries.distroseries_id, DistroSeries.id)

    build_daily = Bool()

    is_stale = Bool()

    @property
    def _sourcepackagename_text(self):
        return self.sourcepackagename.name

    name = Unicode(allow_none=True)
    description = Unicode(allow_none=True)

    @cachedproperty
    def _recipe_data(self):
        return Store.of(self).find(
            SourcePackageRecipeData,
            SourcePackageRecipeData.sourcepackage_recipe == self).one()

    @property
    def builder_recipe(self):
        """Accesses of the recipe go to the SourcePackageRecipeData."""
        return self._recipe_data.getRecipe()

    @property
    def base_branch(self):
        return self._recipe_data.base_branch

    @staticmethod
    def preLoadDataForSourcePackageRecipes(sourcepackagerecipes):
        # Load the referencing SourcePackageRecipeData.
        spr_datas = load_referencing(SourcePackageRecipeData,
                                     sourcepackagerecipes,
                                     ['sourcepackage_recipe_id'])
        # Load the related branches.
        load_related(Branch, spr_datas, ['base_branch_id'])
        # Store the SourcePackageRecipeData in the sourcepackagerecipes
        # objects.
        for spr_data in spr_datas:
            cache = get_property_cache(spr_data.sourcepackage_recipe)
            cache._recipe_data = spr_data
        SourcePackageRecipeData.preLoadReferencedBranches(spr_datas)

    def setRecipeText(self, recipe_text):
        parsed = SourcePackageRecipeData.getParsedRecipe(recipe_text)
        self._recipe_data.setRecipe(parsed)

    @property
    def recipe_text(self):
        return self.builder_recipe.get_recipe_text()

    def updateSeries(self, distroseries):
        if distroseries != self.distroseries:
            self.distroseries.clear()
            for distroseries_item in distroseries:
                self.distroseries.add(distroseries_item)

    @staticmethod
    def new(registrant,
            owner,
            name,
            recipe,
            description,
            distroseries=None,
            daily_build_archive=None,
            build_daily=False,
            date_created=DEFAULT):
        """See `ISourcePackageRecipeSource.new`."""
        store = IMasterStore(SourcePackageRecipe)
        sprecipe = SourcePackageRecipe()
        builder_recipe = SourcePackageRecipeData.getParsedRecipe(recipe)
        SourcePackageRecipeData(builder_recipe, sprecipe)
        sprecipe.registrant = registrant
        sprecipe.owner = owner
        sprecipe.name = name
        if distroseries is not None:
            for distroseries_item in distroseries:
                sprecipe.distroseries.add(distroseries_item)
        sprecipe.description = description
        sprecipe.daily_build_archive = daily_build_archive
        sprecipe.build_daily = build_daily
        sprecipe.date_created = date_created
        sprecipe.date_last_modified = date_created
        store.add(sprecipe)
        return sprecipe

    @staticmethod
    def findStaleDailyBuilds():
        one_day_ago = datetime.now(utc) - timedelta(hours=23, minutes=50)
        joins = (
            SourcePackageRecipe,
            LeftJoin(
                SourcePackageRecipeBuild,
                And(
                    SourcePackageRecipeBuild.recipe_id ==
                    SourcePackageRecipe.id, SourcePackageRecipeBuild.archive_id
                    == SourcePackageRecipe.daily_build_archive_id,
                    SourcePackageRecipeBuild.date_created > one_day_ago)),
        )
        return IStore(SourcePackageRecipe).using(*joins).find(
            SourcePackageRecipe,
            SourcePackageRecipe.is_stale == True,
            SourcePackageRecipe.build_daily == True,
            SourcePackageRecipeBuild.date_created == None,
        ).config(distinct=True)

    @staticmethod
    def exists(owner, name):
        """See `ISourcePackageRecipeSource.new`."""
        store = IMasterStore(SourcePackageRecipe)
        recipe = store.find(SourcePackageRecipe,
                            SourcePackageRecipe.owner == owner,
                            SourcePackageRecipe.name == name).one()
        if recipe:
            return True
        else:
            return False

    def destroySelf(self):
        store = Store.of(self)
        self.distroseries.clear()
        self._recipe_data.instructions.find().remove()
        builds = store.find(SourcePackageRecipeBuild,
                            SourcePackageRecipeBuild.recipe == self)
        builds.set(recipe_id=None)
        store.remove(self._recipe_data)
        store.remove(self)

    def isOverQuota(self, requester, distroseries):
        """See `ISourcePackageRecipe`."""
        return SourcePackageRecipeBuild.getRecentBuilds(
            requester, self, distroseries).count() >= 5

    def containsUnbuildableSeries(self, archive):
        buildable_distros = set(BuildableDistroSeries.findSeries(
            archive.owner))
        return len(set(self.distroseries).difference(buildable_distros)) >= 1

    def requestBuild(self,
                     archive,
                     requester,
                     distroseries,
                     pocket=PackagePublishingPocket.RELEASE,
                     manual=False):
        """See `ISourcePackageRecipe`."""
        if not archive.is_ppa:
            raise NonPPABuildRequest

        buildable_distros = BuildableDistroSeries.findSeries(archive.owner)
        if distroseries not in buildable_distros:
            raise BuildNotAllowedForDistro(self, distroseries)

        reject_reason = archive.checkUpload(requester, distroseries, None,
                                            archive.default_component, pocket)
        if reject_reason is not None:
            raise reject_reason
        if self.isOverQuota(requester, distroseries):
            raise TooManyBuilds(self, distroseries)
        pending = IStore(self).find(
            SourcePackageRecipeBuild,
            SourcePackageRecipeBuild.recipe_id == self.id,
            SourcePackageRecipeBuild.distroseries_id == distroseries.id,
            SourcePackageRecipeBuild.archive_id == archive.id,
            SourcePackageRecipeBuild.status == BuildStatus.NEEDSBUILD)
        if pending.any() is not None:
            raise BuildAlreadyPending(self, distroseries)

        build = getUtility(ISourcePackageRecipeBuildSource).new(
            distroseries, self, requester, archive)
        build.queueBuild()
        queue_record = build.buildqueue_record
        if manual:
            queue_record.manualScore(queue_record.lastscore + 100)
        return build

    def performDailyBuild(self):
        """See `ISourcePackageRecipe`."""
        builds = []
        self.is_stale = False
        buildable_distros = set(
            BuildableDistroSeries.findSeries(self.daily_build_archive.owner))
        build_for = set(self.distroseries).intersection(buildable_distros)
        for distroseries in build_for:
            try:
                build = self.requestBuild(self.daily_build_archive, self.owner,
                                          distroseries,
                                          PackagePublishingPocket.RELEASE)
                builds.append(build)
            except BuildAlreadyPending:
                continue
        return builds

    @property
    def builds(self):
        """See `ISourcePackageRecipe`."""
        order_by = (Desc(
            Greatest(SourcePackageRecipeBuild.date_started,
                     SourcePackageRecipeBuild.date_finished)),
                    Desc(SourcePackageRecipeBuild.date_created),
                    Desc(SourcePackageRecipeBuild.id))
        return self._getBuilds(None, order_by)

    @property
    def completed_builds(self):
        """See `ISourcePackageRecipe`."""
        filter_term = (SourcePackageRecipeBuild.status !=
                       BuildStatus.NEEDSBUILD)
        order_by = (Desc(
            Greatest(SourcePackageRecipeBuild.date_started,
                     SourcePackageRecipeBuild.date_finished)),
                    Desc(SourcePackageRecipeBuild.id))
        return self._getBuilds(filter_term, order_by)

    @property
    def pending_builds(self):
        """See `ISourcePackageRecipe`."""
        filter_term = (
            SourcePackageRecipeBuild.status == BuildStatus.NEEDSBUILD)
        # We want to order by date_created but this is the same as ordering
        # by id (since id increases monotonically) and is less expensive.
        order_by = Desc(SourcePackageRecipeBuild.id)
        return self._getBuilds(filter_term, order_by)

    def _getBuilds(self, filter_term, order_by):
        """The actual query to get the builds."""
        query_args = [
            SourcePackageRecipeBuild.recipe == self,
            SourcePackageRecipeBuild.archive_id == Archive.id,
            Archive._enabled == True,
        ]
        if filter_term is not None:
            query_args.append(filter_term)
        result = Store.of(self).find(SourcePackageRecipeBuild, *query_args)
        result.order_by(order_by)
        return result

    def getPendingBuildInfo(self):
        """See `ISourcePackageRecipe`."""
        builds = self.pending_builds
        result = []
        for build in builds:
            result.append({
                "distroseries":
                build.distroseries.displayname,
                "archive":
                '%s/%s' % (build.archive.owner.name, build.archive.name)
            })
        return result

    @property
    def last_build(self):
        """See `ISourcePackageRecipeBuild`."""
        return self._getBuilds(
            True, Desc(SourcePackageRecipeBuild.date_finished)).first()

    def getMedianBuildDuration(self):
        """Return the median duration of builds of this recipe."""
        store = IStore(self)
        result = store.find(SourcePackageRecipeBuild,
                            SourcePackageRecipeBuild.recipe == self.id,
                            SourcePackageRecipeBuild.date_finished != None)
        durations = [
            build.date_finished - build.date_started for build in result
        ]
        if len(durations) == 0:
            return None
        durations.sort(reverse=True)
        return durations[len(durations) / 2]
示例#17
0
class PackageCopyRequest(Storm):
    """See `IPackageCopyRequest`."""
    __storm_table__ = 'PackageCopyRequest'
    id = Int(primary=True)

    target_archive_id = Int(name='target_archive', allow_none=False)
    target_archive = Reference(target_archive_id, 'Archive.id')
    target_distroseries_id = Int(name='target_distroseries', allow_none=True)
    target_distroseries = Reference(target_distroseries_id, 'DistroSeries.id')
    target_component_id = Int(name='target_component', allow_none=True)
    target_component = Reference(target_component_id, 'Component.id')
    target_pocket = Enum(map=_construct_enum_mapping(PackagePublishingPocket))

    copy_binaries = Bool(allow_none=False, default=False)

    source_archive_id = Int(name='source_archive', allow_none=False)
    source_archive = Reference(source_archive_id, 'Archive.id')
    source_distroseries_id = Int(name='source_distroseries', allow_none=True)
    source_distroseries = Reference(source_distroseries_id, 'DistroSeries.id')
    source_component_id = Int(name='source_component', allow_none=True)
    source_component = Reference(source_component_id, 'Component.id')
    source_pocket = Enum(map=_construct_enum_mapping(PackagePublishingPocket))

    requester_id = Int(name='requester', allow_none=False)
    requester = Reference(requester_id, 'Person.id')

    requester_id = Int(name='requester',
                       allow_none=False,
                       validator=validate_public_person)
    requester = Reference(requester_id, 'Person.id')

    status = Enum(allow_none=False,
                  map=_construct_enum_mapping(PackageCopyStatus))
    reason = Unicode(allow_none=True)

    date_created = DateTime(allow_none=False, default=UTC_NOW)
    date_started = DateTime(allow_none=True)
    date_completed = DateTime(allow_none=True)

    def __str__(self):
        """See `IPackageCopyRequest`."""
        def get_name_or_nothing(property_name, nothing='-'):
            """Helper method, returns property value if set or 'nothing'."""
            property = getattr(self, property_name, None)

            # Return straight-away if property is not set.
            if property is None:
                return nothing

            # Does the property have a name?
            name = getattr(property, 'name', None)
            if name is not None:
                return str(name)

            # Does the property have a title?
            title = getattr(property, 'title', None)
            if title is not None:
                return str(title)

            # Return the string representation of the property as a last
            # resort.
            return str(property)

        result = (
            "Package copy request\n"
            "source = %s/%s/%s/%s\ntarget = %s/%s/%s/%s\n"
            "copy binaries: %s\nrequester: %s\nstatus: %s\n"
            "date created: %s\ndate started: %s\ndate completed: %s" %
            (get_name_or_nothing('source_archive'),
             get_name_or_nothing('source_distroseries'),
             get_name_or_nothing('source_component'),
             get_name_or_nothing('source_pocket'),
             get_name_or_nothing('target_archive'),
             get_name_or_nothing('target_distroseries'),
             get_name_or_nothing('target_component'),
             get_name_or_nothing('target_pocket'),
             get_name_or_nothing('copy_binaries'),
             get_name_or_nothing('requester'), get_name_or_nothing('status'),
             get_name_or_nothing('date_created'),
             get_name_or_nothing('date_started'),
             get_name_or_nothing('date_completed')))
        return result

    def markAsInprogress(self):
        """See `IPackageCopyRequest`."""
        self.status = PackageCopyStatus.INPROGRESS
        self.date_started = UTC_NOW

    def markAsCompleted(self):
        """See `IPackageCopyRequest`."""
        self.status = PackageCopyStatus.COMPLETE
        self.date_completed = UTC_NOW

    def markAsFailed(self):
        """See `IPackageCopyRequest`."""
        self.status = PackageCopyStatus.FAILED
        self.date_completed = UTC_NOW

    def markAsCanceling(self):
        """See `IPackageCopyRequest`."""
        self.status = PackageCopyStatus.CANCELING

    def markAsCancelled(self):
        """See `IPackageCopyRequest`."""
        self.status = PackageCopyStatus.CANCELLED
        self.date_completed = UTC_NOW
示例#18
0
class Notification(Model):
    """
    This table has only one instance, and contain all the notification
    information for the node templates are imported in the handler, but
    settings are expected all at once.
    """
    server = Unicode(validator=shorttext_v, default=u"mail.headstrong.de")
    port = Int(default=587)

    username = Unicode(validator=shorttext_v,
                       default=u"*****@*****.**")
    password = Unicode(validator=shorttext_v, default=u"sendaccount99")

    source_name = Unicode(validator=shorttext_v,
                          default=u"Default GlobaLeaks sender")
    source_email = Unicode(validator=shorttext_v,
                           default=u"*****@*****.**")

    security = Unicode(validator=shorttext_v, default=u"TLS")
    # security_types: 'TLS', 'SSL'

    torify = Int(default=True)

    # Admin Template
    admin_pgp_alert_mail_title = JSON(validator=longlocal_v)
    admin_pgp_alert_mail_template = JSON(validator=longlocal_v)
    admin_anomaly_mail_template = JSON(validator=longlocal_v)
    admin_anomaly_mail_title = JSON(validator=longlocal_v)
    admin_anomaly_disk_low = JSON(validator=longlocal_v)
    admin_anomaly_disk_medium = JSON(validator=longlocal_v)
    admin_anomaly_disk_high = JSON(validator=longlocal_v)
    admin_anomaly_activities = JSON(validator=longlocal_v)

    # Receiver Template
    tip_mail_template = JSON(validator=longlocal_v)
    tip_mail_title = JSON(validator=longlocal_v)
    file_mail_template = JSON(validator=longlocal_v)
    file_mail_title = JSON(validator=longlocal_v)
    comment_mail_template = JSON(validator=longlocal_v)
    comment_mail_title = JSON(validator=longlocal_v)
    message_mail_template = JSON(validator=longlocal_v)
    message_mail_title = JSON(validator=longlocal_v)
    tip_expiration_mail_template = JSON(validator=longlocal_v)
    tip_expiration_mail_title = JSON(validator=longlocal_v)
    pgp_alert_mail_title = JSON(validator=longlocal_v)
    pgp_alert_mail_template = JSON(validator=longlocal_v)
    receiver_notification_limit_reached_mail_template = JSON(
        validator=longlocal_v)
    receiver_notification_limit_reached_mail_title = JSON(
        validator=longlocal_v)
    zip_description = JSON(validator=longlocal_v)

    # Experimental Receiver template
    ping_mail_template = JSON(validator=longlocal_v)
    ping_mail_title = JSON(validator=longlocal_v)
    notification_digest_mail_title = JSON(validator=longlocal_v)

    disable_admin_notification_emails = Bool(default=False)
    disable_receivers_notification_emails = Bool(default=False)
    send_email_for_every_event = Bool(default=True)

    notification_threshold_per_hour = Int(default=20)
    notification_suspension_time = Int(default=(2 * 3600))

    unicode_keys = [
        'server', 'username', 'password', 'source_name', 'source_email',
        'security'
    ]

    localized_strings = [
        'admin_anomaly_mail_title', 'admin_anomaly_mail_template',
        'admin_anomaly_disk_low', 'admin_anomaly_disk_medium',
        'admin_anomaly_disk_high', 'admin_anomaly_activities',
        'admin_pgp_alert_mail_title', 'admin_pgp_alert_mail_template',
        'pgp_alert_mail_title', 'pgp_alert_mail_template', 'tip_mail_template',
        'tip_mail_title', 'file_mail_template', 'file_mail_title',
        'comment_mail_template', 'comment_mail_title', 'message_mail_template',
        'message_mail_title', 'tip_expiration_mail_template',
        'tip_expiration_mail_title', 'notification_digest_mail_title',
        'zip_description', 'ping_mail_template', 'ping_mail_title',
        'receiver_notification_limit_reached_mail_template',
        'receiver_notification_limit_reached_mail_title'
    ]

    int_keys = [
        'port', 'notification_threshold_per_hour',
        'notification_suspension_time'
    ]

    bool_keys = [
        'disable_admin_notification_emails',
        'disable_receivers_notification_emails', 'send_email_for_every_event'
    ]
示例#19
0
class Notification(Model):
    """
    This table has only one instance, and contain all the notification
    information for the node templates are imported in the handler, but
    settings are expected all at once.
    """
    server = Unicode()
    port = Int()
    username = Unicode()
    password = Unicode()

    source_name = Unicode(validator=shorttext_v)
    source_email = Unicode(validator=shorttext_v)

    security = Unicode()
    # security_types = [u'TLS', u'SSL']

    admin_anomaly_template = JSON(validator=longlocal_v)

    encrypted_tip_template = JSON(validator=longlocal_v)
    encrypted_tip_mail_title = JSON(validator=longlocal_v)
    plaintext_tip_template = JSON(validator=longlocal_v)
    plaintext_tip_mail_title = JSON(validator=longlocal_v)

    encrypted_file_template = JSON(validator=longlocal_v)
    encrypted_file_mail_title = JSON(validator=longlocal_v)
    plaintext_file_template = JSON(validator=longlocal_v)
    plaintext_file_mail_title = JSON(validator=longlocal_v)

    encrypted_comment_template = JSON(validator=longlocal_v)
    encrypted_comment_mail_title = JSON(validator=longlocal_v)
    plaintext_comment_template = JSON(validator=longlocal_v)
    plaintext_comment_mail_title = JSON(validator=longlocal_v)

    encrypted_message_template = JSON(validator=longlocal_v)
    encrypted_message_mail_title = JSON(validator=longlocal_v)
    plaintext_message_template = JSON(validator=longlocal_v)
    plaintext_message_mail_title = JSON(validator=longlocal_v)

    admin_pgp_alert_mail_title = JSON(validator=longlocal_v)
    admin_pgp_alert_mail_template = JSON(validator=longlocal_v)
    pgp_alert_mail_title = JSON(validator=longlocal_v)
    pgp_alert_mail_template = JSON(validator=longlocal_v)

    zip_description = JSON(validator=longlocal_v)

    ping_mail_template = JSON(validator=longlocal_v)
    ping_mail_title = JSON(validator=longlocal_v)

    disable_admin_notification_emails = Bool(default=False)
    disable_receivers_notification_emails = Bool(default=False)

    unicode_keys = [
        'server', 'username', 'password', 'source_name', 'source_email',
        'security'
    ]
    localized_strings = [
        'admin_anomaly_template', 'admin_pgp_alert_mail_title',
        'admin_pgp_alert_mail_template', 'pgp_alert_mail_title',
        'pgp_alert_mail_template', 'encrypted_tip_template',
        'encrypted_tip_mail_title', 'plaintext_tip_template',
        'plaintext_tip_mail_title', 'encrypted_file_template',
        'encrypted_file_mail_title', 'plaintext_file_template',
        'plaintext_file_mail_title', 'encrypted_comment_template',
        'encrypted_comment_mail_title', 'plaintext_comment_template',
        'plaintext_comment_mail_title', 'encrypted_message_template',
        'encrypted_message_mail_title', 'plaintext_message_template',
        'plaintext_message_mail_title', 'zip_description',
        'ping_mail_template', 'ping_mail_title'
    ]
    int_keys = [
        'port', 'disable_admin_notification_emails',
        'disable_receivers_notification_emails'
    ]
示例#20
0
class Node(Model):
    """
    This table has only one instance, has the "id", but would not exists a
    second element of this table. This table acts, more or less, like the
    configuration file of the previous GlobaLeaks release (and some of the GL
    0.1 details are specified in Context)

    This table represent the System-wide settings
    """
    name = Unicode(validator=shorttext_v)
    public_site = Unicode(validator=shorttext_v)
    hidden_service = Unicode(validator=shorttext_v)
    email = Unicode(validator=shorttext_v)
    receipt_salt = Unicode(validator=shorttext_v)

    languages_enabled = JSON()
    default_language = Unicode(validator=shorttext_v)
    default_timezone = Int(default=0)

    # localized strings
    description = JSON(validator=longlocal_v)
    presentation = JSON(validator=longlocal_v)
    footer = JSON(validator=longlocal_v)
    security_awareness_title = JSON(validator=longlocal_v)
    security_awareness_text = JSON(validator=longlocal_v)
    context_selector_label = JSON(validator=longlocal_v)

    # Advanced settings
    maximum_namesize = Int()
    maximum_textsize = Int()
    maximum_filesize = Int()
    tor2web_admin = Bool()
    tor2web_submission = Bool()
    tor2web_receiver = Bool()
    tor2web_unauth = Bool()
    allow_unencrypted = Bool()
    allow_iframes_inclusion = Bool()
    submission_minimum_delay = Int(default=10)
    submission_maximum_ttl = Int(default=10800)

    # privileges configurable in node/context/receiver
    can_postpone_expiration = Bool(default=False)
    can_delete_submission = Bool(default=False)

    ahmia = Bool(default=False)
    wizard_done = Bool(default=False)

    disable_privacy_badge = Bool(default=False)
    disable_security_awareness_badge = Bool(default=False)
    disable_security_awareness_questions = Bool(default=False)
    disable_key_code_hint = Bool(default=False)

    whistleblowing_question = JSON(validator=longlocal_v)
    whistleblowing_button = JSON(validator=longlocal_v)

    enable_custom_privacy_badge = Bool(default=False)
    custom_privacy_badge_tor = JSON(validator=longlocal_v)
    custom_privacy_badge_none = JSON(validator=longlocal_v)

    header_title_homepage = JSON(validator=longlocal_v)
    header_title_submissionpage = JSON(validator=longlocal_v)
    header_title_receiptpage = JSON(validator=longlocal_v)

    landing_page = Unicode()

    show_contexts_in_alphabetical_order = Bool(default=False)

    exception_email = Unicode()

    unicode_keys = [
        'name', 'public_site', 'email', 'hidden_service', 'exception_email',
        'default_language', 'landing_page'
    ]

    int_keys = [
        'maximum_namesize', 'maximum_textsize', 'maximum_filesize',
        'default_timezone', 'show_contexts_in_alphabetical_order',
        'submission_minimum_delay', 'submission_maximum_ttl'
    ]

    bool_keys = [
        'tor2web_admin', 'tor2web_receiver', 'tor2web_submission',
        'tor2web_unauth', 'can_postpone_expiration', 'can_delete_submission',
        'ahmia', 'allow_unencrypted', 'allow_iframes_inclusion',
        'disable_privacy_badge', 'disable_security_awareness_badge',
        'disable_security_awareness_questions', 'enable_custom_privacy_badge',
        'disable_key_code_hint'
    ]

    # wizard_done is not checked because it's set by the backend

    localized_strings = [
        'description', 'presentation', 'footer', 'security_awareness_title',
        'security_awareness_text', 'whistleblowing_question',
        'whistleblowing_button', 'custom_privacy_badge_tor',
        'custom_privacy_badge_none', 'header_title_homepage',
        'header_title_submissionpage', 'header_title_receiptpage',
        'context_selector_label'
    ]
示例#21
0
class Field(Model):
    label = JSON(validator=shortlocal_v)
    description = JSON(validator=longlocal_v)
    hint = JSON(validator=shortlocal_v)

    multi_entry = Bool()
    required = Bool()
    preview = Bool()

    # This is set if the field should be duplicated for collecting statistics
    # when encryption is enabled.
    stats_enabled = Bool()

    # This indicates that this field should be used as a template for composing
    # new steps.
    is_template = Bool()

    x = Int()
    y = Int()

    type = Unicode()
    # Supported field types:
    # * inputbox
    # * textarea
    # * selectbox
    # * checkbox
    # * modal
    # * dialog
    # * tos
    # * fieldgroup

    # When only 1 option
    # {
    #     "trigger": field_id
    # }

    # When multiple options
    # [
    #     {
    #         "name": lang_dict,
    #         "x": int,
    #         "y": int,
    #         "description": lang_dict,
    #         "trigger": field_id
    #     }, ...
    # ]

    unicode_keys = ['type']
    int_keys = ['x', 'y']
    localized_strings = ['label', 'description', 'hint']
    bool_keys = [
        'multi_entry', 'preview', 'required', 'stats_enabled', 'is_template'
    ]

    # XXX the instance already knows about the store, are we sure there's no way
    # to obtain it?
    def delete(self, store):
        for child in self.children:
            child.delete(store)
        store.remove(self)

    def copy(self, store, is_template):
        obj_copy = self.__class__()
        obj_copy.label = copy.deepcopy(self.label)
        obj_copy.description = copy.deepcopy(self.label)
        obj_copy.hint = copy.deepcopy(self.label)
        obj_copy.multi_entry = self.multi_entry
        obj_copy.required = self.required
        obj_copy.stats_enabled = self.stats_enabled
        obj_copy.is_template = is_template
        obj_copy.x = self.x
        obj_copy.y = self.y
        obj_copy.type = self.type
        for child in self.children:
            child_copy = child.copy(store, is_template)
            obj_copy.children.add(child_copy)
        for opt in self.options:
            opt_copy = opt.copy(store)
            obj_copy.options.add(opt_copy)
        store.add(obj_copy)
        return obj_copy
示例#22
0
class Node_v_33(models.ModelWithID):
    __storm_table__ = 'node'

    version = Unicode()
    version_db = Unicode()
    name = Unicode(validator=shorttext_v, default=u'')
    basic_auth = Bool(default=False)
    basic_auth_username = Unicode(default=u'')
    basic_auth_password = Unicode(default=u'')
    public_site = Unicode(validator=shorttext_v, default=u'')
    hidden_service = Unicode(validator=shorttext_v, default=u'')
    tb_download_link = Unicode(
        validator=shorttext_v,
        default=u'https://www.torproject.org/download/download')
    receipt_salt = Unicode(validator=shorttext_v)
    languages_enabled = JSON()
    default_language = Unicode(validator=shorttext_v, default=u'en')
    default_password = Unicode(validator=longtext_v, default=u'globaleaks')
    description = JSON(validator=longlocal_v, default_factory=dict)
    presentation = JSON(validator=longlocal_v, default_factory=dict)
    footer = JSON(validator=longlocal_v, default_factory=dict)
    security_awareness_title = JSON(validator=longlocal_v,
                                    default_factory=dict)
    security_awareness_text = JSON(validator=longlocal_v, default_factory=dict)
    maximum_namesize = Int(validator=natnum_v, default=128)
    maximum_textsize = Int(validator=natnum_v, default=4096)
    maximum_filesize = Int(validator=natnum_v, default=30)
    tor2web_admin = Bool(default=True)
    tor2web_custodian = Bool(default=True)
    tor2web_whistleblower = Bool(default=False)
    tor2web_receiver = Bool(default=True)
    tor2web_unauth = Bool(default=True)
    allow_unencrypted = Bool(default=False)
    disable_encryption_warnings = Bool(default=False)
    allow_iframes_inclusion = Bool(default=False)
    submission_minimum_delay = Int(validator=natnum_v, default=10)
    submission_maximum_ttl = Int(validator=natnum_v, default=10800)
    can_postpone_expiration = Bool(default=False)
    can_delete_submission = Bool(default=False)
    can_grant_permissions = Bool(default=False)
    ahmia = Bool(default=False)
    allow_indexing = Bool(default=False)
    wizard_done = Bool(default=False)
    disable_submissions = Bool(default=False)
    disable_privacy_badge = Bool(default=False)
    disable_security_awareness_badge = Bool(default=False)
    disable_security_awareness_questions = Bool(default=False)
    disable_key_code_hint = Bool(default=False)
    disable_donation_panel = Bool(default=False)
    enable_captcha = Bool(default=True)
    enable_proof_of_work = Bool(default=True)
    enable_experimental_features = Bool(default=False)
    whistleblowing_question = JSON(validator=longlocal_v, default_factory=dict)
    whistleblowing_button = JSON(validator=longlocal_v, default_factory=dict)
    whistleblowing_receipt_prompt = JSON(validator=longlocal_v,
                                         default_factory=dict)
    simplified_login = Bool(default=True)
    enable_custom_privacy_badge = Bool(default=False)
    custom_privacy_badge_tor = JSON(validator=longlocal_v,
                                    default_factory=dict)
    custom_privacy_badge_none = JSON(validator=longlocal_v,
                                     default_factory=dict)
    header_title_homepage = JSON(validator=longlocal_v, default_factory=dict)
    header_title_submissionpage = JSON(validator=longlocal_v,
                                       default_factory=dict)
    header_title_receiptpage = JSON(validator=longlocal_v,
                                    default_factory=dict)
    header_title_tippage = JSON(validator=longlocal_v, default_factory=dict)
    widget_comments_title = JSON(validator=shortlocal_v, default_factory=dict)
    widget_messages_title = JSON(validator=shortlocal_v, default_factory=dict)
    widget_files_title = JSON(validator=shortlocal_v, default_factory=dict)
    landing_page = Unicode(default=u'homepage')
    contexts_clarification = JSON(validator=longlocal_v, default_factory=dict)
    show_small_context_cards = Bool(default=False)
    show_contexts_in_alphabetical_order = Bool(default=False)
    wbtip_timetolive = Int(validator=natnum_v, default=90)
    threshold_free_disk_megabytes_high = Int(validator=natnum_v, default=200)
    threshold_free_disk_megabytes_medium = Int(validator=natnum_v, default=500)
    threshold_free_disk_megabytes_low = Int(validator=natnum_v, default=1000)
    threshold_free_disk_percentage_high = Int(default=3)
    threshold_free_disk_percentage_medium = Int(default=5)
    threshold_free_disk_percentage_low = Int(default=10)
    context_selector_type = Unicode(validator=shorttext_v, default=u'list')

    localized_keys = [
        'description', 'presentation', 'footer', 'security_awareness_title',
        'security_awareness_text', 'whistleblowing_question',
        'whistleblowing_button', 'whistleblowing_receipt_prompt',
        'custom_privacy_badge_tor', 'custom_privacy_badge_none',
        'header_title_homepage', 'header_title_submissionpage',
        'header_title_receiptpage', 'header_title_tippage',
        'contexts_clarification', 'widget_comments_title',
        'widget_messages_title', 'widget_files_title'
    ]
示例#23
0
class Node_v_18(Model):
    __storm_table__ = 'node'
    name = Unicode()
    public_site = Unicode()
    hidden_service = Unicode()
    email = Unicode()
    receipt_salt = Unicode()
    last_update = DateTime()
    receipt_regexp = Unicode()
    languages_enabled = JSON()
    default_language = Unicode()
    default_timezone = Int()
    description = JSON()
    presentation = JSON()
    footer = JSON()
    security_awareness_title = JSON()
    security_awareness_text = JSON()
    stats_update_time = Int()
    maximum_namesize = Int()
    maximum_textsize = Int()
    maximum_filesize = Int()
    tor2web_admin = Bool()
    tor2web_submission = Bool()
    tor2web_receiver = Bool()
    tor2web_unauth = Bool()
    allow_unencrypted = Bool()
    allow_iframes_inclusion = Bool()
    postpone_superpower = Bool()
    can_delete_submission = Bool()
    ahmia = Bool()
    wizard_done = Bool()
    disable_privacy_badge = Bool()
    disable_security_awareness_badge = Bool()
    disable_security_awareness_questions = Bool()
    whistleblowing_question = JSON()
    whistleblowing_button = JSON()
    enable_custom_privacy_badge = Bool()
    custom_privacy_badge_tor = JSON()
    custom_privacy_badge_none = JSON()
    header_title_homepage = JSON()
    header_title_submissionpage = JSON()
    landing_page = Unicode()
    exception_email = Unicode()
示例#24
0
class BugTracker(SQLBase):
    """A class to access the BugTracker table in the database.

    Each BugTracker is a distinct instance of that bug tracking
    tool. For example, each Bugzilla deployment is a separate
    BugTracker. bugzilla.mozilla.org and bugzilla.gnome.org are each
    distinct BugTrackers.
    """
    implements(IBugTracker)

    _table = 'BugTracker'

    bugtrackertype = EnumCol(dbName='bugtrackertype',
                             schema=BugTrackerType,
                             notNull=True)
    name = StringCol(notNull=True, unique=True)
    title = StringCol(notNull=True)
    summary = StringCol(notNull=False)
    baseurl = StringCol(notNull=True)
    active = Bool(name='active', allow_none=False, default=True)

    owner = ForeignKey(dbName='owner',
                       foreignKey='Person',
                       storm_validator=validate_public_person,
                       notNull=True)
    contactdetails = StringCol(notNull=False)
    has_lp_plugin = BoolCol(notNull=False, default=False)
    products = SQLMultipleJoin('Product',
                               joinColumn='bugtracker',
                               orderBy='name')
    watches = SQLMultipleJoin('BugWatch',
                              joinColumn='bugtracker',
                              orderBy='-datecreated',
                              prejoins=['bug'])

    _filing_url_patterns = {
        BugTrackerType.BUGZILLA:
        ("%(base_url)s/enter_bug.cgi?product=%(remote_product)s"
         "&short_desc=%(summary)s&long_desc=%(description)s"),
        BugTrackerType.GOOGLE_CODE: ("%(base_url)s/entry?summary=%(summary)s&"
                                     "comment=%(description)s"),
        BugTrackerType.MANTIS:
        ("%(base_url)s/bug_report_advanced_page.php"
         "?summary=%(summary)s&description=%(description)s"),
        BugTrackerType.PHPPROJECT:
        ("%(base_url)s/report.php"
         "?in[sdesc]=%(summary)s&in[ldesc]=%(description)s"),
        BugTrackerType.ROUNDUP:
        ("%(base_url)s/issue?@template=item&title=%(summary)s"
         "&@note=%(description)s"),
        BugTrackerType.RT:
        ("%(base_url)s/Ticket/Create.html?Queue=%(remote_product)s"
         "&Subject=%(summary)s&Content=%(description)s"),
        BugTrackerType.SAVANE:
        ("%(base_url)s/bugs/?func=additem&group=%(remote_product)s"),
        BugTrackerType.SOURCEFORGE: ("%(base_url)s/%(tracker)s/?func=add&"
                                     "group_id=%(group_id)s&atid=%(at_id)s"),
        BugTrackerType.TRAC: ("%(base_url)s/newticket?summary=%(summary)s&"
                              "description=%(description)s"),
    }

    _search_url_patterns = {
        BugTrackerType.BUGZILLA:
        ("%(base_url)s/query.cgi?product=%(remote_product)s"
         "&short_desc=%(summary)s"),
        BugTrackerType.GOOGLE_CODE:
        "%(base_url)s/list?q=%(summary)s",
        BugTrackerType.DEBBUGS:
        ("%(base_url)s/cgi-bin/search.cgi?phrase=%(summary)s"
         "&attribute_field=package&attribute_operator=STROREQ"
         "&attribute_value=%(remote_product)s"),
        BugTrackerType.MANTIS:
        "%(base_url)s/view_all_bug_page.php",
        BugTrackerType.PHPPROJECT:
        ("%(base_url)s/search.php?search_for=%(summary)s"),
        BugTrackerType.ROUNDUP:
        ("%(base_url)s/issue?@template=search&@search_text=%(summary)s"),
        BugTrackerType.RT:
        ("%(base_url)s/Search/Build.html?Query=Queue = "
         "'%(remote_product)s' AND Subject LIKE '%(summary)s'"),
        BugTrackerType.SAVANE:
        ("%(base_url)s/bugs/?func=search&group=%(remote_product)s"),
        BugTrackerType.SOURCEFORGE:
        ("%(base_url)s/search/?group_id=%(group_id)s"
         "&some_word=%(summary)s&type_of_search=artifact"),
        BugTrackerType.TRAC:
        "%(base_url)s/search?ticket=on&q=%(summary)s",
    }

    @property
    def _custom_filing_url_patterns(self):
        """Return a dict of bugtracker-specific bugfiling URL patterns."""
        gnome_bugzilla = getUtility(ILaunchpadCelebrities).gnome_bugzilla
        return {
            gnome_bugzilla:
            ("%(base_url)s/enter_bug.cgi?product=%(remote_product)s"
             "&short_desc=%(summary)s&comment=%(description)s"),
        }

    @property
    def latestwatches(self):
        """See `IBugTracker`."""
        return self.watches[:10]

    @property
    def multi_product(self):
        """Return True if this BugTracker tracks multiple projects."""
        if self.bugtrackertype not in SINGLE_PRODUCT_BUGTRACKERTYPES:
            return True
        else:
            return False

    def getBugFilingAndSearchLinks(self,
                                   remote_product,
                                   summary=None,
                                   description=None,
                                   remote_component=None):
        """See `IBugTracker`."""
        bugtracker_urls = {'bug_filing_url': None, 'bug_search_url': None}

        if remote_product is None and self.multi_product:
            # Don't try to return anything if remote_product is required
            # for this BugTrackerType and one hasn't been passed.
            return bugtracker_urls

        if remote_product is None:
            # Turn the remote product into an empty string so that
            # quote() doesn't blow up later on.
            remote_product = ''

        if remote_component is None:
            # Ditto for remote component.
            remote_component = ''

        if self in self._custom_filing_url_patterns:
            # Some bugtrackers are customised to accept different
            # querystring parameters from the default. We special-case
            # these.
            bug_filing_pattern = self._custom_filing_url_patterns[self]
        else:
            bug_filing_pattern = self._filing_url_patterns.get(
                self.bugtrackertype, None)

        bug_search_pattern = self._search_url_patterns.get(
            self.bugtrackertype, None)

        # Make sure that we don't put > 1 '/' in returned URLs.
        base_url = self.baseurl.rstrip('/')

        # If summary or description are None, convert them to empty
        # strings to that we don't try to pass anything to the upstream
        # bug tracker.
        if summary is None:
            summary = ''
        if description is None:
            description = ''

        # UTF-8 encode the description and summary so that quote()
        # doesn't break if they contain unicode characters it doesn't
        # understand.
        summary = summary.encode('utf-8')
        description = description.encode('utf-8')

        if self.bugtrackertype == BugTrackerType.SOURCEFORGE:
            try:
                # SourceForge bug trackers use a group ID and an ATID to
                # file a bug, rather than a product name. remote_product
                # should be an ampersand-separated string in the form
                # 'group_id&atid'
                group_id, at_id = remote_product.split('&')
            except ValueError:
                # If remote_product contains something that's not valid
                # in a SourceForge context we just return early.
                return None

            # If this bug tracker is the SourceForge celebrity the link
            # is to the new bug tracker rather than the old one.
            sf_celeb = getUtility(ILaunchpadCelebrities).sourceforge_tracker
            if self == sf_celeb:
                tracker = 'tracker2'
            else:
                tracker = 'tracker'

            url_components = {
                'base_url': base_url,
                'tracker': quote(tracker),
                'group_id': quote(group_id),
                'at_id': quote(at_id),
                'summary': quote(summary),
                'description': quote(description),
            }

        else:
            url_components = {
                'base_url': base_url,
                'remote_product': quote(remote_product),
                'remote_component': quote(remote_component),
                'summary': quote(summary),
                'description': quote(description),
            }

        if bug_filing_pattern is not None:
            bugtracker_urls['bug_filing_url'] = (bug_filing_pattern %
                                                 url_components)
        if bug_search_pattern is not None:
            bugtracker_urls['bug_search_url'] = (bug_search_pattern %
                                                 url_components)

        return bugtracker_urls

    def getBugsWatching(self, remotebug):
        """See `IBugTracker`."""
        # We special-case email address bug trackers. Since we don't
        # record a remote bug id for them we can never know which bugs
        # are already watching a remote bug.
        if self.bugtrackertype == BugTrackerType.EMAILADDRESS:
            return []
        return shortlist(
            Store.of(self).find(Bug, BugWatch.bugID == Bug.id,
                                BugWatch.bugtrackerID == self.id,
                                BugWatch.remotebug == remotebug).config(
                                    distinct=True).order_by(Bug.datecreated))

    @property
    def watches_ready_to_check(self):
        return Store.of(self).find(
            BugWatch, BugWatch.bugtracker == self,
            Not(BugWatch.next_check == None),
            BugWatch.next_check <= datetime.now(timezone('UTC')))

    @property
    def watches_with_unpushed_comments(self):
        return Store.of(self).find(
            BugWatch, BugWatch.bugtracker == self,
            BugMessage.bugwatch == BugWatch.id,
            BugMessage.remote_comment_id == None).config(distinct=True)

    @property
    def watches_needing_update(self):
        """All watches needing some sort of update.

        :return: The union of `watches_ready_to_check` and
            `watches_with_unpushed_comments`.
        """
        return self.watches_ready_to_check.union(
            self.watches_with_unpushed_comments)

    # Join to return a list of BugTrackerAliases relating to this
    # BugTracker.
    _bugtracker_aliases = SQLMultipleJoin('BugTrackerAlias',
                                          joinColumn='bugtracker')

    def _get_aliases(self):
        """See `IBugTracker.aliases`."""
        alias_urls = set(alias.base_url for alias in self._bugtracker_aliases)
        # Although it does no harm if the current baseurl is also an
        # alias, we hide it and all its permutations to avoid
        # confusion.
        alias_urls.difference_update(base_url_permutations(self.baseurl))
        return tuple(sorted(alias_urls))

    def _set_aliases(self, alias_urls):
        """See `IBugTracker.aliases`."""
        if alias_urls is None:
            alias_urls = set()
        else:
            alias_urls = set(alias_urls)

        current_aliases_by_url = dict(
            (alias.base_url, alias) for alias in self._bugtracker_aliases)
        # Make a set of the keys, i.e. a set of current URLs.
        current_alias_urls = set(current_aliases_by_url)

        # URLs we need to add as aliases.
        to_add = alias_urls - current_alias_urls
        # URL aliases we need to delete.
        to_del = current_alias_urls - alias_urls

        for url in to_add:
            BugTrackerAlias(bugtracker=self, base_url=url)
        for url in to_del:
            alias = current_aliases_by_url[url]
            alias.destroySelf()

    aliases = property(
        _get_aliases, _set_aliases, None,
        """A list of the alias URLs. See `IBugTracker`.

        The aliases are found by querying BugTrackerAlias. Assign an
        iterable of URLs or None to set or remove aliases.
        """)

    @property
    def imported_bug_messages(self):
        """See `IBugTracker`."""
        return Store.of(self).find(
            BugMessage, BugMessage.bugwatchID == BugWatch.id,
            BugWatch.bugtrackerID == self.id).order_by(BugMessage.id)

    def getLinkedPersonByName(self, name):
        """Return the Person with a given name on this bugtracker."""
        return BugTrackerPerson.selectOneBy(name=name, bugtracker=self)

    def linkPersonToSelf(self, name, person):
        """See `IBugTrackerSet`."""
        # Check that this name isn't already in use for this bugtracker.
        if self.getLinkedPersonByName(name) is not None:
            raise BugTrackerPersonAlreadyExists(
                "Name '%s' is already in use for bugtracker '%s'." %
                (name, self.name))

        bugtracker_person = BugTrackerPerson(name=name,
                                             bugtracker=self,
                                             person=person)

        return bugtracker_person

    def ensurePersonForSelf(self, display_name, email, rationale,
                            creation_comment):
        """Return a Person that is linked to this bug tracker."""
        # If we have an email address to work with we can use
        # ensurePerson() to get the Person we need.
        if email is not None:
            return getUtility(IPersonSet).ensurePerson(email, display_name,
                                                       rationale,
                                                       creation_comment)

        # First, see if there's already a BugTrackerPerson for this
        # display_name on this bugtracker. If there is, return it.
        bugtracker_person = self.getLinkedPersonByName(display_name)

        if bugtracker_person is not None:
            return bugtracker_person.person

        # Generate a valid Launchpad name for the Person.
        base_canonical_name = ("%s-%s" %
                               (sanitize_name(display_name), self.name))
        canonical_name = base_canonical_name

        person_set = getUtility(IPersonSet)
        index = 0
        while person_set.getByName(canonical_name) is not None:
            index += 1
            canonical_name = "%s-%s" % (base_canonical_name, index)

        person = person_set.createPersonWithoutEmail(canonical_name,
                                                     rationale,
                                                     creation_comment,
                                                     displayname=display_name)

        # Link the Person to the bugtracker for future reference.
        bugtracker_person = self.linkPersonToSelf(display_name, person)

        return person

    def resetWatches(self, new_next_check=None):
        """See `IBugTracker`."""
        if new_next_check is None:
            new_next_check = SQL(
                "now() at time zone 'UTC' + (random() * interval '1 day')")

        store = Store.of(self)
        store.find(BugWatch,
                   BugWatch.bugtracker == self).set(next_check=new_next_check,
                                                    lastchecked=None,
                                                    last_error_type=None)

    def addRemoteComponentGroup(self, component_group_name):
        """See `IBugTracker`."""

        if component_group_name is None:
            component_group_name = "default"
        component_group = BugTrackerComponentGroup()
        component_group.name = component_group_name
        component_group.bug_tracker = self

        store = IStore(BugTrackerComponentGroup)
        store.add(component_group)
        store.commit()

        return component_group

    def getAllRemoteComponentGroups(self):
        """See `IBugTracker`."""
        component_groups = []

        component_groups = Store.of(self).find(
            BugTrackerComponentGroup,
            BugTrackerComponentGroup.bug_tracker == self.id)
        component_groups = component_groups.order_by(
            BugTrackerComponentGroup.name)
        return component_groups

    def getRemoteComponentGroup(self, component_group_name):
        """See `IBugTracker`."""
        component_group = None
        store = IStore(BugTrackerComponentGroup)
        if component_group_name is None:
            return None
        elif component_group_name.isdigit():
            component_group_id = int(component_group_name)
            component_group = store.find(
                BugTrackerComponentGroup,
                BugTrackerComponentGroup.id == component_group_id).one()
        else:
            component_group = store.find(
                BugTrackerComponentGroup,
                BugTrackerComponentGroup.name == component_group_name).one()
        return component_group

    def getRemoteComponentForDistroSourcePackageName(self, distribution,
                                                     sourcepackagename):
        """See `IBugTracker`."""
        if distribution is None:
            return None
        dsp = distribution.getSourcePackage(sourcepackagename)
        if dsp is None:
            return None
        return Store.of(self).find(
            BugTrackerComponent,
            BugTrackerComponent.distribution == distribution.id,
            BugTrackerComponent.source_package_name ==
            dsp.sourcepackagename.id).one()

    def getRelatedPillars(self, user=None):
        """See `IBugTracker`."""
        products = IStore(Product).find(
            Product, Product.bugtrackerID == self.id, Product.active == True,
            ProductSet.getProductPrivacyFilter(user)).order_by(Product.name)
        groups = IStore(ProjectGroup).find(
            ProjectGroup, ProjectGroup.bugtrackerID == self.id,
            ProjectGroup.active == True).order_by(ProjectGroup.name)
        return groups, products
示例#25
0
class Node_v_23(Model):
    __storm_table__ = 'node'
    name = Unicode()
    public_site = Unicode()
    hidden_service = Unicode()
    email = Unicode()
    receipt_salt = Unicode()
    languages_enabled = JSON()
    default_language = Unicode()
    default_timezone = Int()
    description = JSON()
    presentation = JSON()
    footer = JSON()
    security_awareness_title = JSON()
    security_awareness_text = JSON()
    context_selector_label = JSON()
    maximum_namesize = Int()
    maximum_textsize = Int()
    maximum_filesize = Int()
    tor2web_admin = Bool()
    tor2web_submission = Bool()
    tor2web_receiver = Bool()
    tor2web_unauth = Bool()
    allow_unencrypted = Bool()
    allow_iframes_inclusion = Bool()
    submission_minimum_delay = Int()
    submission_maximum_ttl = Int()
    can_postpone_expiration = Bool()
    can_delete_submission = Bool()
    ahmia = Bool()
    wizard_done = Bool()
    disable_privacy_badge = Bool()
    disable_security_awareness_badge = Bool()
    disable_security_awareness_questions = Bool()
    disable_key_code_hint = Bool()
    whistleblowing_question = JSON()
    whistleblowing_button = JSON()
    enable_custom_privacy_badge = Bool()
    custom_privacy_badge_tor = JSON()
    custom_privacy_badge_none = JSON()
    header_title_homepage = JSON()
    header_title_submissionpage = JSON()
    header_title_receiptpage = JSON()
    landing_page = Unicode()
    show_contexts_in_alphabetical_order = Bool()
    exception_email = Unicode()
示例#26
0
class Node_v_14(Model):
    __storm_table__ = 'node'
    name = Unicode()
    public_site = Unicode()
    hidden_service = Unicode()
    email = Unicode()
    receipt_salt = Unicode()
    last_update = DateTime()
    receipt_regexp = Unicode()
    languages_enabled = Pickle()
    default_language = Unicode()
    description = Pickle()
    presentation = Pickle()
    footer = Pickle()
    subtitle = Pickle()
    terms_and_conditions = Pickle()
    security_awareness_title = Pickle()
    security_awareness_text = Pickle()
    stats_update_time = Int()
    maximum_namesize = Int()
    maximum_textsize = Int()
    maximum_filesize = Int()
    tor2web_admin = Bool()
    tor2web_submission = Bool()
    tor2web_receiver = Bool()
    tor2web_unauth = Bool()
    allow_unencrypted = Bool()
    x_frame_options_mode = Unicode()
    x_frame_options_allow_from = Unicode()
    postpone_superpower = Bool()
    can_delete_submission = Bool()
    ahmia = Bool()
    wizard_done = Bool()
    anomaly_checks = Bool()
    exception_email = Unicode()
    disable_privacy_badge = Bool()
    disable_security_awareness_badge = Bool()
    disable_security_awareness_questions = Bool()
示例#27
0
class TranslationTemplatesBuild(BuildFarmJobMixin, Storm):
    """A `BuildFarmJob` extension for translation templates builds."""

    implements(ITranslationTemplatesBuild)
    classProvides(ITranslationTemplatesBuildSource)

    __storm_table__ = 'TranslationTemplatesBuild'

    job_type = BuildFarmJobType.TRANSLATIONTEMPLATESBUILD

    id = Int(name='id', primary=True)
    build_farm_job_id = Int(name='build_farm_job', allow_none=False)
    build_farm_job = Reference(build_farm_job_id, 'BuildFarmJob.id')
    branch_id = Int(name='branch', allow_none=False)
    branch = Reference(branch_id, 'Branch.id')

    processor_id = Int(name='processor')
    processor = Reference(processor_id, 'Processor.id')
    virtualized = Bool(name='virtualized')

    date_created = DateTime(name='date_created',
                            tzinfo=pytz.UTC,
                            allow_none=False)
    date_started = DateTime(name='date_started', tzinfo=pytz.UTC)
    date_finished = DateTime(name='date_finished', tzinfo=pytz.UTC)
    date_first_dispatched = DateTime(name='date_first_dispatched',
                                     tzinfo=pytz.UTC)

    builder_id = Int(name='builder')
    builder = Reference(builder_id, 'Builder.id')

    status = DBEnum(name='status', enum=BuildStatus, allow_none=False)

    log_id = Int(name='log')
    log = Reference(log_id, 'LibraryFileAlias.id')

    failure_count = Int(name='failure_count', allow_none=False)

    @property
    def title(self):
        return u'Translation template build for %s' % (self.branch.displayname)

    def __init__(self, build_farm_job, branch, processor):
        super(TranslationTemplatesBuild, self).__init__()
        self.build_farm_job = build_farm_job
        self.branch = branch
        self.status = BuildStatus.NEEDSBUILD
        self.processor = processor

    def makeJob(self):
        """See `IBuildFarmJobOld`."""
        store = IStore(BranchJob)

        # Pass public HTTP URL for the branch.
        metadata = {
            'branch_url': self.branch.composePublicURL(),
            'build_id': self.id,
        }
        branch_job = BranchJob(self.branch,
                               BranchJobType.TRANSLATION_TEMPLATES_BUILD,
                               metadata)
        store.add(branch_job)
        return TranslationTemplatesBuildJob(branch_job)

    @classmethod
    def _getStore(cls, store=None):
        """Return `store` if given, or the default."""
        if store is None:
            return IStore(cls)
        else:
            return store

    @classmethod
    def _getBuildArch(cls):
        """Returns an `IProcessor` to queue a translation build for."""
        # XXX Danilo Segan bug=580429: we hard-code processor to the Ubuntu
        # default processor architecture.  This stops the buildfarm from
        # accidentally dispatching the jobs to private builders.
        ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
        return ubuntu.currentseries.nominatedarchindep.processor

    @classmethod
    def create(cls, branch):
        """See `ITranslationTemplatesBuildSource`."""
        processor = cls._getBuildArch()
        build_farm_job = getUtility(IBuildFarmJobSource).new(
            BuildFarmJobType.TRANSLATIONTEMPLATESBUILD)
        build = TranslationTemplatesBuild(build_farm_job, branch, processor)
        store = cls._getStore()
        store.add(build)
        store.flush()
        return build

    @classmethod
    def getByID(cls, build_id, store=None):
        """See `ITranslationTemplatesBuildSource`."""
        store = cls._getStore(store)
        match = store.find(TranslationTemplatesBuild,
                           TranslationTemplatesBuild.id == build_id)
        return match.one()

    @classmethod
    def getByBuildFarmJob(cls, buildfarmjob, store=None):
        """See `ITranslationTemplatesBuildSource`."""
        store = cls._getStore(store)
        match = store.find(TranslationTemplatesBuild,
                           build_farm_job_id=buildfarmjob.id)
        return match.one()

    @classmethod
    def getByBuildFarmJobs(cls, buildfarmjobs, store=None):
        """See `ITranslationTemplatesBuildSource`."""
        store = cls._getStore(store)
        rows = store.find(
            TranslationTemplatesBuild,
            TranslationTemplatesBuild.build_farm_job_id.is_in(
                bfj.id for bfj in buildfarmjobs))
        return DecoratedResultSet(rows, pre_iter_hook=cls.preloadBuildsData)

    @classmethod
    def preloadBuildsData(cls, builds):
        # Circular imports.
        from lp.services.librarian.model import LibraryFileAlias
        # Load the related branches, products.
        branches = load_related(Branch, builds, ['branch_id'])
        load_related(Product, branches, ['productID'])
        # Preload branches cached associated product series and
        # suite source packages for all the related branches.
        GenericBranchCollection.preloadDataForBranches(branches)
        load_related(LibraryFileAlias, builds, ['log_id'])

    @classmethod
    def findByBranch(cls, branch, store=None):
        """See `ITranslationTemplatesBuildSource`."""
        store = cls._getStore(store)
        return store.find(TranslationTemplatesBuild,
                          TranslationTemplatesBuild.branch == branch)

    @property
    def log_url(self):
        """See `IBuildFarmJob`."""
        if self.log is None:
            return None
        return self.log.http_url
示例#28
0
class Config(Storm):
    __storm_table__ = 'config'
    __storm_primary__ = ('var_group', 'var_name')

    cfg_desc = GLConfig
    var_group = Unicode()
    var_name = Unicode()
    value = JSON()
    customized = Bool(default=False)

    def __init__(self,
                 group=None,
                 name=None,
                 value=None,
                 cfg_desc=None,
                 migrate=False):
        """
        :param value:    This input is passed directly into set_v
        :param migrate:  Added to comply with models.Model constructor which is
                         used to copy every field returned by storm from the db
                         from an old_obj to a new one.
        :param cfg_desc: Used to specify where to look for the Config objs descripitor.
                         This is used in mig 34.
        """
        if cfg_desc is not None:
            self.cfg_desc = cfg_desc

        if migrate:
            return

        self.var_group = unicode(group)
        self.var_name = unicode(name)

        self.set_v(value)

    @staticmethod
    def find_descriptor(config_desc_root, var_group, var_name):
        d = config_desc_root.get(var_group, {}).get(var_name, None)
        if d is None:
            raise ValueError('%s.%s descriptor cannot be None' %
                             (var_group, var_name))

        return d

    def set_v(self, val):
        desc = self.find_descriptor(self.cfg_desc, self.var_group,
                                    self.var_name)
        if val is None:
            val = desc._type()
        if isinstance(desc, config_desc.Unicode) and isinstance(val, str):
            val = unicode(val)
        if not isinstance(val, desc._type):
            raise ValueError("Cannot assign %s with %s" % (self, type(val)))
        if desc.validator is not None:
            desc.validator(self, self.var_name, val)

        if self.value is None:
            self.value = {'v': val}

        elif self.value['v'] != val:
            self.customized = True
            self.value = {'v': val}

    def get_v(self):
        return self.value['v']

    def __repr__(self):
        return "<Config: %s.%s>" % (self.var_group, self.var_name)
示例#29
0
class Context_v_34(models.ModelWithID):
    __storm_table__ = 'context'
    show_small_receiver_cards = Bool(default=False)
    show_context = Bool(default=True)
    show_recipients_details = Bool(default=False)
    allow_recipients_selection = Bool(default=False)
    maximum_selectable_receivers = Int(default=0)
    select_all_receivers = Bool(default=True)
    enable_comments = Bool(default=True)
    enable_messages = Bool(default=False)
    enable_two_way_comments = Bool(default=True)
    enable_two_way_messages = Bool(default=True)
    enable_attachments = Bool(default=True)
    tip_timetolive = Int(default=15)
    name = JSON(validator=shortlocal_v)
    description = JSON(validator=longlocal_v)
    recipients_clarification = JSON()
    status_page_message = JSON()
    show_receivers_in_alphabetical_order = Bool(default=False)
    presentation_order = Int(default=0)
    questionnaire_id = Unicode()
    img_id = Unicode()
示例#30
0
class LiveFS(Storm):
    """See `ILiveFS`."""

    __storm_table__ = 'LiveFS'

    id = Int(primary=True)

    date_created = DateTime(name='date_created',
                            tzinfo=pytz.UTC,
                            allow_none=False)
    date_last_modified = DateTime(name='date_last_modified',
                                  tzinfo=pytz.UTC,
                                  allow_none=False)

    registrant_id = Int(name='registrant', allow_none=False)
    registrant = Reference(registrant_id, 'Person.id')

    owner_id = Int(name='owner', allow_none=False)
    owner = Reference(owner_id, 'Person.id')

    distro_series_id = Int(name='distro_series', allow_none=False)
    distro_series = Reference(distro_series_id, 'DistroSeries.id')

    name = Unicode(name='name', allow_none=False)

    metadata = JSON('json_data')

    require_virtualized = Bool(name='require_virtualized')

    relative_build_score = Int(name='relative_build_score', allow_none=False)

    def __init__(self, registrant, owner, distro_series, name, metadata,
                 require_virtualized, date_created):
        """Construct a `LiveFS`."""
        if not getFeatureFlag(LIVEFS_FEATURE_FLAG):
            raise LiveFSFeatureDisabled
        super(LiveFS, self).__init__()
        self.registrant = registrant
        self.owner = owner
        self.distro_series = distro_series
        self.name = name
        self.metadata = metadata
        self.require_virtualized = require_virtualized
        self.relative_build_score = 0
        self.date_created = date_created
        self.date_last_modified = date_created

    def requestBuild(self,
                     requester,
                     archive,
                     distro_arch_series,
                     pocket,
                     unique_key=None,
                     metadata_override=None,
                     version=None):
        """See `ILiveFS`."""
        if not requester.inTeam(self.owner):
            raise LiveFSNotOwner(
                "%s cannot create live filesystem builds owned by %s." %
                (requester.displayname, self.owner.displayname))
        if not archive.enabled:
            raise ArchiveDisabled(archive.displayname)
        if archive.private and self.owner != archive.owner:
            # See rationale in `LiveFSBuildArchiveOwnerMismatch` docstring.
            raise LiveFSBuildArchiveOwnerMismatch()

        pending = IStore(self).find(
            LiveFSBuild, LiveFSBuild.livefs_id == self.id,
            LiveFSBuild.archive_id == archive.id,
            LiveFSBuild.distro_arch_series_id == distro_arch_series.id,
            LiveFSBuild.pocket == pocket, LiveFSBuild.unique_key == unique_key,
            LiveFSBuild.status == BuildStatus.NEEDSBUILD)
        if pending.any() is not None:
            raise LiveFSBuildAlreadyPending

        build = getUtility(ILiveFSBuildSet).new(
            requester,
            self,
            archive,
            distro_arch_series,
            pocket,
            unique_key=unique_key,
            metadata_override=metadata_override,
            version=version)
        build.queueBuild()
        return build

    def _getBuilds(self, filter_term, order_by):
        """The actual query to get the builds."""
        query_args = [
            LiveFSBuild.livefs == self, LiveFSBuild.archive_id == Archive.id,
            Archive._enabled == True,
            get_enabled_archive_filter(getUtility(ILaunchBag).user,
                                       include_public=True,
                                       include_subscribed=True)
        ]
        if filter_term is not None:
            query_args.append(filter_term)
        result = Store.of(self).find(LiveFSBuild, *query_args)
        result.order_by(order_by)
        return result

    @property
    def builds(self):
        """See `ILiveFS`."""
        order_by = (NullsLast(
            Desc(Greatest(LiveFSBuild.date_started,
                          LiveFSBuild.date_finished))),
                    Desc(LiveFSBuild.date_created), Desc(LiveFSBuild.id))
        return self._getBuilds(None, order_by)

    @property
    def _pending_states(self):
        """All the build states we consider pending (non-final)."""
        return [
            BuildStatus.NEEDSBUILD,
            BuildStatus.BUILDING,
            BuildStatus.UPLOADING,
            BuildStatus.CANCELLING,
        ]

    @property
    def completed_builds(self):
        """See `ILiveFS`."""
        filter_term = (Not(LiveFSBuild.status.is_in(self._pending_states)))
        order_by = (NullsLast(
            Desc(Greatest(LiveFSBuild.date_started,
                          LiveFSBuild.date_finished))), Desc(LiveFSBuild.id))
        return self._getBuilds(filter_term, order_by)

    @property
    def pending_builds(self):
        """See `ILiveFS`."""
        filter_term = (LiveFSBuild.status.is_in(self._pending_states))
        # We want to order by date_created but this is the same as ordering
        # by id (since id increases monotonically) and is less expensive.
        order_by = Desc(LiveFSBuild.id)
        return self._getBuilds(filter_term, order_by)

    def destroySelf(self):
        """See `ILiveFS`."""
        if not self.builds.is_empty():
            raise CannotDeleteLiveFS(
                "Cannot delete a live filesystem with builds.")
        IStore(LiveFS).remove(self)