def fetch_n_save(self):

        command.Op_Handler.fetch_n_save(self)

        g.assurt(self.item_stack_id)
        g.assurt(self.item_type_id)
        g.assurt(self.remind_when)

        qb = self.req.as_iqb(addons=False)
        g.assurt(qb.filters == Query_Filters(None))
        items_fetched = item_user_access.Many()
        #qb.filters.include_item_stack = True
        qb.filters.dont_load_feat_attcs = True
        #qb.filters.min_access_level = Access_Level.viewer # default: client
        items_fetched.search_by_stack_id(self.item_stack_id, qb)
        if not items_fetched:
            raise GWIS_Error(
                'Item stack ID not found or permission denied: %d' %
                (self.item_stack_id, ))
        g.assurt(len(items_fetched) == 1)
        item = items_fetched[0]
        log.debug('fetch_n_save: fetched: %s' % (str(item), ))
        g.assurt(not item.fresh)
        g.assurt(not item.valid)

        success = self.req.db.transaction_retryable(self.attempt_save,
                                                    self.req, item)

        if not success:
            log.warning('fetch_n_save: failed')
Exemple #2
0
   def compose_events_branch(self, qb, rev_parts, branch_id, rid, msg_type_id,
                                   edit_lookup):

      added_event = False

#      conf.break_here('ccpv3')

      sids = edit_lookup[branch_id][rid][msg_type_id]

      qb.filters.only_stack_ids = ','.join([str(x) for x in sids])
      qb.filters.force_resolve_item_type = True
      qb.filters.include_item_stack = True
      items_fetched = item_user_access.Many()
      #items_fetched.search_get_items(qb)
      items_fetched.search_for_items(qb)
      qb.filters.only_stack_ids = ''
      qb.filters.force_resolve_item_type = False
      qb.filters.include_item_stack = False

      if items_fetched:
         if len(items_fetched) != len(sids):
            log.warning(
               'compose_events_branch: fewer found: user: %s / sids: %s / %s'
               % (self.username, sids, len(items_fetched) - len(sids),))
         rev_parts.compose_email_msg_type(msg_type_id)
         rev_parts.compose_email_item_list(
                  qb, msg_type_id, items_fetched)
         added_event = True
      else:
         log.warning(
            'compose_events_branch: nothing found: user: %s / sids: %s'
            % (self.username, sids,))

      return added_event
