예제 #1
0
    def full_receiver_align(self, context_gus, un_receiver_selected):
        """
        Called by Context handlers (PUT|POST), roll in all the receiver and delete|add|skip
        with the presence of context_gus
        """
        store = self.getStore()

        receiver_selected = []
        for r in un_receiver_selected:
            receiver_selected.append(str(r))

        presents_receiver = store.find(Receiver)

        debug_counter = 0
        for r in presents_receiver:

            # if is not present in receiver.contexts and is requested: add
            if not context_gus in r.contexts:
                if r.receiver_gus in receiver_selected:
                    debug_counter += 1
                    r.contexts.append(str(context_gus))
                    r.update_date = gltime.utcTimeNow()

            # if is present in context.receiver and is not selected: remove
            if context_gus in r.contexts:
                if not r.receiver_gus in receiver_selected:
                    debug_counter += 1
                    r.contexts.remove(str(context_gus))
                    r.update_date = gltime.utcTimeNow()

        log.debug("    ****   full_receiver_align in all receivers after %s has been set with %s: %d mods" %
                  ( context_gus, str(receiver_selected), debug_counter ) )
예제 #2
0
    def context_align(self, context_gus, receiver_selected):
        """
        Called by Context handler, (PUT|POST), just take the context and update the
        associated receivers, checks the receiver existence, and return an
        exception if do not exist.
        """
        from globaleaks.models.receiver import Receiver
        from globaleaks.rest.errors import ReceiverGusNotFound

        try:
            requested_c = self.store.find(Context, Context.context_gus == unicode(context_gus)).one()
        except NotOneError:
            raise ContextGusNotFound
        if requested_c is None:
            raise ContextGusNotFound

        requested_c.receivers = []
        for r in receiver_selected:

            try:
                selected = self.store.find(Receiver, Receiver.receiver_gus == unicode(r)).one()
            except NotOneError:
                raise ReceiverGusNotFound
            if selected is None:
                raise ReceiverGusNotFound

            requested_c.receivers.append(str(r))
            requested_c.update_date = gltime.utcTimeNow()

        log.debug("    ++++   context_align in receiver %s with receivers %s" % (context_gus, str(receiver_selected)))
예제 #3
0
    def align_context_delete(self, receivers_gus_list, removed_context_gus):
        """
        @param receivers_gus_list: a list of receiver_gus target of the ops
        @param context_gus: context being removed
        @return: None
        """
        store = self.getStore()

        aligned_counter = 0

        for receiver_gus in receivers_gus_list:

            try:
                requested_r = store.find(Receiver, Receiver.receiver_gus == unicode(receiver_gus)).one()
            except NotOneError:
                raise ReceiverGusNotFound
            if requested_r is None:
                raise ReceiverGusNotFound

            if str(removed_context_gus) in requested_r.contexts:
                requested_r.contexts.remove(str(removed_context_gus))
                requested_r.update_date = gltime.utcTimeNow()
                aligned_counter += 1
            else:
                raise AssertionError # Just for debug

        # TODO XXX Applicative log about aligned_counter
        return aligned_counter
예제 #4
0
    def receiver_align(self, receiver_gus, context_selected):
        """
        Called by Receiver handler, (PUT|POST), just take the receiver and update the
        associated contexts
        """
        from globaleaks.models.context import Context
        from globaleaks.rest.errors import ContextGusNotFound

        store = self.getStore()

        try:
            requested_r = store.find(Receiver, Receiver.receiver_gus == unicode(receiver_gus)).one()
        except NotOneError:
            raise ReceiverGusNotFound
        if requested_r is None:
            raise ReceiverGusNotFound

        requested_r.contexts = []
        for c in context_selected:

            try:
                selected = store.find(Context, Context.context_gus == unicode(c)).one()
            except NotOneError:
                raise ContextGusNotFound
            if selected is None:
                raise ContextGusNotFound

            requested_r.contexts.append(str(c))
            requested_r.update_date = gltime.utcTimeNow()

        log.debug("    ++++   receiver_align in receiver %s with contexts %s" %
                  ( receiver_gus, str(context_selected) ) )
