コード例 #1
0
ファイル: wsgi.py プロジェクト: funkyeah/tiddlyweb
class PermissionsExceptor(object):
    """
    Trap permissions exceptions and turn them into HTTP
    exceptions so the errors are propagated to client
    code.
    """

    def __init__(self, application):
        self.application = application

    def __call__(self, environ, start_response):
        try:
            output = self.application(environ, start_response)
            return output
        except ForbiddenError, exc:
            raise HTTP403(exc)
        except UserRequiredError, exc:
            # We only send to the challenger on a GET
            # request. Otherwise we're in for major confusion
            # on dealing with redirects and the like in
            # scripts and javascript, where follow
            # behavior is inconsistent.
            if environ['REQUEST_METHOD'] == 'GET':
                url = _challenge_url(environ)
                raise HTTP302(url)
            raise HTTP403(exc)
コード例 #2
0
def list_collection(environ, start_response):
    """
    WSGI application handling PROPFIND requests
    """
    if environ.get("HTTP_DEPTH", "0") not in ("0", "1"):
        raise HTTP403("excessive depth requested")

    doc = {
        "multistatus": {
            "@xmlns":
            "DAV:",
            "response": (multistatus_response(entry)
                         for entry in determine_entries(environ))
        }
    }
    doc = """<?xml version="1.0" encoding="utf-8" ?>\n%s""" % dict2xml(doc)

    # XXX: DEBUG
    from .util import prettify
    print "%s\n%s\n%s" % ("=" * 80, prettify(doc, "application/xml"), "-" * 80)

    headers = merge(
        {},
        DEFAULT_HEADERS,
        {
            "Content-Type": "application/xml",  # XXX: charset?
            "Content-Length": "%s" % len(doc)
        })
    start_response("207 Multi-Status", headers.items())
    return doc
コード例 #3
0
ファイル: handler.py プロジェクト: dahukanna/tiddlyspace
def get_identities(environ, start_response):
    """
    Get a list of the identities associated with the named user.
    That named user must match the current user or the current
    user must be an admin.
    """
    store = environ['tiddlyweb.store']
    username = environ['wsgiorg.routing_args'][1]['username']
    usersign = environ['tiddlyweb.usersign']['name']
    roles = environ['tiddlyweb.usersign']['roles']

    if username != usersign and 'ADMIN' not in roles:
        raise HTTP403('Bad user for action')

    identities = []
    try:
        mapped_bag = store.get(Bag('MAPUSER'))
        tiddlers = store.list_bag_tiddlers(mapped_bag)
        matched_tiddlers = control.filter_tiddlers(
            tiddlers, 'select=mapped_user:%s' % username, environ)
        identities = [tiddler.title for tiddler in matched_tiddlers]
    except NoBagError:
        pass

    start_response('200 OK',
                   [('Content-Type', 'application/json; charset=UTF-8')])
    return [simplejson.dumps(identities)]
コード例 #4
0
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)
コード例 #5
0
ファイル: safemode.py プロジェクト: sethnz/tiddlyspace
def safe_mode(environ, start_response):
    """
    Serve up a space in safe mode. Safe mode means that
    non-required plugins are turned off and plugins that
    duplicate those in the core bags (system and tiddlyspace)
    are deleted from the store of the space in question.
    """

    http_host, _ = determine_host(environ)
    space_name = determine_space(environ, http_host)
    recipe_name = determine_space_recipe(environ, space_name)
    if recipe_name != '%s_private' % space_name:
        raise HTTP403('membership required for safe mode')

    if environ['REQUEST_METHOD'] == 'GET':
        return _send_safe_mode(environ, start_response)

    store = environ['tiddlyweb.store']

    # Get the list of core plugins
    core_plugin_tiddler_titles = _get_core_plugins(store)

    # Delete those plugins in the space's recipes which
    # duplicate the core plugins
    recipe = _delete_duplicates(environ, core_plugin_tiddler_titles,
                                recipe_name, space_name)

    # Process the recipe. For those tiddlers which do not have a bag
    # in CORE_RECIPE, remove the systemConfig tag.
    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))
コード例 #6
0
def _same_space_required(environ, space_name):
    """
    Raise 403 unless the current space (http_host) is the same as the
    target space.
    """
    current_space = determine_space(environ, determine_host(environ)[0])
    if current_space != space_name:
        raise HTTP403('space membership changes only allowed from space')
コード例 #7
0
                        remove=None,
                        current_user=None):
    """
    The guts of adding a member to space.
    """
    try:
        space = Space(space_name)
    except ValueError, exc:
        raise HTTP404('Space %s invalid: %s' % (space_name, exc))
    private_bag = store.get(Bag(space.private_bag()))

    if current_user:
        private_bag.policy.allows(current_user, 'manage')

    if remove and len(private_bag.policy.manage) == 1:
        raise HTTP403('must not remove the last member from a space')

    # This will throw NoUserError (to be handled by the caller)
    # if the user does not exist.
    if add:
        store.get(User(add))

    bags = [store.get(Bag(bag)) for bag in space.list_bags()]
    recipes = [store.get(Recipe(bag)) for bag in space.list_recipes()]
    for entity in bags + recipes:
        new_policy = _update_policy(entity.policy, add=add, subtract=remove)
        entity.policy = new_policy
        store.put(entity)


def confirm_space(environ, start_response):
コード例 #8
0
ファイル: wsgi.py プロジェクト: funkyeah/tiddlyweb
 def __call__(self, environ, start_response):
     try:
         output = self.application(environ, start_response)
         return output
     except ForbiddenError, exc:
         raise HTTP403(exc)