Esempio n. 1
0
def validate_mapuser(tiddler, environ):
    """
    If a tiddler is put to the MAPUSER bag clear
    out the tiddler and set fields['mapped_user']
    to the current username. There will always be
    a current username because the create policy
    for the bag is set to ANY.
    """
    if tiddler.bag == 'MAPUSER':
        try:
            user_cookie = environ['HTTP_COOKIE']
            cookie = Cookie.SimpleCookie()
            cookie.load(user_cookie)
            cookie_value = cookie['tiddlyweb_secondary_user'].value
            secret = environ['tiddlyweb.config']['secret']
            usersign, cookie_secret = cookie_value.rsplit(':', 1)
        except KeyError:
            raise InvalidTiddlerError('secondary cookie not present')

        if cookie_secret != sha('%s%s' % (usersign, secret)).hexdigest():
            raise InvalidTiddlerError('secondary cookie invalid')

        if usersign != tiddler.title:
            raise InvalidTiddlerError('secondary cookie mismatch')

        store = environ['tiddlyweb.store']
        # XXX this is a potentially expensive operation but let's not
        # early optimize
        if tiddler.title in (user.usersign for user in store.list_users()):
            raise InvalidTiddlerError('username exists')
        tiddler.text = ''
        tiddler.tags = []
        tiddler.fields = {}
        tiddler.fields['mapped_user'] = environ['tiddlyweb.usersign']['name']
    return tiddler
def check_html(value, environ):
    """
    This function does the actual validation.
    environ must have 'allowed_tags' and
    'allowed_attributes' in it.
    
    Removes unwanted tags, attributes and
    comments.
    
    Value should be the string to be validated.
    """
    if type(value) != unicode:
        try:
            value = unicode(value)
        except UnicodeDecodeError:
            raise InvalidTiddlerError(
                'HTML Validation Failed: contents of tiddler not a valid string.'
            )

    url_regex = re.compile(r'[\s]*(&#x.{1,7})?'.join(list('javascript:')))

    soup = BeautifulSoup(value)

    for comment in soup.findAll(text=lambda text: isinstance(text, Comment)):
        comment.extract()

    for tag in soup.findAll(True):
        if tag.name not in environ['tiddlyweb.config']['allowed_tags']:
            tag.hidden = True
        tag.attrs = [
            (attr, url_regex.sub('', val)) for attr, val in tag.attrs
            if attr in environ['tiddlyweb.config']['allowed_attributes']
        ]

    return soup.renderContents().decode('utf8')
def check_bag(tiddler, store, bag_names):
    """
    check that the tiddler is not in the listed bags
    """
    for bag_name in bag_names:
        bag = Bag(bag_name)
        bag = store.get(bag)
        tiddlers = bag.gen_tiddlers()
        if tiddler.title in [reserved.title for reserved in tiddlers]:
            raise InvalidTiddlerError('Tiddler name is reserved: %s' \
                % tiddler.title)
def check_recaptcha(tiddler, environ):
    """
    validates a tiddler using the recaptcha api
    """
    #get required variables for POSTing to reCAPTCHA
    privatekey = environ['tiddlyweb.config']['recaptcha_private_key']
    remoteip = environ['REMOTE_ADDR']
    challenge = urllib.quote(tiddler.fields.get('recaptcha_challenge_field', \
        None))
    response = urllib.quote(tiddler.fields.get('recaptcha_response_field', \
        None))

    #make sure fields are present
    if not challenge:
        raise InvalidTiddlerError('recaptcha_challenge_field not found')
    if not response:
        raise InvalidTiddlerError('recaptcha_response_field not found')

    #send the request to reCAPTCHA
    postdata = 'privatekey=%s&remoteip=%s&challenge=%s&response=%s' % \
        (privatekey, remoteip, challenge, response)
    http = httplib2.Http()
    response, content = http.request(SERVER_URL, method='POST', \
        headers={'Content-type': 'application/x-www-form-urlencoded'}, \
        body=postdata)

    if response['status'] != '200':
        raise InvalidTiddlerError('reCAPTCHA verification failed. Response ' \
            'code "%s" received.' % response)

    content = content.splitlines()
    result = content[0]
    if result == 'false':
        raise InvalidTiddlerError('reCAPTCHA verification failed. Please try ' \
            'again. Error message was "%s"' % content[1])

    #remove the CAPTCHA fields so they don't appear in the saved tiddler
    tiddler.fields.pop('recaptcha_challenge_field')
    tiddler.fields.pop('recaptcha_response_field')

    return tiddler
def validate_tiddlywiki(tiddler, environ):
    """
    check RESERVED_TITLES, tiddlers in named bag, presence of systemConfig
    """
    if tiddler.title in RESERVED_TITLES:
        raise InvalidTiddlerError('Tiddler name is reserved: %s' \
            % tiddler.title)
    if 'systemConfig' in tiddler.tags:
        tiddler.tags.remove('systemConfig')

    check_bag(tiddler, environ['tiddlyweb.store'], \
        environ['tiddlyweb.config'].get('reserved_bag_names', []))
    return tiddler
Esempio n. 6
0
def validate_mapspace(tiddler, environ):
    """
    If a tiddler is put to the MAPSPACE bag clear
    out the tiddler and set fields['mapped_space']
    to the current space.

    Elsewhere in the space the mapped_space can map
    a alien domain to space.
    """
    if tiddler.bag == 'MAPSPACE':
        current_space = determine_space(environ, determine_host(environ)[0])
        recipe_name = determine_space_recipe(environ, current_space)
        if recipe_name != '%s_private' % current_space:
            raise InvalidTiddlerError('non member may not map space')

        tiddler.text = ''
        tiddler.tags = []
        tiddler.fields = {}
        tiddler.fields['mapped_space'] = current_space
    return tiddler
Esempio n. 7
0
def check_for_text(tiddler, environ):
    if 'foobar' not in tiddler.text:
        raise InvalidTiddlerError('missing "foobar" in tiddler.text')