예제 #5
0
    def new(self, itip_id, comment, source, author_gus=None):
        """
        @param itip_id: InternalTip.id of reference, need to be addressed
        @param comment: the unicode text expected to be recorded
        @param source: the source kind of the comment (receiver, wb, system)
        @param name: the Comment wb_r name to be show and recorded, can be absent if source is enough
        @return: None
        """

        if not source in [ u'receiver', u'whistleblower', u'system' ]:
            raise NotImplemented

        try:
            itip = self.store.find(InternalTip, InternalTip.id == int(itip_id)).one()
        except NotOneError:
            # This can't actually happen
            raise Exception
        if itip is None:
            # This can't actually happen
            raise Exception

        # this approach is a little different from the other classes in ExternalTip
        # they use a new Object() in the caller method, and then Object.initialize
        # to fill with data.

        try:
            self.creation_time = gltime.utcTimeNow()
            self.source = source
            self.content = comment
            self.author_gus = author_gus
            self.internaltip = itip
            self.internaltip_id = int(itip_id)
        except TypeError, e:
            raise InvalidInputFormat("Unable to create comment: (wrong %s)" % e )
예제 #6
0
    def add_comment(self, itip_id, comment, source, author_gus=None):
        """
        @param itip_id: InternalTip.id of reference, need to be addressed
        @param comment: the unicode text expected to be recorded
        @param source: the source kind of the comment (receiver, wb, system)
        @param name: the Comment author name to be show and recorded, can be absent if source is enough
        @return: None
        """
        log.debug("[D] %s %s " % (__file__, __name__), "InternalTip class", "add_comment",
            "itip_id", itip_id, "source", source, "author_gus", author_gus)

        if not source in [ u'receiver', u'whistleblower', u'system' ]:
            raise Exception("Invalid developer brain status", source)

        store = self.getStore('add_comment')

        # this approach is a little different from the other classes in ExternalTip
        # they use a new Object() in the caller method, and then Object.initialize
        # to fill with data.
        # XXX this would be refactored when TaskQueue would be engineered
        newcomment = Comment()
        newcomment.creation_time = gltime.utcTimeNow()
        newcomment.source = source
        newcomment.content = comment
        newcomment.author_gus = author_gus
        newcomment.notification_mark = u'not notified'
        newcomment.internaltip_id = itip_id
        store.add(newcomment)

        retVal = newcomment._description_dict()

        store.commit()
        store.close()

        return retVal
예제 #7
0
    def get_single(self, tip_gus):
        """
        This is the method called when a receiver is accessing to Tip. It return
        InternalTip details and update the last_access date.
        """
        store = self.getStore()

        try:
            requested_t = store.find(ReceiverTip, ReceiverTip.tip_gus == tip_gus).one()
        except NotOneError:
            raise TipGusNotFound
        if not requested_t:
            raise TipGusNotFound

        # Access counter is incremented before the data extraction,
        # last_access is incremented after (because the receiver want know
        # if someone has accesses in his place)
        requested_t.access_counter += 1

        # The single tip dump is composed by InternalTip + ReceiverTip details
        tip_details = requested_t.internaltip._description_dict()
        tip_details.update(requested_t._description_dict())

        requested_t.last_access = gltime.utcTimeNow()

        # every time the name 'id' is misused, a kitten die :(
        tip_details.update({ 'id' : requested_t.tip_gus })
        # XXX verifiy why need to be echoed back

        return dict(tip_details)
예제 #8
0
    def update_notification_date(self, tip_gus):

        store = self.getStore()

        requested_t = store.find(ReceiverTip, ReceiverTip.tip_gus == tip_gus).one()
        requested_t.notification_date = gltime.utcTimeNow()

        return requested_t._description_dict()
