Example #1
0
    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
Example #2
0
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]
Example #3
0
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]
Example #4
0
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
Example #5
0
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
Example #6
0
        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')