示例#1
0
def get(environ, start_response):
    """
    Perform a search on the store. What search
    means and what results are returned is dependent
    on the search implementation (if any) in the
    chosen store.
    """
    store = environ['tiddlyweb.store']
    search_query = get_search_query(environ)
    title = 'Search for %s' % search_query
    title = environ['tiddlyweb.query'].get('title', [title])[0]

    try:
        tiddlers = get_tiddlers(environ)

        usersign = environ['tiddlyweb.usersign']

        candidate_tiddlers = Tiddlers(title=title, store=store)
        candidate_tiddlers.is_search = True

        for tiddler in readable_tiddlers_by_bag(store, tiddlers, usersign):
            candidate_tiddlers.add(tiddler)

    except StoreMethodNotImplemented:
        raise HTTP400('Search system not implemented')
    except StoreError, exc:
        raise HTTP400('Error while processing search: %s' % exc)
示例#2
0
def _create_bag(environ):
    """Take the form input and turn it into a bag."""
    query_data = _flatten_form_data(environ['tiddlyweb.query'])
    logging.debug(query_data)
    store = environ['tiddlyweb.store']
    try:
        new_bag_name = query_data['bag_name']

        if _bag_exists(store, new_bag_name):
            raise HTTP409('That bag may not be created.')

        new_bag = Bag(new_bag_name)

        username = environ['tiddlyweb.usersign']['name']
        new_bag.policy.owner = username
        new_bag.policy.manage = [username]
        new_bag.desc = query_data.get('bag_desc', '')

        for policy_type in ('read', 'write', 'create', 'delete'):
            texted = query_data.get(policy_type + '_text', None)
            logging.debug('texted: %s' % texted)
            if texted:
                new_bag.policy.__setattr__(
                    policy_type,
                    [x.lstrip().rstrip() for x in texted.split(',')])
            else:
                set = query_data[policy_type]
                new_bag.policy.__setattr__(
                    policy_type, _policy_form_to_entry(username, set))

        store.put(new_bag)
    except KeyError, exc:
        raise HTTP400('something went wrong processing for: %s' % exc)
示例#3
0
def _create_recipe(environ):
    """Take the form input and turn it into a recipe."""
    # get bag_names before we flatten because it will be a list
    bag_names = environ['tiddlyweb.query'].get('bags', [])
    query_data = _flatten_form_data(environ['tiddlyweb.query'])
    store = environ['tiddlyweb.store']
    try:
        new_recipe_name = query_data['recipe_name']

        if _recipe_exists(store, new_recipe_name):
            raise HTTP409('That recipe may not be created.')

        new_recipe = Recipe(new_recipe_name)

        username = environ['tiddlyweb.usersign']['name']
        new_recipe.policy.owner = username
        new_recipe.policy.manage = [username]
        new_recipe.desc = query_data.get('recipe_desc', '')

        privacy = query_data['privacy']
        new_recipe.policy.read = _policy_form_to_entry(username, privacy)

        bag_list = []

        if query_data.get('autowiki', 0):
            bag_list.extend(AUTOWIKI_BAGS)

        # don't worry about default content bag yet
        bag_list.extend(bag_names)
        recipe_list = [[bag_name, ''] for bag_name in bag_list]
        new_recipe.set_recipe(recipe_list)

        store.put(new_recipe)
    except KeyError, exc:
        raise HTTP400('something went wrong processing for: %s' % exc)
示例#4
0
def send_tiddlers(environ, start_response, tiddlers=None):
    """
    Output the tiddlers contained in the provided
    Tiddlers collection in a Negotiated representation.
    Often, but not always, a wiki.
    """
    last_modified = None
    etag = None
    download = environ['tiddlyweb.query'].get('download', [None])[0]
    filters = environ['tiddlyweb.filters']
    store = environ['tiddlyweb.store']

    if filters:
        candidate_tiddlers = Tiddlers(store=store)
        try:
            candidate_tiddlers.title = tiddlers.title
            candidate_tiddlers.is_search = tiddlers.is_search
            candidate_tiddlers.is_revisions = tiddlers.is_revisions
        except AttributeError:
            pass
        try:
            for tiddler in recursive_filter(filters, tiddlers):
                recipe = tiddler.recipe
                if not tiddler.store:
                    tiddler = store.get(tiddler)
                    if recipe:
                        tiddler.recipe = recipe
                candidate_tiddlers.add(tiddler)
        except FilterError, exc:
            raise HTTP400('malformed filter: %s' % exc)