예제 #9
0
    def new(self, context_dict):
        """
        @param context_dict: a dictionary containing the expected field of a context,
                is called and define as contextDescriptionDict
        @return: context_gus, the universally unique identifier of the context
        """

        self.context_gus = idops.random_context_gus()

        self.creation_date = gltime.utcTimeNow()
        self.update_date = gltime.utcTimeNow()
        self.last_activity = gltime.utcTimeNow()
        self.receivers = []

        try:
            self._import_dict(context_dict)
        except KeyError, e:
            raise InvalidInputFormat("Context Import failed (missing %s)" % e)
예제 #10
0
    def add_comment(self, itip_id, comment, source, author_gus=None):
        """
        @param itip_id: InternalTip.id of reference, need to be addressed
        @param comment: the unicode text expected to be recorded
        @param source: the source kind of the comment (receiver, wb, system)
        @param name: the Comment wb_r name to be show and recorded, can be absent if source is enough
        @return: None
        """

        if not source in [ u'receiver', u'whistleblower', u'system' ]:
            raise NotImplemented

        store = self.getStore()

        try:
            itip = store.find(InternalTip, InternalTip.id == int(itip_id)).one()
        except NotOneError:
            # This can't actually happen
            raise Exception
        if itip is None:
            # This can't actually happen
            raise Exception

        # this approach is a little different from the other classes in ExternalTip
        # they use a new Object() in the caller method, and then Object.initialize
        # to fill with data.
        newcomment = Comment()

        newcomment.creation_time = gltime.utcTimeNow()
        newcomment.source = source
        newcomment.content = comment
        newcomment.author_gus = author_gus
        newcomment.internaltip = itip
        newcomment.internaltip_id = int(itip_id)

        # TODO |need to be reeingineered, only with the queue task
        # TODO |manager can be digest and track the single notification.
        # TODO |
        newcomment.notification_mark = u'not notified'
        store.add(newcomment)

        return newcomment._description_dict()
예제 #11
0
    def new(self, profile_dict):
        """
        @profile_dict need to contain the keys: 'plugin_type', 'plugin_name',
            'admin_settings',
        """

        try:

            # below, before _import_dict, are checked profile_type, and plugin_name
            # both of them can't be updated, are chosen at creation time,

            if not unicode(profile_dict['plugin_type']) in valid_plugin_types:
                raise InvalidInputFormat("plugin_type not recognized")

            if not PluginManager.plugin_exists(profile_dict['plugin_name']):
                raise InvalidInputFormat("plugin_name not recognized between available plugins")

            self._import_dict(profile_dict)

            self.profile_gus = idops.random_plugin_gus()
            self.creation_time = gltime.utcTimeNow()

            # the name can be updated, but need to be checked to be UNIQUE
            if self.store.find(PluginProfiles, PluginProfiles.profile_name == self.profile_name).count() >= 1:
                raise ProfileNameConflict

            plugin_info = PluginManager.get_plugin(profile_dict['plugin_name'])

            # initialize the three plugin_* fields, inherit by Plugin code
            self.plugin_name = unicode(plugin_info['plugin_name'])
            self.plugin_type = unicode(plugin_info['plugin_type'])
            self.plugin_description = unicode(plugin_info['plugin_description'])
            self.admin_fields = dict(plugin_info['admin_fields'])

            # Admin-only plugins are listed here, and they have not receiver_fields
            if self.plugin_type in [ u'fileprocess' ]:
                self.receiver_fields = []
            else:
                self.receiver_fields = plugin_info['receiver_fields']

        except KeyError, e:
            raise InvalidInputFormat("Profile creation failed (missing %s)" % e)
예제 #12
0
    def self_update(self, receiver_gus, receiver_dict):
        """
        This is the method called by a receiver for change/set their preference
        """

        try:
            requested_r = self.store.find(Receiver, Receiver.receiver_gus == unicode(receiver_gus)).one()
        except NotOneError:
            raise ReceiverGusNotFound
        if requested_r is None:
            raise ReceiverGusNotFound

        try:
            requested_r.name = receiver_dict['name']
            requested_r.description = receiver_dict['description']
            requested_r.tags = receiver_dict['tags']
            requested_r.know_languages = receiver_dict['languages']
            requested_r.update_date = gltime.utcTimeNow()

        except KeyError, e:
            raise InvalidInputFormat("self update failed (missing %s)" % e)
