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