示例#5
0
def webfinger(environ, start_response):
    """
    Display the webfinger information for a given user.
    """
    http_host, host_url = determine_host(environ)
    if http_host != host_url:
        raise HTTP404('No webfinger at this host: %s' % http_host)

    username = environ['tiddlyweb.query'].get('q', [None])[0]

    if not username:
        raise HTTP400('No account provided to webfinger query')

    if username.startswith('acct:'):
        username = username.split(':', 1)[1]
    username = username.split('@', 1)[0]

    start_response('200 OK', [('Content-Type', 'application/xrd+xml')])

    return [
        WEBFINGER_TEMPLATE % {
            'username': username,
            'host': http_host,
            'server_host': server_base_url(environ)
        }
    ]
def get(environ, start_response):
    """
    Using query parameters, determine the current tiddler
    and produce an editor for it.
    """
    usersign = environ['tiddlyweb.usersign']
    try:
        tiddler_name = environ['tiddlyweb.query'].get('tiddler', [''])[0]
        recipe_name = environ['tiddlyweb.query'].get('recipe', [''])[0]
        bag_name = environ['tiddlyweb.query'].get('bag', [''])[0]
    except (KeyError, IndexError):
        raise HTTP400('tiddler, recipe and bag query strings required')

    store = environ['tiddlyweb.store']

    tiddler = Tiddler(tiddler_name)
    if bag_name:
        tiddler.bag = bag_name
    else:
        recipe = Recipe(recipe_name)
        try:
            recipe = store.get(recipe)
            tiddler.bag = control.determine_tiddler_bag_from_recipe(
                recipe, tiddler).name
            tiddler.recipe = recipe.name
        except NoRecipeError, exc:
            raise HTTP404('unable to edit %s, recipe %s not found: %s' %
                          (tiddler.title, recipe_name, exc))
        except NoBagError, exc:
            raise HTTP404('unable to edit %s: %s' % (tiddler.title, exc))
示例#7
0
def reflect(environ, start_response):
    if environ.get('tiddlyweb.type', '') == 'multipart/form-data':
        form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)
    else:
        # This hack to ensure that we have a uniform interface
        # On the cgi form field values whether we are multipart or
        # url encoded.
        form = cgi.FieldStorage()
        form.list = []
        for key, value in environ['tiddlyweb.query'].items():
            for single_value in value:
                form.list.append(cgi.MiniFieldStorage(key, single_value))
    # Ordering is important here. File will often appear true when
    # it is not.
    if 'uri' in form and form['uri'].value:
        try:
            uri = form.getfirst('uri')
            request = urllib2.Request(uri)
            if (request.get_type() != 'file'):
                filehandle = urllib2.urlopen(uri)
                type = filehandle.info()['content-type']
            else:
                raise ValueError('file: not allowed')
        except (ValueError, AttributeError, urllib2.URLError), exc:
            raise HTTP400('URI Input error: %s' % exc)
示例#8
0
def send_tiddlers(environ, start_response, tiddlers=None):
    """
    Output the tiddlers contained in the provided
    Tiddlers collection in a Negotiated representation.
    Often, but not always, a wiki.
    """
    last_modified = None
    etag = None
    download = environ['tiddlyweb.query'].get('download', [None])[0]
    filters = environ['tiddlyweb.filters']
    store = environ['tiddlyweb.store']

    if tiddlers.store is None and not filters:
        logging.warn('Incoming tiddlers no store set %s', inspect.stack()[1])

    if filters:
        candidate_tiddlers = Tiddlers(store=store)
        try:
            candidate_tiddlers.title = tiddlers.title
            candidate_tiddlers.link = tiddlers.link
            candidate_tiddlers.is_search = tiddlers.is_search
            candidate_tiddlers.is_revisions = tiddlers.is_revisions
        except AttributeError:
            pass
        try:
            for tiddler in recursive_filter(filters, tiddlers):
                candidate_tiddlers.add(tiddler)
        except FilterError, exc:
            raise HTTP400('malformed filter: %s' % exc)