예제 #13
0
    def pertinence_vote(self, tip_gus, vote):
        """
        check if the receiver has already voted. if YES: raise an exception, if NOT
        mark the expressed vote and call the internaltip to register the fact.
        @vote would be True or False, default is "I'm not expressed".

        return the actual vote expressed by all the receivers, to the same iTip.
        """

        store = self.getStore()

        try:
            requested_t = store.find(ReceiverTip, ReceiverTip.tip_gus == tip_gus).one()
        except NotOneError:
            raise TipGusNotFound
        if not requested_t:
            raise TipGusNotFound

        if requested_t.expressed_pertinence:
            raise TipPertinenceExpressed

        # expressed_pertinence has these meanings:
        # 0 = unassigned
        # 1 = negative vote
        # 2 = positive vote
        requested_t.expressed_pertinence = 2 if vote else 1
        requested_t.last_access = gltime.utcTimeNow()

        expressed_t = store.find(ReceiverTip, (ReceiverTip.internaltip_id == requested_t.internaltip_id, ReceiverTip.expressed_pertinence != 0))

        vote_sum = 0
        for et in expressed_t:
            if et.expressed_pertinence == 1:
                vote_sum -= 1
            else:
                vote_sum += 1

        itip_id_copy = requested_t.internaltip_id
        return (itip_id_copy, vote_sum)
예제 #14
0
    def get_single(self, receipt):

        try:
            requested_t = self.store.find(WhistleblowerTip, WhistleblowerTip.receipt == unicode(receipt)).one()
        except NotOneError:
            raise TipReceiptNotFound
        if not requested_t:
            raise TipReceiptNotFound

        requested_t.access_counter += 1

        # The single tip dump is composed by InternalTip + WBTip details
        tip_details = requested_t.internaltip._description_dict()
        tip_details.update(requested_t._description_dict())

        requested_t.last_access = gltime.utcTimeNow()

        # every time the name 'id' is misused, a kitten die :(
        tip_details.update({ 'id' : requested_t.receipt })
        # XXX verifiy why need to be echoed back

        return dict(tip_details)
예제 #15
0
    def newprofile(self, plugtype, plugname, profname, plugreq, desc=None, settings=None):
        """
        @param plugtype:  notification|delivery|inputfilter, already checked by the caller
        @param plugname:  plugin name, already checked the existence using GLPluginManager
        @param profname:  a profile name, used to recognize a unique profile in a list
        @param plugreq: the plugins required fields for admin and receiver.
        @param desc: a descriptive string that would be presented to the receiver
        @param settings:  the admin side configuration fields for the plugin.
        @return:
        """
        log.debug("[D] %s %s " % (__file__, __name__), "Class PluginConf", "newprofile", ptype, pname)

        store = self.getStore('newprofile')

        if store.find(PluginProfiles, PluginProfiles.profile_name == profname).count() >= 1:
            store.close()
            raise ProfileNameConflict

        newone = PluginProfiles()
        newone.profile_gus = idops.random_plugin_gus()
        newone.profile_name = profname
        newone.creation_time = gltime.utcTimeNow()
        newone.plugin_type = plugtype
        newone.plugin_name = plugname
        newone.required_fields = plugreq

        if settings:
            newone.admin_fields = settings

        if desc:
            newone.external_description = desc

        store.add(newone)

        store.commit()
        store.close()
예제 #16
0
            newone.admin_fields = dict(plugin_info['admin_fields'])

            # Admin-only plugins are listed here, and they have not receiver_fields
            if newone.plugin_type in [ u'fileprocess' ]:
                newone.receiver_fields = []
            else:
                newone.receiver_fields = plugin_info['receiver_fields']

        except KeyError, e:
            raise InvalidInputFormat("Profile creation failed (missing %s)" % e)

        except TypeError, e:
            raise InvalidInputFormat("Profile creation failed (wrong %s)" % e)

        newone.profile_gus = idops.random_plugin_gus()
        newone.creation_time = gltime.utcTimeNow()

        store.add(newone)

        # build return value for the handler
        return newone._description_dict()


    @transact
    def update(self, profile_gus, profile_dict):

        store = self.getStore()

        try:
            looked_p = store.find(PluginProfiles, PluginProfiles.profile_gus == profile_gus).one()
        except NotOneError:
