def search(self, search_query): """ Search in the store for :py:class:`tiddlers <tiddlyweb.model.tiddler.Tiddler>` that match ``search_query``. This is intentionally implemented as a simple and limited grep through files. """ bag_filenames = self._bag_filenames() query = search_query.lower() for bagname in bag_filenames: bagname = unquote(bagname) tiddler_dir = self._tiddlers_dir(bagname) tiddler_files = self._files_in_dir(tiddler_dir) for tiddler_name in tiddler_files: tiddler = Tiddler(title=unquote(tiddler_name), bag=bagname) try: revision_id = self.list_tiddler_revisions(tiddler)[0] if query in tiddler.title.lower(): yield tiddler continue with codecs.open( self._tiddler_full_filename(tiddler, revision_id), encoding='utf-8') as tiddler_file: for line in tiddler_file: if query in line.lower(): yield tiddler break except (OSError, NoTiddlerError) as exc: LOGGER.warn('malformed tiddler during search: %s:%s, %s', bagname, tiddler_name, exc) return
def list_bags(self): """ List all the :py:class:`bags <tiddlyweb.model.bag.Bag>` in the store. """ bags = self._bag_filenames() return (Bag(unquote(bag)) for bag in bags)
def get_route_value(environ, name): """ Retrieve and decode ``name`` from data provided in WSGI route. If ``name`` is not present in the route, allow KeyError to raise. """ value = environ['wsgiorg.routing_args'][1][name] value = unquote(value) return value.replace('%2F', '/')
def _get_bag_tiddlers(self, bag): filepath = os.path.join(self._base, encode_name(bag.name)) if os.path.isdir(filepath): filenames = os.listdir(filepath) for name in filenames: name = unquote(name) name = name.rsplit('.', 1)[0] tiddler = Tiddler(name, bag.name) yield tiddler
def _get_title_from_uri(uri): """ Turn a uri of tiddler into the title of a tiddler, by looking at the final segment of the path. """ title = uri.split('/')[-1] title = _strip_extension(title) title = unquote(title) return title
def list_recipes(self): """ List all the :py:class:`recipes <tiddlyweb.model.recipe.Recipe>` in the store. """ path = os.path.join(self._store_root(), 'recipes') recipes = self._files_in_dir(path) return (Recipe(unquote(recipe)) for recipe in recipes)
def list_users(self): """ List all the :py:class:`users <tiddlyweb.model.user.User>` in the store. """ path = os.path.join(self._store_root(), 'users') users = self._files_in_dir(path) return (User(unquote(user)) for user in users)
def list_bag_tiddlers(self, bag): """ List all the :py:class:`tiddlers <tiddlyweb.model.tiddler.Tiddler>` in the provided :py:class:`bag <tiddlyweb.model.bag.Bag>`. """ tiddlers_dir = self._tiddlers_dir(bag.name) try: tiddlers = (filename for filename in self._files_in_dir(tiddlers_dir) if os.path.isdir(os.path.join(tiddlers_dir, filename))) except (IOError, OSError) as exc: raise NoBagError('unable to list tiddlers in bag: %s' % exc) for title in tiddlers: title = unquote(title) tiddler = Tiddler(title, bag.name) yield tiddler
def test_roundtrip_unicode_recipe(): encoded_recipe_name = '%E3%81%86%E3%81%8F%E3%81%99' recipe_name = unquote(encoded_recipe_name) recipe_list = [[recipe_name, '']] body = simplejson.dumps(dict(desc='', recipe=recipe_list)) response, content = http.requestU( 'http://our_test_domain:8001/recipes/%s' % encoded_recipe_name, method='PUT', body=body.encode('utf-8'), headers={'Content-Type': 'application/json'}) assert response['status'] == '204' recipe = Recipe(recipe_name) recipe = store.get(recipe) assert recipe.get_recipe() == recipe_list response, content = http.requestU( 'http://our_test_domain:8001/recipes/%s.json' % encoded_recipe_name, method='GET') assert response['status'] == '200' assert simplejson.loads(content)['recipe'] == recipe_list
def fake_start_response(status, headers, exc_info=None): """ add a csrf_token header (if we need to) """ user_cookie = Cookie.SimpleCookie() user_cookie.load(str(environ.get('HTTP_COOKIE', ''))) csrf_cookie = user_cookie.get('csrf_token') timestamp = '' cookie_user = None if csrf_cookie: try: timestamp, cookie_user, _ = csrf_cookie.value.split(':', 2) cookie_user = unquote(cookie_user) except ValueError: timestamp = '' cookie_user = '' username = environ['tiddlyweb.usersign']['name'] now = datetime.utcnow().strftime('%Y%m%d%H') if username == 'GUEST': if cookie_user: if 'MSIE' in environ.get('HTTP_USER_AGENT', ''): expires = 'Expires=%s;' % datetime.strftime( datetime.utcnow() - timedelta(hours=1), '%a, %d-%m-%y %H:%M:%S GMT') else: expires = 'Max-Age=0;' set_cookie = 'csrf_token=; %s' % expires headers.append(('Set-Cookie', set_cookie)) else: start_response(status, headers, exc_info) return elif now != timestamp or cookie_user != username: user, space, secret = get_nonce_components(environ) nonce = gen_nonce(user, space, now, secret) # URL encode cookie for safe Unicode usernames set_cookie = 'csrf_token=%s' % quote(nonce.encode('utf-8'), safe=".!~*'():") headers.append(('Set-Cookie', set_cookie)) start_response(status, headers, exc_info)
def test_roundtrip_unicode_bag(): encoded_bag_name = '%E3%81%86%E3%81%8F%E3%81%99' bag_name = unquote(encoded_bag_name) bag_content = {'policy': {'read': ['a', 'b', 'c', 'GUEST']}} body = simplejson.dumps(bag_content) response, content = http.requestU( 'http://our_test_domain:8001/bags/%s' % encoded_bag_name, method='PUT', body=body, headers={'Content-Type': 'application/json'}) assert response['status'] == '204' bag = Bag(bag_name) bag = store.get(bag) assert bag.name == bag_name response, content = http.requestU( 'http://our_test_domain:8001/bags/%s.json' % encoded_bag_name, method='GET') bag_data = simplejson.loads(content) assert response['status'] == '200' assert bag_data['policy']['read'] == ['a', 'b', 'c', 'GUEST']
def _recipe_lines(self, body): """ Given text containing a list of recipes, calculate the recipe information they hold and return as a list of bagname, filter lists. """ recipe_lines = [] if len(body): lines = body.rstrip().split('\n') for line in lines: if '?' in line: bag, query_string = line.split('?') filter_string = query_string else: bag = line filter_string = '' if bag.startswith('/bags/'): bagname = bag.split('/')[2] bagname = unquote(bagname) else: bagname = bag recipe_lines.append((bagname, filter_string)) return recipe_lines
def extract(self, environ, start_response): """ Extract the cookie, if there, from the headers and attempt to validate its contents. """ try: user_cookie = environ['HTTP_COOKIE'] LOGGER.debug('simple_cookie looking at cookie string: %s', user_cookie) cookie = SimpleCookie() cookie.load(str(user_cookie)) cookie_value = cookie['tiddlyweb_user'].value secret = environ['tiddlyweb.config']['secret'] usersign, cookie_secret = cookie_value.rsplit(':', 1) if cookie_secret == sha('%s%s' % (usersign, secret)).hexdigest(): usersign = unquote(usersign) user = self.load_user(environ, usersign) return {"name": user.usersign, "roles": user.list_roles()} except CookieError as exc: raise HTTP400('malformed cookie: %s' % exc) except (KeyError, ValueError): pass return False
def test_uri(): encoded_name = 'aaa%25%E3%81%86%E3%81%8F%E3%81%99' name = unquote(encoded_name) assert uri(name) == encoded_name
def _parse_fragment(fragment): """ Turn a TiddlyWiki permaview into a list of tiddlers. """ fragment = unquote(fragment) return string_to_tags_list(fragment)
""" Test a full suite of unicode interactions. """ from tiddlyweb.fixups import unquote import simplejson import httplib2 from .fixtures import (reset_textstore, _teststore, initialize_app, get_http) from tiddlyweb.model.recipe import Recipe from tiddlyweb.model.tiddler import Tiddler from tiddlyweb.model.bag import Bag from tiddlyweb.model.user import User encoded_name = 'aaa%25%E3%81%86%E3%81%8F%E3%81%99' name = unquote(encoded_name) http = get_http() def setup_module(module): initialize_app() reset_textstore() module.store = _teststore() user = User(name) user.set_password(name) module.store.put(user) module.cookie = None def test_unicode_cookie(): global cookie
from tiddlyweb.fixups import unquote import simplejson import httplib2 from .fixtures import (reset_textstore, _teststore, initialize_app, get_http) from tiddlyweb.model.recipe import Recipe from tiddlyweb.model.tiddler import Tiddler from tiddlyweb.model.bag import Bag from tiddlyweb.model.user import User from tiddlyweb.config import config encoded_name = 'aaa%25%E3%81%86%E3%81%8F%E3%81%99' name = unquote(encoded_name) http = get_http() def setup_module(module): initialize_app() reset_textstore() module.store = _teststore() user = User(name) user.set_password(name) module.store.put(user) module.cookie = None def test_unicode_cookie(): global cookie