示例#9
0
文件: bag.py 项目: funkyeah/tiddlyweb
def delete(environ, start_response):
    """
    Remove a bag and its tiddlers from the store.
    How the store chooses to handle remove and what
    it means is up to the store.
    """
    bag_name = web.get_route_value(environ, 'bag_name')
    bag_name = web.handle_extension(environ, bag_name)

    usersign = environ['tiddlyweb.usersign']

    bag = _get_bag(environ, bag_name)
    bag.policy.allows(usersign, 'manage')
    # reuse the store attribute that was set on the
    # bag when we "got" it.
    # we don't need to check for existence here because
    # the above get already did
    try:
        store = environ['tiddlyweb.store']
        store.delete(bag)
    except StoreMethodNotImplemented:
        raise HTTP400('Bag DELETE not supported')

    start_response("204 No Content", [])
    return []
示例#10
0
文件: bag.py 项目: funkyeah/tiddlyweb
def put(environ, start_response):
    """
    Put a bag to the server, meaning the description and
    policy of the bag, if policy allows.
    """
    bag_name = web.get_route_value(environ, 'bag_name')
    bag_name = web.handle_extension(environ, bag_name)

    bag = Bag(bag_name)
    store = environ['tiddlyweb.store']
    length = environ['CONTENT_LENGTH']

    usersign = environ['tiddlyweb.usersign']

    try:
        bag = store.get(bag)
        bag.policy.allows(usersign, 'manage')
    except NoBagError:
        create_policy_check(environ, 'bag', usersign)

    try:
        serialize_type = web.get_serialize_type(environ)[0]
        serializer = Serializer(serialize_type, environ)
        serializer.object = bag
        content = environ['wsgi.input'].read(int(length))
        serializer.from_string(content.decode('utf-8'))

        bag.policy.owner = usersign['name']

        _validate_bag(environ, bag)
        store.put(bag)
    except BagFormatError, exc:
        raise HTTP400('unable to put bag: %s' % exc)
def put_user(environ, start_response):
    """
    Allow a user or an admin to set the password for a user
    at /users/{usersign}. A non-admin can only set their
    own password.

    The sent data is a JSON dict with at least the key
    'password' with a value of whatever the password
    should be.

    Users of this method should take not that that password
    is being sent in the clear over what is likely an
    unencrypted network.
    """
    store = environ['tiddlyweb.store']
    current_user = environ['tiddlyweb.usersign']
    target_user = environ['wsgiorg.routing_args'][1]['usersign']
    target_user = urllib.unquote(target_user)
    target_user = unicode(target_user, 'utf-8')

    if not ('ADMIN' in current_user['roles']
            or current_user['name'] == target_user):
        raise HTTP403('Incorrect User')

    content_type = environ['tiddlyweb.type']
    length = environ['CONTENT_LENGTH']
    if content_type != 'application/json':
        raise HTTP415('application/json required')
    content = environ['wsgi.input'].read(int(length))

    try:
        user_info = simplejson.loads(content)
    except ValueError, exc:
        raise HTTP400('Invalid JSON, %s' % exc)
示例#12
0
def list_entities(environ, start_response, mime_type, store_list,
                  serializer_list):
    """
    Get a list of all the bags or recipes the current user can read.
    """
    filters = environ['tiddlyweb.filters']
    try:
        kept_entities = _filter_readable(environ, store_list(), filters)
    except FilterError, exc:
        raise HTTP400(exc)
示例#13
0
def get_search_query(environ):
    """
    Inspect tiddlyweb.query in the environment to get
    the search query.
    """
    try:
        search_query = environ['tiddlyweb.query']['q'][0]
        search_query = urllib.unquote(search_query)
    except (KeyError, IndexError):
        raise HTTP400('query string required')
    return search_query
