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
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
def check_for_text(tiddler, environ): if 'foobar' not in tiddler.text: raise InvalidTiddlerError('missing "foobar" in tiddler.text')