Ejemplo n.º 1
0
def _validate_subscription(environ, name, recipe):
    """
    Determine if this space can be subscribed to.

    We know that the space exists, what we want to determine here is if
    it has been blacklisted or already been subscribed.
    """
    space = Space(name)
    if name in environ['tiddlyweb.config'].get('blacklisted_spaces', []):
        raise HTTP409('Subscription not allowed to space: %s' % name)
    elif [space.public_bag(), ''] in recipe:
        raise HTTP409('Space already subscribed: %s' % name)
    return space
Ejemplo n.º 2
0
def add_space_member(environ, start_response):
    """
    Add a member to a space if they are not already a member.
    If they are already a member, nothing happens. If the username
    given does not exist, raise 409. If the space does not exist
    raise 404.
    """
    store = environ['tiddlyweb.store']
    space_name = get_route_value(environ, 'space_name')
    user_name = get_route_value(environ, 'user_name')
    current_user = environ['tiddlyweb.usersign']

    _same_space_required(environ, space_name)

    try:
        change_space_member(store,
                            space_name,
                            add=user_name,
                            current_user=current_user)
    except (NoBagError, NoRecipeError):
        raise HTTP404('space %s does not exist' % space_name)
    except NoUserError:
        raise HTTP409('attempt to add non-existent user: %s' % user_name)

    start_response('204 No Content', [])
    return ['']
Ejemplo n.º 3
0
def _do_unsubscriptions(space_name, unsubscriptions, public_recipe_list,
                        private_recipe_list):
    """
    Remove unsubscriptions from the space represented by
    public_recipe_list and private_recipe_list.
    """
    for space in unsubscriptions:
        if space == space_name:
            raise HTTP409('Attempt to unsubscribe self')
        try:
            unsubscribed_space = Space(space)
            bag = unsubscribed_space.public_bag()
            public_recipe_list.remove([bag, ""])
            private_recipe_list.remove([bag, ""])
        except ValueError, exc:
            raise HTTP409('Invalid content for unsubscription: %s' % exc)
Ejemplo n.º 4
0
def delete_space_member(environ, start_response):
    """
    Remove a member from a space. If the space does not exist
    raise 404. If the named member is not in the space, do
    nothing.
    """
    store = environ['tiddlyweb.store']
    space_name = get_route_value(environ, 'space_name')
    user_name = get_route_value(environ, 'user_name')
    current_user = environ['tiddlyweb.usersign']

    _same_space_required(environ, space_name)

    try:
        change_space_member(store,
                            space_name,
                            remove=user_name,
                            current_user=current_user)
    except (NoBagError, NoRecipeError):
        raise HTTP404('space %s does not exist' % space_name)
    except NoUserError:
        raise HTTP409('attempt to remove non-member user: %s' % user_name)

    start_response('204 No Content', [])
    return ['']
Ejemplo n.º 5
0
def _validate_bag(environ, bag):
    """
    Unless bag is valid raise a `409` with the reason why.
    """
    try:
        validate_bag(bag, environ)
    except InvalidBagError as exc:
        raise HTTP409('Bag content is invalid: %s' % exc)
Ejemplo n.º 6
0
def _validate_recipe(environ, recipe):
    """
    Unless recipe is valid raise a ``409`` with the reason why.
    """
    try:
        validate_recipe(recipe, environ)
    except InvalidBagError as exc:
        raise HTTP409('Recipe content is invalid: %s' % exc)
Ejemplo n.º 7
0
def _validate_tiddler_content(environ, tiddler):
    """
    Unless tiddler is valid raise a 409 with the reason why
    things to check are presumably tags and title, but we don't
    want to worry about that here, we want to dispatch elsewhere.
    """
    try:
        validate_tiddler(tiddler, environ)
    except InvalidTiddlerError as exc:
        raise HTTP409('Tiddler content is invalid: %s' % exc)
Ejemplo n.º 8
0
def _validate_space_name(environ, name):
    """
    Determine if space name can be used.
    We've already checked if the space exists.
    """
    store = environ['tiddlyweb.store']
    try:
        space = Space(name)
    except ValueError, exc:
        raise HTTP409(exc)
Ejemplo n.º 9
0
def _put_tiddler(environ, start_response, tiddler):
    """
    The guts of putting a tiddler into the store.

    There's a fair bit of special handling done here
    depending on whether the tiddler already exists or
    not.
    """
    store = environ['tiddlyweb.store']

    try:
        bag = Bag(tiddler.bag)
        _check_and_validate_tiddler(environ, bag, tiddler)

        user = environ['tiddlyweb.usersign']['name']
        tiddler.modifier = user
        tiddler.modified = current_timestring()

        try:
            check_bag_constraint(environ, bag, 'accept')
        except (PermissionsError):
            _validate_tiddler_content(environ, tiddler)

        store.put(tiddler)
    except NoBagError as exc:
        raise HTTP409("Unable to put tiddler, %s. There is no bag named: "
                "%s (%s). Create the bag." %
                (tiddler.title, tiddler.bag, exc))
    except NoTiddlerError as exc:
        raise HTTP404('Unable to put tiddler, %s. %s' % (tiddler.title, exc))
    except TypeError as exc:
        raise HTTP409('Unable to put badly formed tiddler, %s:%s. %s'
                % (tiddler.bag, tiddler.title, exc))

    etag = ('ETag', tiddler_etag(environ, tiddler))
    response = [('Location', tiddler_url(environ, tiddler))]
    if etag:
        response.append(etag)
    start_response("204 No Content", response)

    return []