示例#14
0
def _length_and_type(environ):
    """
    To PUT we must have content-length and content-type
    headers. Raise 400 if we cannot get these things.
    """
    try:
        length = environ['CONTENT_LENGTH']
        content_type = environ['tiddlyweb.type']
    except KeyError:
        raise HTTP400(
            'Content-Length and content-type required to put tiddler')
    return length, content_type
示例#15
0
 def extract_query(self, environ):
     """
     Read the QUERY_STRING and body (if a POSTed form) to extract
     query paremeters. Put the results in tiddlyweb.query.
     """
     content_type = environ.get('CONTENT_TYPE', '')
     environ['tiddlyweb.query'] = {}
     if environ['REQUEST_METHOD'].upper() == 'POST' and \
             content_type.startswith('application/x-www-form-urlencoded'):
         try:
             length = environ['CONTENT_LENGTH']
             content = environ['wsgi.input'].read(int(length))
         except KeyError, exc:
             raise HTTP400('Invalid post, unable to read content: %s' % exc)
         posted_data = parse_qs(content, keep_blank_values=True)
         try:
             _update_tiddlyweb_query(environ, posted_data)
         except UnicodeDecodeError, exc:
             raise HTTP400(
                 'Invalid encoding in query string, utf-8 required: %s',
                 exc)
示例#16
0
def put(environ, start_response):
    """
    Put a new recipe to the server.
    """
    recipe_name = environ['wsgiorg.routing_args'][1]['recipe_name']
    recipe_name = urllib.unquote(recipe_name)
    recipe_name = unicode(recipe_name, 'utf-8')
    recipe_name = web.handle_extension(environ, recipe_name)

    recipe = Recipe(recipe_name)
    store = environ['tiddlyweb.store']
    length = environ['CONTENT_LENGTH']

    usersign = environ['tiddlyweb.usersign']

    try:
        recipe = store.get(recipe)
        recipe.policy.allows(usersign, 'manage')
    except NoRecipeError:
        create_policy_check(environ, 'recipe', usersign)

    try:
        serialize_type = web.get_serialize_type(environ)[0]
    except TypeError:
        raise HTTP400('Content-type header required')

    try:
        serializer = Serializer(serialize_type, environ)
        serializer.object = recipe
        content = environ['wsgi.input'].read(int(length))
        serializer.from_string(content.decode('utf-8'))

        recipe.policy.owner = usersign['name']

        _validate_recipe(environ, recipe)
        store.put(recipe)
    except RecipeFormatError, exc:
        raise HTTP400('unable to put recipe: %s' % exc)
示例#17
0
def get_route_value(environ, name):
    """
    Retrieve and decode from UTF-8 data provided in WSGI route.

    If name is not present in the route, allow KeyError to raise.

    If the provided data is not URI escaped UTF-8, raise and HTTP400
    """
    try:
        value = environ['wsgiorg.routing_args'][1][name]
        value = urllib.unquote(value).decode('utf-8')
    except UnicodeDecodeError, exc:
        raise HTTP400('incorrect encoding for %s, UTF-8 required: %s',
                exc)
示例#18
0
def manage_mine(environ, start_response):
    """Handle POST"""
    # put a try around this stuff eventually
    creation = environ['tiddlyweb.query']['creatego'][0]
    if creation == 'Quick!':
        _quick_create(environ)
    elif creation == 'Create Recipe':
        _create_recipe(environ)
    elif creation == 'Create Bag':
        _create_bag(environ)
    else:
        raise HTTP400('Improper Form Submit')
    home_uri = '%s/mine' % environ['tiddlyweb.config']['server_prefix']
    raise HTTP302(home_uri)