예제 #17
0
        One that want review the whistles blowed documents. It's a sort of
        transparency baptism: here you get your GlobaLeaks Unique String, sir!
        """

        store = self.getStore()

        try:
            self._import_dict(receiver_dict)
        except KeyError, e:
            raise InvalidInputFormat("initialization failed (missing %s)" % e)
        except TypeError, e:
            raise InvalidInputFormat("initialization failed (wrong %s)" % e)

        self.receiver_gus = idops.random_receiver_gus()

        self.creation_date = gltime.utcTimeNow()
        self.update_date = gltime.utcTimeNow()

        store.add(self)

        return self._description_dict()


    @transact
    def update(self, receiver_gus, receiver_dict):
        """
        This is the method called by the admin for change receiver preferences.
        may edit more elements than the next method (self_update)
        the dict need to be already validated
        """
예제 #18
0
            raise ContextGusNotFound

        if requested_c is None:
            raise ContextGusNotFound

        try:
            requested_c._import_dict(context_dict)
        except KeyError, e:
            raise InvalidInputFormat("Context update failed (missing %s)" % e)
        except TypeError, e:
            raise InvalidInputFormat("Context update failed (wrong %s)" % e)

        if requested_c.selectable_receiver and requested_c.escalation_threshold:
            raise InvalidInputFormat("selectable_receiver and escalation_threshold are mutually exclusive")

        requested_c.update_date = gltime.utcTimeNow()

        log.msg(
            "Updated context %s in %s, created in %s"
            % (requested_c.name, requested_c.update_date, requested_c.creation_date)
        )

        return requested_c._description_dict()

    def delete_context(self, context_gus):
        """
        @param context_gus: the universal unique identifier of the context
        @return: None if is deleted correctly, or raise an exception if something is wrong.
        """

        # Handler Guarantee these operations *before*:
예제 #19
0
            raise InvalidInputFormat("Receiver and Context do not fit")

        # TODO check in a strongest way if newcfg.receiver_setting fit with newcfg.profile.receiver_fields
        key_expectation_fail = None
        for expected_k in self.profile.receiver_fields.iterkeys():
            if not self.receiver_settings.has_key(expected_k):
                key_expectation_fail = expected_k
                break

        if key_expectation_fail:
            raise InvalidInputFormat("Expected field %s" % key_expectation_fail)
        # End of temporary check: why I'm not put the raise exception inside
        # of the for+if ? because otherwise Storm results locked in the future operations :(

        self.plugin_type = self.profile.plugin_type
        self.creation_time = gltime.utcTimeNow()
        self.last_update = gltime.utcTimeNow()

        self.store.add(self)

        return self._description_dict()


    def update(self, conf_id, receiver_authorized, received_dict):

        try:
            looked_cfg = self.store.find(ReceiverConfs, ReceiverConfs.id == int(conf_id)).one()
        except NotOneError:
            raise ReceiverConfNotFound
        if not looked_cfg:
            raise ReceiverConfNotFound
예제 #20
0
        except KeyError, e:
            raise InvalidInputFormat("File import failed (missing %s)" % e)
        except TypeError, e:
            raise InvalidInputFormat("File import failed (wrong %s)" % e)

        try:
            self.context = store.find(Context, Context.context_gus == self.context_gus).one()

        except NotOneError:
            # This can never happen
            raise Exception("Internal Impossible Error")

        self.mark = self._marker[0] # not processed
        self.completed = False
        self.uploaded_date = gltime.utcTimeNow()

        self.file_gus = unicode(idops.random_file_gus())

        # When the file is 'not processed', this value stay to 0
        self.internaltip_id = 0

        store.add(self)
        return self._description_dict()


    # update in short modify only filename and description, at the moment API is missing
    # Remind open ticket with GLClient
    @transact
    def update(self, file_gus, received_dict):