Ejemplo n.º 10
0
def _get_subscription_info(environ):
    """
    Extract subscription info from the JSON posted to a space.
    """
    try:
        length = environ['CONTENT_LENGTH']
        content = environ['wsgi.input'].read(int(length))
        info = simplejson.loads(content)
        subscriptions = info.get('subscriptions', [])
        unsubscriptions = info.get('unsubscriptions', [])
    except (JSONDecodeError, KeyError), exc:
        raise HTTP409('Invalid content for subscription: %s' % exc)
Ejemplo n.º 11
0
def _do_subscriptions(environ, subscriptions, public_recipe_list,
                      private_recipe_list, store):
    """
    Add subscriptions to the space represented by public_recipe_list
    and private_recipe_list.
    """
    for space in subscriptions:
        try:
            subscribed_space = _validate_subscription(environ, space,
                                                      private_recipe_list)
        except ValueError, exc:
            raise HTTP409('Invalid space name: %s' % exc)
        try:
            subscribed_recipe = store.get(
                Recipe(subscribed_space.public_recipe()))
            for bag, filter_string in subscribed_recipe.get_recipe()[2:]:
                if [bag, filter_string] not in public_recipe_list:
                    public_recipe_list.insert(-1, (bag, filter_string))
                if [bag, filter_string] not in private_recipe_list:
                    private_recipe_list.insert(-2, (bag, filter_string))
        except NoRecipeError, exc:
            raise HTTP409('Invalid content for subscription: %s' % exc)
Ejemplo n.º 12
0
def subscribe_space(environ, start_response):
    """
    Subscribe and/or unsubscribe the spaces named in the JSON
    content of the request to the space named in the URI. The current
    user must be a member of the space. Raise 409 if the
    JSON is no good. Raise 404 if the space does not exist.
    Raise 409 if a space in the JSON does not exist.
    """
    store = environ['tiddlyweb.store']
    space_name = get_route_value(environ, 'space_name')
    current_user = environ['tiddlyweb.usersign']
    try:
        current_space = Space(space_name)
    except ValueError, exc:
        raise HTTP409('Invalid space name: %s' % exc)
Ejemplo n.º 13
0
def _update_policy(policy, add=None, subtract=None):
    """
    Update the policy adding or subtracting the user named in
    add or subtract.
    """
    for constraint in ('read', 'write', 'create', 'delete', 'manage'):
        constraint_values = getattr(policy, constraint)
        if add and add not in constraint_values:
            if constraint == 'read' and constraint_values == []:
                pass
            else:
                if 'ANY' in constraint_values or 'NONE' in constraint_values:
                    raise HTTP409('Policy contains ANY or NONE.')
                constraint_values.append(add)
        if subtract and subtract in constraint_values:
            constraint_values.remove(subtract)
    return policy
Ejemplo n.º 14
0
def _store_tiddler_revisions(environ, content, tiddler):
    """
    Given JSON revisions in content, store them
    as a revision history to tiddler.
    """
    try:
        json_tiddlers = simplejson.loads(content)
    except ValueError as exc:
        raise HTTP409('unable to handle json: %s' % exc)

    store = environ['tiddlyweb.store']
    serializer = Serializer('json', environ)
    serializer.object = tiddler
    try:
        for json_tiddler in reversed(json_tiddlers):
            json_string = simplejson.dumps(json_tiddler)
            serializer.from_string(json_string)
            store.put(tiddler)
    except NoTiddlerError as exc:
        raise HTTP400('Unable to store tiddler revisions: %s' % exc)
Ejemplo n.º 15
0
def destroy_key(environ, start_response):
    """
    Remove a key.
    """
    config = environ['tiddlyweb.config']
    store = environ['tiddlyweb.store']
    username = environ['tiddlyweb.usersign']['name']
    bag_name = config.get('oauth.tokens_bag', 'oauth_tokens')
    key_name = get_route_value(environ, 'key_name')

    tiddler = Tiddler(key_name, bag_name)
    try:
        tiddler = store.get(tiddler)
    except NoTiddlerError:
        raise HTTP404('key does not exist')

    if tiddler.modifier != username:
        raise HTTP409('owner mismatch')

    store.delete(tiddler)

    start_response('204 No Content', [('Content-Type', 'text/plain')])

    return []
Ejemplo n.º 16
0
def _validate_space_name(environ, name):
    """
    Determine if space name can be used.
    We've already checked if the space exists.
    """
    store = environ['tiddlyweb.store']
    try:
        space = Space(name)
    except ValueError, exc:
        raise HTTP409(exc)
    # This reserved list should/could be built up from multiple
    # sources.
    reserved_space_names = environ['tiddlyweb.config'].get(
        'socialusers.reserved_names', [])
    if name in reserved_space_names:
        raise HTTP409('Invalid space name: %s' % name)
    try:
        store.get(Recipe(space.private_recipe()))
        raise HTTP409('%s already exists as space' % name)
    except NoRecipeError:
        pass


import tiddlywebplugins.socialusers
original_validate_user = tiddlywebplugins.socialusers._validate_user


def _validate_user_name(environ, user_info):
    """
    Override socialusers _validate_user.
    """