示例#19
0
    def __call__(self, environ, start_response):

        def fake_start_response(status, headers, exc_info=None):
            """
            add a csrf_token header (if we need to)
            """
            if environ['tiddlyweb.usersign']['name'] == 'GUEST':
                start_response(status, headers, exc_info)
                return
            user_cookie = Cookie.SimpleCookie()
            user_cookie.load(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)
                except ValueError:
                    timestamp = ''
                    cookie_user = ''
            username = environ['tiddlyweb.usersign']['name']
            now = datetime.now().strftime('%Y%m%d%H')
            if now != timestamp or cookie_user != username:
                user, space, secret = get_nonce_components(environ)
                nonce = gen_nonce(user, space, now, secret)
                set_cookie = 'csrf_token=%s' % nonce
                headers.append(('Set-Cookie', set_cookie.encode()))
            start_response(status, headers, exc_info)

        def app():
            output = self.application(environ, fake_start_response)
            return output

        if environ['REQUEST_METHOD'] != 'POST':
            return app()
        if environ['tiddlyweb.usersign']['name'] == 'GUEST':
            return app()
        if environ.get('tiddlyweb.type', '') not in [
                'application/x-www-form-urlencoded',
                'multipart/form-data']:
            return app()
        form = environ['tiddlyweb.query']
        nonce = form.pop('csrf_token', [''])[0]
        try:
            self.check_csrf(environ, nonce)
        except InvalidNonceError, exc:
            raise HTTP400(exc)
示例#20
0
def delete(environ, start_response):
    """
    Delete a recipe, where what delete means
    depends on the store used.
    """
    recipe = _determine_recipe(environ)
    store = environ['tiddlyweb.store']

    recipe.policy.allows(environ['tiddlyweb.usersign'], 'manage')

    try:
        store.delete(recipe)
    except StoreMethodNotImplemented:
        raise HTTP400('Recipe DELETE not supported')

    start_response("204 No Content", [])
    return []
示例#21
0
    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']
            logging.debug('simple_cookie looking at cookie string: %s',
                    user_cookie)
            cookie = Cookie.SimpleCookie()
            cookie.load(user_cookie)
            cookie_value = cookie['tiddlyweb_user'].value
            secret = environ['tiddlyweb.config']['secret']
            usersign, cookie_secret = cookie_value.rsplit(':', 1)
            store = environ['tiddlyweb.store']

            if cookie_secret == sha('%s%s' % (usersign, secret)).hexdigest():
                usersign = usersign.decode('utf-8')
                user = self.load_user(environ, usersign)
                return {"name": user.usersign, "roles": user.list_roles()}
        except Cookie.CookieError, exc:
            raise HTTP400('malformed cookie: %s' % exc)
def post_user(environ, start_response):
    """
    Create a new user through a JSON POST to /users.
    If the not JSON, return 415. If users exists, return 409.

    The JSON should be a dict with two keys: 'username'
    and 'password'. Future iterations of this code
    will take additional keys and save them as fields
    to be used with the tiddlywebplugins.magicuser
    extractor.
    """
    content_type = environ['tiddlyweb.type']
    if content_type != 'application/json':
        raise HTTP415('application/json required')
    length = environ['CONTENT_LENGTH']
    content = environ['wsgi.input'].read(int(length))
    store = environ['tiddlyweb.store']

    try:
        user_info = simplejson.loads(content)
    except ValueError, exc:
        raise HTTP400('Invalid JSON, %s' % exc)
示例#23
0
            bag.policy.allows(usersign, 'read')
    except NoBagError, exc:
        raise HTTP404('recipe %s lists an unknown bag: %s' %
                      (recipe.name, exc))

    # from this point forward we know the tiddlers are
    # readable

    # get the tiddlers from the recipe and uniquify them
    try:
        candidate_tiddlers = control.get_tiddlers_from_recipe(recipe, environ)
    except NoBagError, exc:
        raise HTTP404('recipe %s lists an unknown bag: %s' %
                      (recipe.name, exc))
    except FilterError, exc:
        raise HTTP400('malformed filter: %s' % exc)

    if filters:
        tiddlers = Tiddlers(title=title)
    else:
        tiddlers = Tiddlers(title=title, store=store)

    for tiddler in candidate_tiddlers:
        tiddler.recipe = recipe.name
        tiddlers.add(tiddler)

    tiddlers.link = '%s/tiddlers' % web.recipe_url(environ, recipe, full=False)

    return send_tiddlers(environ, start_response, tiddlers=tiddlers)

