def refresh(self, varenv): '''try to refresh a complete namespace from the graph. set self.complete iff successful. ''' # see if we can fetch the whole thing: # for large namespaces, don't try to fetch the whole thing if not self.complete: return datelineqs = '' if self.last_dateline is not None: datelineqs = 'dateline>%s' % self.last_dateline args = (self.namemap.bootstrap.has_key[1:], self.guid[1:], datelineqs, self.max_complete + 1) qs = '(typeguid=%s left=%s comparator="octet" datatype=string %s pagesize=%d result=((value left right)))' % args r = self.namemap.gc.read_varenv(qs, varenv) # check if we hit the maximum size for cacheable namespaces if len(r) > self.max_complete: LOG.notice('mql.namespace.refresh', '%s too large to cache' % self.guid) self.complete = 0 elif self.complete == -1: self.complete = 1 if len(r) > 0: self.update_namespaces(r) else: if self.last_dateline is not None: # XXX should extract the dateline from the empty result and # update self.last_dateline in order to minimize the dateline # ranges in later queries. pass
def check_permission_permission(querier, varenv, permission_guid): """ Check if the user has permission to administer the given permission """ permission_permission = varenv.setdefault('permission_permission', {}) if permission_guid not in permission_permission: userguid = varenv.get_user_guid() authorityguid = varenv.authority_guid permission = Permission(querier, permission_guid) has_access = permission.user_has_permission_permission( userguid, varenv) if not has_access and authorityguid: has_access = permission.user_has_permission_permission( authorityguid, varenv) if has_access: LOG.notice( 'access.authority', 'for user %s, permission %s and authority %s' % (userguid, permission_guid, authorityguid)) permission_permission[permission_guid] = has_access return permission_permission[permission_guid]
def check_permission(querier, varenv, permissionguid): """ Check if the user can write to objects permitted by permission_guid """ write_permission = varenv.setdefault('write_permission', {}) if permissionguid not in write_permission: userguid = varenv.get_user_guid() authorityguid = varenv.authority_guid permission = Permission(querier, permissionguid) has_access = permission.user_has_write_permission(userguid, varenv) if not has_access and authorityguid: has_access = permission.user_has_write_permission( authorityguid, varenv) if has_access: LOG.notice( 'access.authority', 'for user %s, permission %s and authority %s' % (userguid, permissionguid, authorityguid)) if not has_access and varenv.get('$privileged') is Privileged: LOG.notice( 'access.privileged', 'for user %s and permission %s' % (userguid, permissionguid)) has_access = True write_permission[permissionguid] = has_access return write_permission[permissionguid]
def check_write_throttle(querier, varenv): userguid = varenv.get_user_guid() max_writes = varenv.get('max_writes', None) if max_writes is None or userguid in MAX_WRITE_EXCEPTED_USERS: LOG.error('write.throttle.skipped', 'user=%s skipped write throttle' % userguid) return True # userguid starts with a '#' while max_writes['guid'] does not. # We need to strip the '#' in order for the comparison to succeed. if userguid[0] == '#': userguid = userguid[1:] if max_writes['guid'] != userguid: LOG.notice( 'write.throttle.different_users', 'Logged in user: %s different from mqlwrite user: %s' % (max_writes['guid'], userguid)) # 1 day tdelta = timedelta(1) yesterday = (datetime.utcnow() - tdelta).isoformat() # MQL attribution models documented at: # https://wiki.metaweb.com/index.php/MQL_Attribution_for_OAuth%2C_Acre%2C_etc # normal attribution query # need the optional to suppress EMPTY on count=0 graphq = ('(scope=%s timestamp>%s live=dontcare newest>=0 result=(count) ' 'optional)') % (max_writes['guid'], yesterday) gresult = querier.gc.read_varenv(graphq, varenv) count = int(gresult[0]) # oauth/open social attribution query graphq = ('(scope->(scope=%s) timestamp>%s live=dontcare newest>=0 ' 'result=(count) optional)') % (max_writes['guid'], yesterday) gresult = querier.gc.read_varenv(graphq, varenv) count += int(gresult[0]) if count > max_writes['limit']: LOG.alert( 'write.throttle.exceeded', 'user=%s count=%s max=%d delta=%s' % (max_writes['guid'], count, max_writes['limit'], str(tdelta))) msg = 'Daily write limit of %s was exceeded.' % max_writes['limit'] raise MQLWriteQuotaError(None, msg, user='******' + max_writes['guid'], count=count, max_writes=max_writes['limit'], period=str(tdelta)) else: LOG.notice( 'write.throttle.ok', 'user=%s count=%s max=%s' % (max_writes['guid'], count, max_writes['limit'])) return True
def check_change_permission_by_user(querier, varenv, old_permission_guid, new_permission_guid): has_old_permission = \ check_permission_permission(querier, varenv, old_permission_guid) has_new_permission = \ check_permission_permission(querier, varenv, new_permission_guid) # privileged access bypass if varenv.get('$privileged') is Privileged: LOG.notice( 'access.privileged', 'for user %s changing permission %s to %s' % (varenv.get_user_guid(), old_permission_guid, new_permission_guid)) return True # no privileged block because I don't have any need to # privilege this operation (yet) when there is a need a # privileged block can be put here. return has_old_permission and has_new_permission
reserved_names = ('request_id', 'cost', 'lang', 'transaction_id', 'permission', 'cursor', 'user') valid_queries = ((k, v) for k, v in sq.iteritems() if k not in reserved_names) # make sure to copy the request_id if 'request_id' in sq: response['request_id'] = sq['request_id'] # should only looking either at sq['query'] for a single query or # sq['queries'] for multiple queries for id, subq in valid_queries: # assuming querier is a bound method here.. LOG.notice('Query', '%s.%s' % (querier.im_class.__name__, querier.__name__), subq=subq) try: results[id] = querier(subq, varenv) response.extend(status='200 OK') except EmptyResult, e: LOG.info('emptyresult', '%s' % e) response.log('empty result for query %s' % subq) result = None # exceptions should be packed into response['error'] except ParameterizedError, e: if isinstance(e, MQLInternalError): response.extend(status='500 Internal Server Error')