Exemple #3
0
    def setup_user_watcher_get_rhs(self, user_qb, stack_id):

        # EXPLAIN: Does saving a link_value check the user's access to the
        # geofeature or the attachment? [lb] thinks that commit.py checks,
        # or maybe it's grac_manager's prepare_item_valid_req. Hrm.

        rhs_item = None

        items_fetched = item_user_access.Many()

        items_fetched.search_by_stack_id(stack_id, user_qb)

        if len(items_fetched) > 0:
            g.assurt(len(items_fetched) == 1)
            rhs_item = items_fetched[0]

            #if rhs_item.deleted:
            #   conf.break_here('ccpv3')

            log.verbose2('setup_user_watcher: rhs_item: %s' %
                         (str(rhs_item), ))
            log.verbose2('setup_user_watcher: access_level_id: %d' %
                         (rhs_item.access_level_id, ))
            log.verbose2('setup_user_watcher: real_item_type_id: %s' %
                         (rhs_item.real_item_type_id, ))
            log.verbose2('setup_user_watcher: item_type: %s' %
                         (Item_Type.id_to_str(rhs_item.real_item_type_id), ))
            g.assurt(rhs_item.item_type_id == Item_Type.ITEM_USER_ACCESS)
            g.assurt(rhs_item.real_item_type_id)  # I.e., Region, Byway, etc.
        else:
            # Don't log an error or the cron job dies.
            log.warning('setup_user_watcher: watched item not found: %d' %
                        (stack_id, ))
            # 2013.03.27: There are some regions in CcpV1 being watched that don't
            #             really exist.
            # ccpv1_lite=> select * from region_watcher where region_id = 1558741;
            #
            #               region_id |   username
            #              -----------+---------------
            #                 1558741 |  [redacted]
            #
            # ccpv1_lite=> select * from region where id = 1558741;
            #              (0 rows)
            # ccpv1_lite=> select * from watch_region where id = 1558741;
            #              (0 rows)
            # Skipping: g.assurt(False)

        return rhs_item
    def fetch_n_save(self):

        command.Op_Handler.fetch_n_save(self)

        # Assemble the qb from the request.
        qb = self.req.as_iqb(addons=False)
        g.assurt(qb.filters == Query_Filters(None))

        item_stack_ids = qb.filters.decode_ids_compact('./ssec_sids',
                                                       self.req.doc_in)
        if ((not item_stack_ids) or (item_stack_ids.find(',') != -1)):
            raise GWIS_Error('Expecting one stack ID in ssec_sids doc.')

        item_stack_id = int(item_stack_ids)
        if item_stack_id <= 0:
            raise GWIS_Error('Expecting positive valued stack ID.')

        items_fetched = item_user_access.Many()
        # So we get access_infer, etc.
        qb.filters.include_item_stack = True
        # Don't forget to maybe use the session ID.
        qb.filters.gia_use_sessid = self.req.filters.gia_use_sessid
        items_fetched.search_by_stack_id(item_stack_id, qb)

        if not items_fetched:
            raise GWIS_Error(
                'Item stack ID not found or you cannot access: %d' %
                (item_stack_id, ))

        g.assurt(len(items_fetched) == 1)
        item = items_fetched[0]
        log.verbose1('verify_access: fetched: %s' % (str(item), ))
        g.assurt(not item.fresh)
        g.assurt(not item.valid)

        # What's the policy for who can make stealth secret values?
        # They're not really that special, but if every item in the database
        # had one, that's a lotta mozzarrella.
        #
        # Users should at least be able to edit: for example, if an owner of a
        # route linked to a route in a discussion, the public has view access
        # to the route based on the discussion, but we wouldn't want someone
        # with view access to create a stealth secret, since the owner should
        # actively manage the stealth secret access via the gia sharing widget.

        #  item.groups_access_load_from_db(qb)
        #  g.assurt(item.groups_access) # else, stealth to permissions_free?
        #  access_infer_id = item.get_access_infer(qb)
        if item.access_style_id == Access_Style.pub_editor:
            # Re prev. comments, ability to edit includes ability to make ssecs.
            if not item.can_edit():
                raise GWIS_Error(
                    'You must be editor of public item to create link: %d' %
                    (item_stack_id, ))
        elif item.access_style_id == Access_Style.usr_editor:
            g.assurt(item.can_edit())
        elif item.access_style_id == Access_Style.restricted:
            # Restricted item types, like routes and track, can only have stealth
            # access created by their arbiters and owners.
            if not item.can_arbit():
                raise GWIS_Error(
                    'You must be arbiter of restricted item to create link: %d'
                    % (item_stack_id, ))
            # This is the path when an anonymous user gets a route and makes a
            # link for it. We'll call add_stealth_gia to make sure user has access
            # to the stealth secret.
        else:
            raise GWIS_Error('What you are trying to do is not supported.')

        if item.stealth_secret:
            new_stealth_secret = False
            stealth_secret = item.stealth_secret
            log.warning('fetch_n_save: Item already has link: %d' %
                        (item_stack_id, ))
        else:
            new_stealth_secret = True
            stealth_secret = self.make_stealth_secret(item)
            # See also route_get: Maybe we should just INSERT INTO
            # group_item_access ourselves, but instead we sneakily
            # use the commit command to process a style_change.
            if ((qb.filters.gia_use_sessid)
                    and (qb.username == conf.anonymous_username)):
                item_arr = [
                    item,
                ]
                self.req.db.transaction_retryable(self.add_stealth_gia,
                                                  self.req, item_arr)
                item = item_arr[0]

        # The outermost document.
        ssecrets = etree.Element('ssecrets')
        # The response document.
        ssecret = etree.Element('ssecret')
        misc.xa_set(ssecret, 'stack_id', item.stack_id)
        misc.xa_set(ssecret, 'ssecret', stealth_secret)
        # Include the possibly changed access_infer_id.
        if new_stealth_secret:
            misc.xa_set(ssecret, 'acif', item.access_infer_id)
            # Include the possibly new and changed grac records.
            if item.groups_access is None:
                item.groups_access_load_from_db(qb)
            log.debug('fetch_n_save: no. groups_access: %d' %
                      (len(item.groups_access), ))
            grac_doc = etree.Element('access_control')
            misc.xa_set(grac_doc, 'control_type', 'group_item_access')
            for grpa in item.groups_access.itervalues():
                grpa.append_gml(grac_doc, need_digest=False)
            ssecret.append(grac_doc)
        # Bundle it up.
        ssecrets.append(ssecret)
        # And we're done.
        self.ssec_xml = ssecrets
    def fetch_n_save(self):

        gwis_errs = []

        # Call parent's fcn., which calls Query_Overlord.prepare_filters()
        # and initializes self.doc to etree.Element('data').
        command.Op_Handler.fetch_n_save(self)

        # Assemble the qb from the request.
        qb = self.req.as_iqb(addons=False)
        g.assurt(qb.filters == Query_Filters(None))

        # We set login_required so this should always be the case.
        g.assurt(self.req.client.username != conf.anonymous_username)
        g.assurt(qb.username == self.req.client.username)

        self.item_stack_ids = qb.filters.decode_ids_compact(
            './fbil_sids', self.req.doc_in)
        if self.item_stack_ids and self.use_all_in_history:
            gwis_errs.append('Please specify only fbil_sids or all_hist.')

        items = item_user_access.Many()
        g.assurt(qb.sql_clauses is None)
        qb.sql_clauses = item_user_access.Many.sql_clauses_cols_all.clone()
        qb.filters.dont_load_feat_attcs = True
        qb.filters.min_access_level = Access_Level.denied

        if not self.item_stack_ids:
            g.assurt(self.use_all_in_history)
            stack_id_table_ref = 'temp_stack_id__item_findability'
            stack_ids_sql = ("""
            SELECT
               stack_id
            INTO TEMPORARY TABLE
               %s
            FROM
               (SELECT
                  item_stack_id
                FROM
                  item_findability
                WHERE
                  (show_in_history IS TRUE)
                  AND (username = %s)) AS foo_ifp
            """ % (
                stack_id_table_ref,
                qb.db.quoted(qb.username),
            ))
            rows = qb.db.sql(stack_ids_sql)
            #
            qb.sql_clauses.inner.join += ("""
            JOIN %s
               ON (gia.stack_id = %s.stack_id)
            """ % (
                stack_id_table_ref,
                stack_id_table_ref,
            ))
            check_exist = False
        else:
            id_count = self.item_stack_ids.count(',')
            if id_count > conf.constraint_sids_max:
                gwis_errs.append(
                    'Too many stack IDs in request: %d (max: %d).' % (
                        id_count,
                        conf.constraint_sids_max,
                    ))
            else:
                qb.filters.only_stack_ids = self.item_stack_ids
            # We'll have to double-check if these records exist before updating.
            check_exist = True

        if True:

            items.search_for_items_clever(qb)

            if not items:
                log.warning('fetch_n_save: no findability items: %s' %
                            (str(qb.filters), ))
                gwis_errs.append('No items were found to be findabilitied.')
            else:
                log.debug('fetch_n_save: no. item_findability: %d' %
                          (len(items), ))

            use_sids = []
            for itm in items:
                if ((self.action_squelch_pub is not None)
                        or (self.action_squelch_usr is not None)):
                    if itm.access_level_id <= Access_Level.arbiter:
                        log.debug('fetch_n_save: action_squelch: item: %s',
                                  itm)
                        use_sids.append(str(itm.stack_id))
                    else:
                        gwis_errs.append(
                            'You must be arbiter to change squelch.')
                else:
                    # self.action_history_add, self.action_history_chg
                    if itm.access_level_id > Access_Level.viewer:
                        gwis_errs.append('Unknown item or access denied.')
                    else:
                        log.debug('fetch_n_save: action_history: item: %s',
                                  itm)
                        use_sids.append(str(itm.stack_id))

            if not use_sids:

                gwis_errs.append('No items were found.')

            else:

                # use_sids = [ str(sid) for sid in use_sids ]
                self.update_stack_ids = ", ".join(use_sids)

                if check_exist:
                    # Make a list of stack IDs to insert first, before updating.
                    if ((self.action_history_add is not None)
                            or (self.action_history_chg is not None)):
                        username = qb.username
                    elif self.action_squelch_pub is not None:
                        username = conf.anonymous_username
                    else:
                        g.assurt(self.action_squelch_usr is not None)
                        username = qb.username
                    user_id = User.user_id_from_username(qb.db, username)
                    missing_sids_sql = ("""
                  SELECT
	                  DISTINCT(itmv.stack_id)
                  FROM
                     item_versioned AS itmv
                  LEFT OUTER JOIN
                     item_findability AS itmf
                     ON ((itmv.stack_id = itmf.item_stack_id)
                         AND (itmf.username = %s))
                  WHERE
                     (itmf.username IS NULL)
                     AND (itmv.stack_id IN (%s))
                  """ % (
                        qb.db.quoted(username),
                        self.update_stack_ids,
                    ))
                    rows = qb.db.sql(missing_sids_sql)
                    log.debug('fetch_n_save: missing: %d' %
                              (len(missing_sids_sql), ))
                    value_objs = []
                    for row in rows:
                        # These value objects match below:
                        #   INSERT INTO item_findability
                        #      (item_stack_id, username, user_id,
                        #       library_squelch, show_in_history, branch_id)
                        value_objs.append("(%d, '%s', %d, %d, %s, %d)" % (
                            row['stack_id'],
                            username,
                            user_id,
                            Library_Squelch.squelch_always_hide,
                            'FALSE',
                            qb.branch_hier[0][0],
                        ))
                    self.insert_values = ", ".join(value_objs)

                success = qb.db.transaction_retryable(self.attempt_save, qb,
                                                      qb)

                if not success:
                    log.warning('fetch_n_save: failed!')

        if gwis_errs:
            err_str = ' / '.join(gwis_errs)
            log.debug('fetch_n_save: err_str: %s' % (err_str, ))
            raise GWIS_Error(err_str)
    def fetch_n_save(self):
        command.Op_Handler.fetch_n_save(self)

        # Assemble the qb from the request.
        qb = self.req.as_iqb(addons=False)
        g.assurt(qb.filters == Query_Filters(None))

        item_stack_ids = qb.filters.decode_ids_compact('./fbil_sids',
                                                       self.req.doc_in)
        if ((not item_stack_ids) or (item_stack_ids.find(',') != -1)):
            raise GWIS_Error('Expecting one stack ID in fbil_sids doc.')

        items = item_user_access.Many()
        g.assurt(qb.sql_clauses is None)
        qb.sql_clauses = item_user_access.Many.sql_clauses_cols_all.clone()
        qb.filters.dont_load_feat_attcs = True
        qb.filters.only_stack_ids = item_stack_ids
        sql_many = items.search_get_sql(qb)

        sql_itmf = ("""
         SELECT
            itmf.item_stack_id
            , itmf.username
            -- , itmf.user_id
            , itmf.library_squelch
            , itmf.show_in_history
            -- , itmf.last_viewed
            -- , itmf.branch_id
         FROM (%s) AS gia
         JOIN item_findability AS itmf
            ON (gia.stack_id = itmf.item_stack_id)
         WHERE
            (       (itmf.username = %s)
                AND (gia.access_level_id <= %d))
            OR (    (itmf.username = %s)
                AND (gia.access_level_id <= %d))
         """ % (
            sql_many,
            qb.db.quoted(conf.anonymous_username),
            Access_Level.arbiter,
            qb.db.quoted(qb.username),
            Access_Level.viewer,
        ))

        rows = qb.db.sql(sql_itmf)

        if len(rows) == 0:
            raise GWIS_Warning('No item_findability for user-item.')

        # We'll find one or two records: one for the user, and one for the
        # public.
        # EXPLAIN: What records exist for anon route request?
        #          [lb] thinks it's a GIA record with a stealth secret,
        #               but probably not an item_findability record.
        #
        #          FIXME: TEST: anon get route, log in, save route
        #
        fbilities = etree.Element('fbilities')
        for row in rows:
            fbility = etree.Element('fbility')
            misc.xa_set(fbility, 'sid', row['item_stack_id'])
            if row['username'] == conf.anonymous_username:
                # MAGIC_NUMBER: Usernames prefixed with a floorbar are special.
                username_hacked = '_anonymous'
            else:
                username_hacked = row['username']
            misc.xa_set(fbility, 'unom', username_hacked)
            #misc.xa_set(fbility, 'uid', row['user_id'])
            misc.xa_set(fbility, 'sqel', row['library_squelch'])
            misc.xa_set(fbility, 'hist', row['show_in_history'])
            #misc.xa_set(fbility, 'lstv', row['last_viewed'])
            #misc.xa_set(fbility, 'brid', row['branch_id'])
            fbilities.append(fbility)
        self.itmf_xml = fbilities