示例#24
0
        if environ['REQUEST_METHOD'].upper() == 'POST' and \
                content_type.startswith('application/x-www-form-urlencoded'):
            try:
                length = environ['CONTENT_LENGTH']
                content = environ['wsgi.input'].read(int(length))
            except KeyError, exc:
                raise HTTP400('Invalid post, unable to read content: %s' % exc)
            posted_data = parse_qs(content, keep_blank_values=True)
            try:
                _update_tiddlyweb_query(environ, posted_data)
            except UnicodeDecodeError, exc:
                raise HTTP400(
                    'Invalid encoding in query string, utf-8 required: %s',
                    exc)
        filters, leftovers = parse_for_filters(environ.get('QUERY_STRING', ''),
                                               environ)
        query_data = parse_qs(leftovers, keep_blank_values=True)
        try:
            _update_tiddlyweb_query(environ, query_data)
        except UnicodeDecodeError, exc:
            raise HTTP400(
                'Invalid encoding in query string, utf-8 required: %s', exc)
        environ['tiddlyweb.filters'] = filters


def _update_tiddlyweb_query(environ, data):
    environ['tiddlyweb.query'].update(
        dict([(unicode(key,
                       'UTF-8'), [unicode(value, 'UTF-8') for value in values])
              for key, values in data.items()]))
示例#25
0
    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']
            logging.debug('simple_cookie looking at cookie string: %s',
                          user_cookie)
            cookie = Cookie.SimpleCookie()
            cookie.load(user_cookie)
            cookie_value = cookie['tiddlyweb_user'].value
            secret = environ['tiddlyweb.config']['secret']
            usersign, cookie_secret = cookie_value.rsplit(':', 1)
            store = environ['tiddlyweb.store']

            if cookie_secret == sha('%s%s' % (usersign, secret)).hexdigest():
                user = User(usersign)
                try:
                    user = store.get(user)
                except (StoreMethodNotImplemented, NoUserError):
                    pass

                #check that the user has the requisite bags
                #if they don't, create them
                public_bag = '%s_public' % user.usersign
                private_bag = '%s_private' % user.usersign
                space = {
                    'bags': {
                        public_bag: {
                            'policy': {
                                "read": [],
                                "create": [user.usersign],
                                "manage": [user.usersign, "R:ADMIN"],
                                "accept": [],
                                "write": [user.usersign],
                                "owner": user.usersign,
                                "delete": [user.usersign, "R:ADMIN"]
                            }
                        },
                        private_bag: {
                            'policy': {
                                "read": [user.usersign],
                                "create": [user.usersign],
                                "manage": [user.usersign, "R:ADMIN"],
                                "accept": [],
                                "write": [user.usersign],
                                "owner": user.usersign,
                                "delete": [user.usersign]
                            }
                        }
                    },
                    'recipes': {
                        '%s' % user.usersign: {
                            'recipe': [['system', ''], [public_bag, ''],
                                       [private_bag, '']],
                            'policy': {
                                "read": [user.usersign],
                                "create": [user.usersign],
                                "manage": [user.usersign, "R:ADMIN"],
                                "accept": [],
                                "write": [user.usersign],
                                "owner": user.usersign,
                                "delete": [user.usersign]
                            }
                        }
                    }
                }
                user_space = Space(environ)
                user_space.create_space(space)

                return {"name": user.usersign, "roles": user.list_roles()}
        except Cookie.CookieError, exc:
            raise HTTP400('malformed cookie: %s' % exc)
示例#26
0
        raise HTTP400('Content-type header required')

    try:
        serializer = Serializer(serialize_type, environ)
        serializer.object = recipe
        content = environ['wsgi.input'].read(int(length))
        serializer.from_string(content.decode('utf-8'))

        recipe.policy.owner = usersign['name']

        _validate_recipe(environ, recipe)
        store.put(recipe)
    except RecipeFormatError, exc:
        raise HTTP400('unable to put recipe: %s' % exc)
    except TypeError, exc:
        raise HTTP400('malformed input: %s' % exc)
    except NoSerializationError:
        raise HTTP415('Content type %s not supported' % serialize_type)

    start_response("204 No Content",
                   [('Location', web.recipe_url(environ, recipe))])

    return []


def _validate_recipe(environ, recipe):
    """
    Unless recipe is valid raise a 409 with the reason why.
    """
    try:
        validate_recipe(recipe, environ)
示例#27
0
        content = environ['wsgi.input'].read(int(length))

        try:
            try:
                # XXX HACK! We don't want to decode content unless
                # the serializer has a as_tiddler. We should be able
                # to just rely on NoSerializationError, but we need
                # to call the method to do that, and to call the method we
                # need to decode the string...
                serialize_type = web.get_serialize_type(environ)[0]
                serializer = Serializer(serialize_type, environ)
                serializer.object = tiddler
                try:
                    serializer.from_string(content.decode('utf-8'))
                except TiddlerFormatError, exc:
                    raise HTTP400('unable to put tiddler: %s' % exc)
            except NoSerializationError:
                tiddler.type = content_type
                if pseudo_binary(tiddler.type):
                    tiddler.text = content.decode('utf-8')
                else:
                    tiddler.text = content
        except UnicodeDecodeError, exc:
            raise HTTP400('unable to decode tiddler, utf-8 expected: %s', exc)

    try:
        recipe_name = web.get_route_value(environ, 'recipe_name')
        recipe = Recipe(recipe_name)
        try:
            store = environ['tiddlyweb.store']
            recipe = store.get(recipe)
    content = environ['wsgi.input'].read(int(length))

    try:
        user_info = simplejson.loads(content)
    except ValueError, exc:
        raise HTTP400('Invalid JSON, %s' % exc)

    try:
        user = User(target_user)
        try:
            store.get(user)
        except NoUserError:
            raise HTTP404()
        user.set_password(user_info['password'])
    except KeyError, exc:
        raise HTTP400('Missing required data: %s', exc)

    store.put(user)
    start_response('204 No Content',
                   [('Content-Type', 'text/html; charset=UTF-8')])
    return ['Updated %s' % target_user]


def post_user(environ, start_response):
    """
    Create a new user through a JSON POST to /users.
    If the not JSON, return 415. If users exists, return 409.

    The JSON should be a dict with two keys: 'username'
    and 'password'. Future iterations of this code
    will take additional keys and save them as fields
示例#29
0
                form.list.append(cgi.MiniFieldStorage(key, single_value))
    # Ordering is important here. File will often appear true when
    # it is not.
    if 'uri' in form and form['uri'].value:
        try:
            uri = form.getfirst('uri')
            request = urllib2.Request(uri)
            if (request.get_type() != 'file'):
                filehandle = urllib2.urlopen(uri)
                type = filehandle.info()['content-type']
            else:
                raise ValueError('file: not allowed')
        except (ValueError, AttributeError, urllib2.URLError), exc:
            raise HTTP400('URI Input error: %s' % exc)
    elif 'file' in form and form['file'].file:
        try:
            filehandle = form['file'].file
            type = form['file'].type
            # XXX: this might have charset in it
            #options = form['file'].type_options
        except (AttributeError, ValueError), exc:
            raise HTTP400('File Input error: %s' % exc)
    else:
        raise HTTP400('Incomplete form')

    start_response('200 OK', [('Content-Type', type)])
    # XXX If reading the file causes an exception
    # it will be trapped as a 500 by HTTPExceptor.
    # Better handling may be desired.
    return filehandle
示例#30
0
文件: bag.py 项目: funkyeah/tiddlyweb
    try:
        serialize_type = web.get_serialize_type(environ)[0]
        serializer = Serializer(serialize_type, environ)
        serializer.object = bag
        content = environ['wsgi.input'].read(int(length))
        serializer.from_string(content.decode('utf-8'))

        bag.policy.owner = usersign['name']

        _validate_bag(environ, bag)
        store.put(bag)
    except BagFormatError, exc:
        raise HTTP400('unable to put bag: %s' % exc)
    except TypeError:
        raise HTTP400('Content-type header required')
    except NoSerializationError:
        raise HTTP415('Content type not supported: %s' % serialize_type)

    start_response("204 No Content",
            [('Location', web.bag_url(environ, bag))])

    return []


def _validate_bag(environ, bag):
    """
    Unless bag is valid raise a 409 with the reason why.
    """
    try:
        validate_bag(bag, environ)