Ejemplo n.º 1
0
def get_user_has_permission(request):
    discussion_id = int(request.matchdict['discussion_id'])
    permission = request.matchdict['permission']
    discussion = Discussion.get_instance(discussion_id)
    if not discussion:
        raise HTTPNotFound("Discussion %d does not exist" % (discussion_id,))
    return a_users_with_permission(discussion_id, permission)
Ejemplo n.º 2
0
def save_synthesis(request):
    synthesis_id = request.matchdict['id']
    discussion_id = int(request.matchdict['discussion_id'])
    if synthesis_id == 'next_synthesis':
        discussion = Discussion.get_instance(discussion_id)
        synthesis = discussion.get_next_synthesis()
    else:
        synthesis = Synthesis.get_instance(synthesis_id)
    if not synthesis:
        raise HTTPBadRequest("Synthesis with id '%s' not found." %
                             synthesis_id)

    synthesis_data = json.loads(request.body)
    user_id = request.authenticated_userid
    permissions = get_permissions(user_id, discussion_id)

    for key in ('subject', 'introduction', 'conclusion'):
        if key in synthesis_data:
            ls_data = synthesis_data[key]
            if ls_data is None:
                continue
            assert isinstance(ls_data, dict)
            current = LangString.create_from_json(ls_data,
                                                  user_id,
                                                  permissions=permissions)
            setattr(synthesis, key, current)

    Synthesis.default_db.add(synthesis)
    Synthesis.default_db.flush()

    return {'ok': True, 'id': synthesis.uri()}
Ejemplo n.º 3
0
def discussion_from_request(request):
    from ..models import Discussion
    from assembl.views.traversal import TraversalContext
    if request.matchdict:
        if 'discussion_id' in request.matchdict:
            discussion_id = int(request.matchdict['discussion_id'])
            discussion = Discussion.get_instance(discussion_id)
            if not discussion:
                raise HTTPNotFound("No discussion ID %d" % (discussion_id, ))
            return discussion
        elif 'discussion_slug' in request.matchdict:
            slug = request.matchdict['discussion_slug']
            discussion = find_discussion_from_slug(slug)
            if not discussion:
                raise HTTPNotFound("No discussion found for slug=%s" %
                                   (slug, ))
            return discussion
    if getattr(request, "context", None) and isinstance(
            request.context, TraversalContext):
        discussion_id = request.context.get_discussion_id()
        if discussion_id:
            return Discussion.get(discussion_id)
    if request.session.get("discussion", None):
        slug = request.session["discussion"]
        discussion = find_discussion_from_slug(slug)
        if not discussion:
            raise HTTPNotFound("No discussion found for slug=%s" % (slug, ))
        return discussion
Ejemplo n.º 4
0
def put_discussion_roles_for_user(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    if not discussion:
        raise HTTPNotFound("Discussion %d does not exist" % (discussion_id, ))
    user_id = request.matchdict['user_id']
    user = User.get_instance(user_id)
    if not user:
        raise HTTPNotFound("User id %d does not exist" % (user_id, ))
    try:
        data = json.loads(request.body)
    except Exception as e:
        raise HTTPBadRequest("Malformed Json")
    session = Discussion.default_db
    if not isinstance(data, list):
        raise HTTPBadRequest("Not a list")
    if data and frozenset((type(x) for x in data)) != frozenset((str, )):
        raise HTTPBadRequest("not strings")
    roles = set(session.query(Role).filter(Role.name.in_(data)).all())
    data = set(data)
    if len(roles) != len(data):
        raise HTTPBadRequest("Not valid roles: %s" %
                             (repr(data - set((p.name for p in roles))), ))
    known_lu_roles = session.query(LocalUserRole).join(Role).filter(
        user=user, discussion=discussion).all()
    lur_by_role = {lur.role.name: lur for lur in known_lu_roles}
    known_roles = set(lur_by_role.keys())
    for role in known_roles - roles:
        session.query.delete(lur_by_role[role])
    for role in roles - known_roles:
        session.add(LocalUserRole(user=user, role=role, discussion=discussion))
    return {
        "added": list(roles - known_roles),
        "removed": list(known_roles - roles)
    }
Ejemplo n.º 5
0
def test_simultaneous_ajax_calls(request):
    g = lambda x: request.GET.get(x, None)

    session = User.default_db

    discussion_id = g('discussion_id')
    widget_id = g('widget_id')
    if not discussion_id:
        return HTTPBadRequest(
            explanation="Please provide a discussion_id parameter")
    if not widget_id:
        return HTTPBadRequest(
            explanation="Please provide a widget_id parameter")

    widget_id = int(widget_id)
    discussion_id = int(discussion_id)
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound("Discussion with id '%d' not found." %
                           (discussion_id, ))

    user_id = authenticated_userid(request)
    assert user_id

    context = dict(get_default_context(request),
                   discussion=discussion,
                   discussion_id=discussion_id,
                   widget_id=widget_id)

    return render_to_response('admin/test_simultaneous_ajax_calls.jinja2',
                              context,
                              request=request)
Ejemplo n.º 6
0
def get_user_has_permission(request):
    discussion_id = int(request.matchdict['discussion_id'])
    permission = request.matchdict['permission']
    discussion = Discussion.get_instance(discussion_id)
    if not discussion:
        raise HTTPNotFound("Discussion %d does not exist" % (discussion_id, ))
    return a_users_with_permission(discussion_id, permission)
Ejemplo n.º 7
0
def discussion_edit(request):
    discussion_id = int(request.matchdict["discussion_id"])
    discussion = Discussion.get_instance(discussion_id)
    user_id = authenticated_userid(request)
    assert user_id
    permissions = get_permissions(user_id, discussion_id)
    partners = json.dumps(
        [p.generic_json(user_id=user_id, permissions=permissions) for p in discussion.partner_organizations]
    )

    if not discussion:
        raise HTTPNotFound("Discussion with id '%d' not found." % (discussion_id,))

    context = dict(
        get_default_context(request),
        discussion=discussion,
        admin_discussion_permissions_url=request.route_url("discussion_permissions", discussion_id=discussion.id),
        partners=partners,
    )

    if request.method == "POST":

        g = lambda x: request.POST.get(x, None)

        (topic, slug, objectives) = (g("topic"), g("slug"), g("objectives"))

        discussion.topic = topic
        discussion.slug = slug
        discussion.objectives = objectives

    return render_to_response("admin/discussion_edit.jinja2", context, request=request)
Ejemplo n.º 8
0
def put_discussion_roles_for_user(request):
    discussion_id = request.matchdict['discussion_id']
    user_id = request.matchdict['user_id']
    discussion = Discussion.get_instance(discussion_id)
    if not discussion:
        raise HTTPNotFound("Discussion %s does not exist" % (discussion_id,))
    user = User.get_instance(user_id)
    if not user:
        raise HTTPNotFound("User id %s does not exist" % (user_id,))
    try:
        data = json.loads(request.body)
    except Exception as e:
        raise HTTPBadRequest("Malformed Json")
    session = Discussion.db()
    if not isinstance(data, list):
        raise HTTPBadRequest("Not a list")
    if data and frozenset((type(x) for x in data)) != frozenset((str,)):
        raise HTTPBadRequest("not strings")
    roles = set(session.query(Role).filter(name in data).all())
    data = set(data)
    if len(roles) != len(data):
        raise HTTPBadRequest("Not valid roles: %s" % (repr(
            data - set((p.name for p in roles))),))
    known_lu_roles = session.query(LocalUserRole).join(Role).filter(
        user=user, discussion=discussion).all()
    lur_by_role = {lur.role.name: lur for lur in known_lu_roles}
    known_roles = set(lur_by_role.keys())
    for role in known_roles - roles:
        session.query.delete(lur_by_role(role))
    for role in roles - known_roles:
        session.add(LocalUserRole(
            user=user, role=role, discussion=discussion))
    return {"added": list(roles - known_roles),
            "removed": list(known_roles - roles)}
Ejemplo n.º 9
0
def test_simultaneous_ajax_calls(request):
    g = lambda x: request.GET.get(x, None)

    session = User.default_db

    discussion_id = g('discussion_id')
    widget_id = g('widget_id')
    if not discussion_id:
        return HTTPBadRequest(
            explanation="Please provide a discussion_id parameter")
    if not widget_id:
        return HTTPBadRequest(
            explanation="Please provide a widget_id parameter")

    widget_id = int(widget_id)
    discussion_id = int(discussion_id)
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound("Discussion with id '%d' not found." % (
            discussion_id,))

    user_id = authenticated_userid(request)
    assert user_id

    context = dict(
        get_default_context(request),
        discussion=discussion,
        discussion_id=discussion_id,
        widget_id=widget_id)

    return render_to_response(
        'admin/test_simultaneous_ajax_calls.jinja2',
        context,
        request=request)
Ejemplo n.º 10
0
def save_synthesis(request):
    synthesis_id = request.matchdict['id']
    discussion_id = int(request.matchdict['discussion_id'])
    if synthesis_id == 'next_synthesis':
        discussion = Discussion.get_instance(discussion_id)
        synthesis = discussion.get_next_synthesis()
    else:
        synthesis = Synthesis.get_instance(synthesis_id)
    if not synthesis:
        raise HTTPBadRequest("Synthesis with id '%s' not found." % synthesis_id)

    synthesis_data = json.loads(request.body)
    user_id = request.authenticated_userid
    permissions = get_permissions(user_id, discussion_id)

    for key in ('subject', 'introduction', 'conclusion'):
        if key in synthesis_data:
            ls_data = synthesis_data[key]
            if ls_data is None:
                continue
            assert isinstance(ls_data, dict)
            current = LangString.create_from_json(
                ls_data, user_id, permissions=permissions)
            setattr(synthesis, key, current)

    Synthesis.default_db.add(synthesis)
    Synthesis.default_db.flush()

    return {'ok': True, 'id': synthesis.uri()}
Ejemplo n.º 11
0
def delete_discussion(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound(
            "Discussion with id '%s' not found." % discussion_id)

    discussion.delete()
    return HTTPNoContent()
Ejemplo n.º 12
0
def delete_discussion(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound("Discussion with id '%s' not found." %
                           discussion_id)

    discussion.delete()
    return HTTPNoContent()
Ejemplo n.º 13
0
def get_permissions_for_user(request):
    discussion_id = request.matchdict['discussion_id']
    user_id = request.matchdict['user_id']
    discussion = Discussion.get_instance(discussion_id)
    if not discussion:
        raise HTTPNotFound("Discussion %s does not exist" % (discussion_id,))
    if user_id not in (Authenticated, Everyone):
        user = User.get_instance(user_id)
        if not user:
            raise HTTPNotFound("User id %s does not exist" % (user_id,))
    return a_permissions_for_user(discussion_id, user_id)
Ejemplo n.º 14
0
def get_permissions_for_user(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    if not discussion:
        raise HTTPNotFound("Discussion %d does not exist" % (discussion_id, ))
    user_id = request.matchdict['user_id']
    if user_id not in (Authenticated, Everyone):
        user = User.get_instance(user_id)
        if not user:
            raise HTTPNotFound("User id %s does not exist" % (user_id, ))
        user_id = user.id
    return get_permissions(user_id, discussion_id)
Ejemplo n.º 15
0
def get_discussion(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    view_def = request.GET.get('view') or 'default'
    user_id = authenticated_userid(request) or Everyone
    permissions = get_permissions(user_id, discussion_id)

    if not discussion:
        raise HTTPNotFound(
            "Discussion with id '%s' not found." % discussion_id)

    return discussion.generic_json(view_def, user_id, permissions)
Ejemplo n.º 16
0
def get_discussion(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    view_def = request.GET.get('view') or 'default'
    user_id = authenticated_userid(request)
    permissions = get_permissions(user_id, discussion_id)

    if not discussion:
        raise HTTPNotFound(
            "Discussion with id '%s' not found." % discussion_id)

    return discussion.generic_json(view_def, user_id, permissions)
Ejemplo n.º 17
0
def get_user_has_permission(request):
    discussion_id = int(request.matchdict['discussion_id'])
    user_id = request.matchdict['user_id']
    permission = request.matchdict['permission']
    discussion = Discussion.get_instance(discussion_id)
    if not discussion:
        raise HTTPNotFound("Discussion %d does not exist" % (discussion_id,))
    if user_id not in (Authenticated, Everyone):
        user = User.get_instance(user_id)
        if not user:
            raise HTTPNotFound("User id %s does not exist" % (user_id,))
        user_id = user.id
    return a_user_has_permission(discussion_id, user_id, permission)
Ejemplo n.º 18
0
def get_discussion(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    is_etalab_request = request.matched_route.name == 'etalab_discussion'
    view_def = request.GET.get(
        'view', 'etalab' if is_etalab_request else 'default')
    user_id = request.authenticated_userid or Everyone
    permissions = get_permissions(user_id, discussion_id)

    if not discussion:
        raise HTTPNotFound(
            "Discussion with id '%s' not found." % discussion_id)

    return discussion.generic_json(view_def, user_id, permissions)
Ejemplo n.º 19
0
def get_discussion(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    is_etalab_request = request.matched_route.name == 'etalab_discussion'
    view_def = request.GET.get('view',
                               'etalab' if is_etalab_request else 'default')
    user_id = request.authenticated_userid or Everyone
    permissions = get_permissions(user_id, discussion_id)

    if not discussion:
        raise HTTPNotFound("Discussion with id '%s' not found." %
                           discussion_id)

    return discussion.generic_json(view_def, user_id, permissions)
Ejemplo n.º 20
0
def post_discussion(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound("Discussion with id '%s' not found." %
                           discussion_id)

    discussion_data = json.loads(request.body)

    discussion.topic = discussion_data.get('topic', discussion.slug)
    discussion.slug = discussion_data.get('slug', discussion.slug)
    discussion.objectives = discussion_data.get('objectives',
                                                discussion.objectives)

    return {'ok': True}
Ejemplo n.º 21
0
def get_sources(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    view_def = request.GET.get('view') or 'default'

    if not discussion:
        raise HTTPNotFound(
            "Discussion with id '%s' not found." % discussion_id
        )

    user_id = authenticated_userid(request)
    permissions = get_permissions(user_id, discussion_id)

    res = [source.generic_json(view_def, user_id, permissions)
           for source in discussion.sources]
    return [x for x in res if x is not None]
Ejemplo n.º 22
0
def get_sources(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    view_def = request.GET.get('view') or 'default'

    if not discussion:
        raise HTTPNotFound(
            "Discussion with id '%s' not found." % discussion_id
        )

    user_id = request.authenticated_userid or Everyone
    permissions = get_permissions(user_id, discussion_id)

    res = [source.generic_json(view_def, user_id, permissions)
           for source in discussion.sources]
    return [x for x in res if x is not None]
Ejemplo n.º 23
0
def post_discussion(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound(
            "Discussion with id '%s' not found." % discussion_id)

    discussion_data = json.loads(request.body)

    discussion.topic = discussion_data.get('topic', discussion.slug)
    discussion.slug = discussion_data.get('slug', discussion.slug)
    discussion.objectives = discussion_data.get(
        'objectives', discussion.objectives)

    return {'ok': True}
Ejemplo n.º 24
0
def get_synthesis(request):
    synthesis_id = request.matchdict['id']
    if synthesis_id == 'next_synthesis':
        discussion_id = int(request.matchdict['discussion_id'])
        discussion = Discussion.get_instance(discussion_id)
        synthesis = discussion.get_next_synthesis()
    else:
        synthesis = Synthesis.get_instance(synthesis_id)
    if not synthesis:
        raise HTTPNotFound("Synthesis with id '%s' not found." % synthesis_id)

    view_def = request.GET.get('view') or 'default'
    discussion_id = int(request.matchdict['discussion_id'])
    user_id = authenticated_userid(request) or Everyone
    permissions = get_permissions(user_id, discussion_id)

    return synthesis.generic_json(view_def, user_id, permissions)
Ejemplo n.º 25
0
def get_synthesis(request):
    synthesis_id = request.matchdict['id']
    if synthesis_id == 'next_synthesis':
        discussion_id = int(request.matchdict['discussion_id'])
        discussion = Discussion.get_instance(discussion_id)
        synthesis = discussion.get_next_synthesis()
    else:
        synthesis = Synthesis.get_instance(synthesis_id)
    if not synthesis:
        raise HTTPNotFound("Synthesis with id '%s' not found." % synthesis_id)

    view_def = request.GET.get('view') or 'default'
    discussion_id = int(request.matchdict['discussion_id'])
    user_id = authenticated_userid(request) or Everyone
    permissions = get_permissions(user_id, discussion_id)

    return synthesis.generic_json(view_def, user_id, permissions)
Ejemplo n.º 26
0
def mark_post_read(request):
    """Mark this post as un/read. Return the read post count for all affected ideas."""
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    post_id = request.matchdict['id']
    post = Post.get_instance(post_id)
    if not post:
        raise HTTPNotFound("Post with id '%s' not found." % post_id)
    post_id = post.id
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized()
    read_data = json.loads(request.body)
    db = discussion.db
    change = False
    with transaction.manager:
        if read_data.get('read', None) is False:
            view = db.query(ViewPost).filter_by(post_id=post_id,
                                                actor_id=user_id,
                                                tombstone_date=None).first()
            if view:
                change = True
                view.is_tombstone = True
        else:
            count = db.query(ViewPost).filter_by(post_id=post_id,
                                                 actor_id=user_id,
                                                 tombstone_date=None).count()
            if not count:
                change = True
                db.add(ViewPost(post=post, actor_id=user_id))

    new_counts = []
    if change:
        new_counts = Idea.idea_read_counts(discussion_id, post_id, user_id)

    return {
        "ok":
        True,
        "ideas": [{
            "@id": Idea.uri_generic(idea_id),
            "num_read_posts": read_posts
        } for (idea_id, read_posts) in new_counts]
    }
Ejemplo n.º 27
0
def mark_post_read(request):
    discussion_id = int(request.matchdict["discussion_id"])
    discussion = Discussion.get_instance(discussion_id)
    post_id = request.matchdict["id"]
    post = Post.get_instance(post_id)
    if not post:
        raise HTTPNotFound("Post with id '%s' not found." % post_id)
    post_id = post.id
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized()
    read_data = json.loads(request.body)
    db = Discussion.db()
    change = False
    with transaction.manager:
        if read_data.get("read", None) is False:
            view = db.query(ViewPost).filter(ViewPost.post_id == post_id).filter(Action.actor_id == user_id).first()
            if view:
                change = True
                db.delete(view)
        else:
            count = db.query(ViewPost).filter(ViewPost.post_id == post_id).filter(Action.actor_id == user_id).count()
            if not count:
                change = True
                db.add(ViewPost(post=post, actor_id=user_id))

    new_counts = []
    if change:
        new_counts = Idea.idea_counts(discussion_id, post_id, user_id)

    return {
        "ok": True,
        "ideas": [
            {
                "@id": Idea.uri_generic(idea_id),
                "@type": db.query(Idea).get(idea_id).external_typename(),
                "num_posts": total_posts,
                "num_read_posts": read_posts,
            }
            for (idea_id, total_posts, read_posts) in new_counts
        ],
    }
Ejemplo n.º 28
0
def save_synthesis(request):
    synthesis_id = request.matchdict['id']
    if synthesis_id == 'next_synthesis':
        discussion_id = int(request.matchdict['discussion_id'])
        discussion = Discussion.get_instance(discussion_id)
        synthesis = discussion.get_next_synthesis()
    else:
        synthesis = Synthesis.get_instance(synthesis_id)
    if not synthesis:
        raise HTTPBadRequest("Synthesis with id '%s' not found." % synthesis_id)

    synthesis_data = json.loads(request.body)

    synthesis.subject = synthesis_data.get('subject')
    synthesis.introduction = synthesis_data.get('introduction')
    synthesis.conclusion = synthesis_data.get('conclusion')

    Synthesis.default_db.add(synthesis)
    Synthesis.default_db.flush()

    return {'ok': True, 'id': synthesis.uri()}
Ejemplo n.º 29
0
def save_synthesis(request):
    synthesis_id = request.matchdict['id']
    if synthesis_id == 'next_synthesis':
        discussion_id = int(request.matchdict['discussion_id'])
        discussion = Discussion.get_instance(discussion_id)
        synthesis = discussion.get_next_synthesis()
    else:
        synthesis = Synthesis.get_instance(synthesis_id)
    if not synthesis:
        raise HTTPBadRequest("Synthesis with id '%s' not found." % synthesis_id)

    synthesis_data = json.loads(request.body)

    synthesis.subject = synthesis_data.get('subject')
    synthesis.introduction = synthesis_data.get('introduction')
    synthesis.conclusion = synthesis_data.get('conclusion')

    Synthesis.default_db.add(synthesis)
    Synthesis.default_db.flush()

    return {'ok': True, 'id': synthesis.uri()}
Ejemplo n.º 30
0
def mark_post_read(request):
    """Mark this post as un/read. Return the read post count for all affected ideas."""
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    post_id = request.matchdict['id']
    post = Post.get_instance(post_id)
    if not post:
        raise HTTPNotFound("Post with id '%s' not found." % post_id)
    post_id = post.id
    user_id = request.authenticated_userid
    if not user_id:
        raise HTTPUnauthorized()
    read_data = json.loads(request.body)
    db = discussion.db
    change = False
    with transaction.manager:
        if read_data.get('read', None) is False:
            view = db.query(ViewPost).filter_by(
                post_id=post_id, actor_id=user_id,
                tombstone_date=None).first()
            if view:
                change = True
                view.is_tombstone = True
        else:
            count = db.query(ViewPost).filter_by(
                post_id=post_id, actor_id=user_id,
                tombstone_date=None).count()
            if not count:
                change = True
                db.add(ViewPost(post=post, actor_id=user_id))

    new_counts = []
    if change:
        new_counts = Idea.idea_read_counts(discussion_id, post_id, user_id)

    return { "ok": True, "ideas": [
        {"@id": Idea.uri_generic(idea_id),
         "num_read_posts": read_posts
        } for (idea_id, read_posts) in new_counts] }
Ejemplo n.º 31
0
def discussion_edit(request):
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    user_id = authenticated_userid(request)
    assert user_id
    permissions = get_permissions(user_id, discussion_id)
    partners = json.dumps([
        p.generic_json(user_id=user_id, permissions=permissions)
        for p in discussion.partner_organizations
    ])

    if not discussion:
        raise HTTPNotFound("Discussion with id '%d' not found." %
                           (discussion_id, ))

    context = dict(get_default_context(request),
                   discussion=discussion,
                   admin_discussion_permissions_url=request.route_url(
                       'discussion_permissions', discussion_id=discussion.id),
                   partners=partners)

    if request.method == 'POST':

        g = lambda x: request.POST.get(x, None)

        (topic, slug, objectives) = (
            g('topic'),
            g('slug'),
            g('objectives'),
        )

        discussion.topic = topic
        discussion.slug = slug
        discussion.objectives = objectives

    return render_to_response('admin/discussion_edit.jinja2',
                              context,
                              request=request)
Ejemplo n.º 32
0
def discussion_permissions(request):
    user_id = authenticated_userid(request)
    assert user_id
    db = Discussion.default_db
    discussion_id = int(request.matchdict["discussion_id"])
    discussion = Discussion.get_instance(discussion_id)
    error = ""

    if not discussion:
        raise HTTPNotFound("Discussion with id '%d' not found." % (discussion_id,))

    roles = db.query(Role).all()
    roles_by_name = {r.name: r for r in roles}
    role_names = [r.name for r in roles]
    permissions = db.query(Permission).all()
    perms_by_name = {p.name: p for p in permissions}
    permission_names = [p.name for p in permissions]

    disc_perms = db.query(DiscussionPermission).filter_by(discussion_id=discussion_id).join(Role, Permission).all()
    disc_perms_as_set = set((dp.role.name, dp.permission.name) for dp in disc_perms)
    disc_perms_dict = {(dp.role.name, dp.permission.name): dp for dp in disc_perms}
    local_roles = db.query(LocalUserRole).filter_by(discussion_id=discussion_id).join(Role, User).all()
    local_roles_as_set = set((lur.user.id, lur.role.name) for lur in local_roles)
    local_roles_dict = {(lur.user.id, lur.role.name): lur for lur in local_roles}
    users = set(lur.user for lur in local_roles)
    num_users = ""

    if request.POST:
        if "submit_role_permissions" in request.POST:
            for role in role_names:
                if role == R_SYSADMIN:
                    continue
                for permission in permission_names:
                    allowed_text = "allowed_%s_%s" % (role, permission)
                    if (role, permission) not in disc_perms_as_set and allowed_text in request.POST:
                        dp = DiscussionPermission(
                            role=roles_by_name[role], permission=perms_by_name[permission], discussion_id=discussion_id
                        )
                        disc_perms_dict[(role, permission)] = dp
                        disc_perms_as_set.add((role, permission))
                        db.add(dp)
                    elif (role, permission) in disc_perms_as_set and allowed_text not in request.POST:
                        dp = disc_perms_dict[(role, permission)]
                        del disc_perms_dict[(role, permission)]
                        disc_perms_as_set.remove((role, permission))
                        db.delete(dp)
                if not role in SYSTEM_ROLES and "delete_" + role in request.POST:
                    db.delete(roles_by_name[role])
                    del roles_by_name[role]
                    role_names.remove(role)
        elif "submit_add_role" in request.POST:
            # TODO: Sanitize role
            role = Role(name="r:" + request.POST["new_role"])
            roles_by_name[role.name] = role
            role_names.append(role.name)
            db.add(role)
        elif "submit_user_roles" in request.POST:
            user_ids = {u.id for u in users}
            for role in role_names:
                if role == R_SYSADMIN:
                    continue
                prefix = "has_" + role + "_"
                for name in request.POST:
                    if name.startswith(prefix):
                        a_user_id = int(name[len(prefix) :])
                        if a_user_id not in user_ids:
                            users.add(User.get_instance(a_user_id))
                            user_ids.add(a_user_id)
                for user in users:
                    has_role_text = "has_%s_%d" % (role, user.id)
                    if (user.id, role) not in local_roles_as_set and has_role_text in request.POST:
                        lur = LocalUserRole(role=roles_by_name[role], user=user, discussion_id=discussion_id)
                        local_roles.append(lur)
                        local_roles_dict[(user.id, role)] = lur
                        local_roles_as_set.add((user.id, role))
                        db.add(lur)
                    elif (user.id, role) in local_roles_as_set and has_role_text not in request.POST:
                        lur = local_roles_dict[(user.id, role)]
                        del local_roles_dict[(user.id, role)]
                        local_roles_as_set.remove((user.id, role))
                        local_roles.remove(lur)
                        db.delete(lur)

        elif "submit_look_for_user" in request.POST:
            search_string = "%" + request.POST["user_search"] + "%"
            other_users = (
                db.query(User)
                .outerjoin(Username)
                .filter(
                    AgentProfile.name.ilike(search_string)
                    | Username.username.ilike(search_string)
                    | User.preferred_email.ilike(search_string)
                )
                .all()
            )
            users.update(other_users)
        elif "submit_user_file" in request.POST:
            role = request.POST["add_with_role"] or R_PARTICIPANT
            if role == R_SYSADMIN and not user_has_permission(discussion_id, user_id, P_SYSADMIN):
                role = R_ADMINISTRATOR
            if "user_csvfile" in request.POST:
                try:
                    num_users = add_multiple_users_csv(request.POST["user_csvfile"].file, discussion_id, role)
                except Exception as e:
                    error = repr(e)
            else:
                error = request.localizer.translate(_("No file given."))

    def allowed(role, permission):
        if role == R_SYSADMIN:
            return True
        return (role, permission) in disc_perms_as_set

    def has_local_role(user_id, role):
        return (user_id, role) in local_roles_as_set

    context = dict(
        get_default_context(request),
        discussion=discussion,
        allowed=allowed,
        roles=role_names,
        permissions=permission_names,
        users=users,
        error=error,
        num_users=num_users,
        has_local_role=has_local_role,
        is_system_role=lambda r: r in SYSTEM_ROLES,
    )

    return render_to_response("admin/discussion_permissions.jinja2", context, request=request)
Ejemplo n.º 33
0
def create_post(request):
    """
    We use post, not put, because we don't know the id of the post
    """
    localizer = request.localizer
    request_body = json.loads(request.body)
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized()

    user = Post.default_db.query(User).filter_by(id=user_id).one()

    body = request_body.get('body', None)
    html = request_body.get('html', None)  # BG: Is this used now? I cannot see it.
    reply_id = request_body.get('reply_id', None)
    idea_id = request_body.get('idea_id', None)
    subject = request_body.get('subject', None)
    publishes_synthesis_id = request_body.get('publishes_synthesis_id', None)

    if not body and not publishes_synthesis_id:
        # Should we allow empty messages otherwise?
        raise HTTPBadRequest(localizer.translate(
                _("Your message is empty")))

    if reply_id:
        in_reply_to_post = Post.get_instance(reply_id)
    else:
        in_reply_to_post = None

    if idea_id:
        in_reply_to_idea = Idea.get_instance(idea_id)
    else:
        in_reply_to_idea = None

    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound(localizer.translate(_(
            "No discussion found with id=%s")) % (discussion_id,)
        )

    ctx = DummyContext({Discussion: discussion})
    if html:
        log.warning("Still using html")
        # how to guess locale in this case?
        body = LangString.create(html)
    elif body:
        body = LangString.create_from_json(
            body, context=ctx, user_id=user_id)
    else:
        body = LangString.EMPTY(discussion.db)

    if subject:
        subject = LangString.create_from_json(
            subject, context=ctx, user_id=user_id)
    else:
        # print(in_reply_to_post.subject, discussion.topic)
        if in_reply_to_post:
            subject = (in_reply_to_post.get_title().first_original().value
                       if in_reply_to_post.get_title() else '')
        elif in_reply_to_idea:
            # TODO:  THis should use a cascade like the frontend
            subject = (in_reply_to_idea.short_title
                       if in_reply_to_idea.short_title else '')
        else:
            subject = discussion.topic if discussion.topic else ''
        # print subject
        if subject is not None and len(subject):
            new_subject = "Re: " + restrip_pat.sub('', subject).strip()
            if (in_reply_to_post and new_subject == subject and
                    in_reply_to_post.get_title()):
                # reuse subject and translations
                subject = in_reply_to_post.get_title()
            else:
                # how to guess locale in this case?
                subject = LangString.create(new_subject)
        else:
            raven_client = get_raven_client()
            if raven_client:
                raven_client.captureMessage(
                    "A message is about to be written to the database with an "
                    "empty subject.  This is not supposed to happen.")
            subject = LangString.EMPTY(discussion.db)

    post_constructor_args = {
        'discussion': discussion,
        'creator_id': user_id,
        'subject': subject,
        'body': body
        }

    if publishes_synthesis_id:
        published_synthesis = Synthesis.get_instance(publishes_synthesis_id)
        post_constructor_args['publishes_synthesis'] = published_synthesis
        new_post = SynthesisPost(**post_constructor_args)
    else:
        new_post = AssemblPost(**post_constructor_args)

    discussion.db.add(new_post)
    discussion.db.flush()

    if in_reply_to_post:
        new_post.set_parent(in_reply_to_post)
    if in_reply_to_idea:
        idea_post_link = IdeaRelatedPostLink(
            creator_id=user_id,
            content=new_post,
            idea=in_reply_to_idea
        )
        discussion.db.add(idea_post_link)
        idea = in_reply_to_idea
        while idea:
            idea.send_to_changes()
            parents = idea.get_parents()
            idea = next(iter(parents)) if parents else None
    else:
        discussion.root_idea.send_to_changes()
    for source in discussion.sources:
        if 'send_post' in dir(source):
            source.send_post(new_post)
    permissions = get_permissions(user_id, discussion_id)

    return new_post.generic_json('default', user_id, permissions)
Ejemplo n.º 34
0
def create_post(request):
    """
    We use post, not put, because we don't know the id of the post
    """
    localizer = get_localizer(request)
    request_body = json.loads(request.body)
    user_id = authenticated_userid(request)
    user = Post.db.query(User).filter_by(id=user_id).one()

    message = request_body.get("message", None)
    html = request_body.get("html", None)
    reply_id = request_body.get("reply_id", None)
    idea_id = request_body.get("idea_id", None)
    subject = request_body.get("subject", None)
    publishes_synthesis_id = request_body.get("publishes_synthesis_id", None)

    if not user_id:
        raise HTTPUnauthorized()

    if not message:
        raise HTTPUnauthorized()

    if reply_id:
        in_reply_to_post = Post.get_instance(reply_id)
    else:
        in_reply_to_post = None

    if idea_id:
        in_reply_to_idea = Idea.get_instance(idea_id)
    else:
        in_reply_to_idea = None

    discussion_id = request.matchdict["discussion_id"]
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound(localizer.translate(_("No discussion found with id=%s" % discussion_id)))

    if subject:
        subject = subject
    elif in_reply_to_post:
        subject = in_reply_to_post.subject
    elif in_reply_to_idea:
        subject = in_reply_to_idea.short_title
    else:
        subject = discussion.topic
    subject = "Re: " + restrip_pat.sub("", subject)

    post_constructor_args = {
        "discussion": discussion,
        "message_id": uuid.uuid1().urn,
        "creator_id": user_id,
        "subject": subject,
        "body": html if html else message,
    }

    if publishes_synthesis_id:
        published_synthesis = Synthesis.get_instance(publishes_synthesis_id)
        post_constructor_args["publishes_synthesis"] = published_synthesis
        new_post = SynthesisPost(**post_constructor_args)
    else:
        new_post = AssemblPost(**post_constructor_args)

    new_post.db.add(new_post)
    new_post.db.flush()

    if in_reply_to_post:
        new_post.set_parent(in_reply_to_post)
    if in_reply_to_idea:
        idea_post_link = IdeaRelatedPostLink(creator_id=user_id, content=new_post, idea=in_reply_to_idea)
        IdeaRelatedPostLink.db.add(idea_post_link)

    for source in discussion.sources:
        source.send_post(new_post)

    return {"ok": True}
Ejemplo n.º 35
0
def discussion_permissions(request):
    user_id = authenticated_userid(request)
    db = Discussion.db()
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound("Discussion with id '%d' not found." % (
            discussion_id,))

    roles = db.query(Role).all()
    roles_by_name = {r.name: r for r in roles}
    role_names = [r.name for r in roles]
    permissions = db.query(Permission).all()
    perms_by_name = {p.name: p for p in permissions}
    permission_names = [p.name for p in permissions]

    disc_perms = db.query(DiscussionPermission).filter_by(
        discussion_id=discussion_id).join(Role, Permission).all()
    disc_perms_as_set = set((dp.role.name, dp.permission.name)
                            for dp in disc_perms)
    disc_perms_dict = {(dp.role.name, dp.permission.name): dp
                       for dp in disc_perms}
    local_roles = db.query(LocalUserRole).filter_by(
        discussion_id=discussion_id).join(Role, User).all()
    local_roles_as_set = set((lur.user.id, lur.role.name)
                             for lur in local_roles)
    local_roles_dict = {(lur.user.id, lur.role.name):lur
                        for lur in local_roles}
    users = set(lur.user for lur in local_roles)

    if request.POST:
        if 'submit_role_permissions' in request.POST:
            for role in role_names:
                if role == R_SYSADMIN:
                    continue
                for permission in permission_names:
                    allowed_text = 'allowed_%s_%s' % (role, permission)
                    if (role, permission) not in disc_perms_as_set and \
                            allowed_text in request.POST:
                        dp = DiscussionPermission(
                            role=roles_by_name[role],
                            permission=perms_by_name[permission],
                            discussion_id=discussion_id)
                        disc_perms_dict[(role, permission)] = dp
                        disc_perms_as_set.add((role, permission))
                        db.add(dp)
                    elif (role, permission) in disc_perms_as_set and \
                            allowed_text not in request.POST:
                        dp = disc_perms_dict[(role, permission)]
                        del disc_perms_dict[(role, permission)]
                        disc_perms_as_set.remove((role, permission))
                        db.delete(dp)
                if not role in SYSTEM_ROLES and\
                    'delete_'+role in request.POST:
                    db.delete(roles_by_name[role])
                    del roles_by_name[role]
                    role_names.remove(role)
        elif 'submit_add_role' in request.POST:
            #TODO: Sanitize role
            role = Role(name='r:'+request.POST['new_role'])
            roles_by_name[role.name] = role
            role_names.append(role.name)
            db.add(role)
        elif 'submit_user_roles' in request.POST:
            user_ids = {u.id for u in users}
            for role in role_names:
                if role == R_SYSADMIN:
                    continue
                prefix = 'has_'+role+'_'
                for name in request.POST:
                    if name.startswith(prefix):
                        user_id = int(name[len(prefix):])
                        if user_id not in user_ids:
                            users.add(User.get_instance(user_id))
                            user_ids.add(user_id)
                for user in users:
                    has_role_text = 'has_%s_%d' % (role, user.id)
                    if (user.id, role) not in local_roles_as_set and \
                            has_role_text in request.POST:
                        lur = LocalUserRole(
                            role=roles_by_name[role],
                            user=user,
                            discussion_id=discussion_id)
                        local_roles.append(lur)
                        local_roles_dict[(user.id, role)] = lur
                        local_roles_as_set.add((user.id, role))
                        db.add(lur)
                    elif (user.id, role) in local_roles_as_set and \
                            has_role_text not in request.POST:
                        lur = local_roles_dict[(user.id, role)]
                        del local_roles_dict[(user.id, role)]
                        local_roles_as_set.remove((user.id, role))
                        local_roles.remove(lur)
                        db.delete(lur)

        elif 'submit_look_for_user' in request.POST:
            search_string = '%' + request.POST['user_search'] + '%'
            other_users = db.query(User).join(AgentProfile).filter(AgentProfile.name.ilike(search_string)).union(
                db.query(User).outerjoin(Username).filter(Username.username.ilike(search_string))).union(
                db.query(User).filter(User.preferred_email.ilike(search_string))).all()
            users.update(other_users)

    def allowed(role, permission):
        if role == R_SYSADMIN:
            return True
        return (role, permission) in disc_perms_as_set

    def has_local_role(user_id, role):
        return (user_id, role) in local_roles_as_set

    context = dict(
        discussion=discussion,
        allowed=allowed,
        roles=role_names,
        permissions=permission_names,
        users=users,
        has_local_role=has_local_role,
        is_system_role=lambda r: r in SYSTEM_ROLES
    )

    return render_to_response(
        'admin/discussion_permissions.jinja2',
        context,
        request=request)
Ejemplo n.º 36
0
def discussion_permissions(request):
    user_id = authenticated_userid(request)
    assert user_id
    db = Discussion.default_db
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    error = ''

    if not discussion:
        raise HTTPNotFound("Discussion with id '%d' not found." % (
            discussion_id,))

    roles = db.query(Role).all()
    roles_by_name = {r.name: r for r in roles}
    role_names = [r.name for r in roles]
    role_names.sort()
    permissions = db.query(Permission).all()
    perms_by_name = {p.name: p for p in permissions}
    permission_names = [p.name for p in permissions]
    permission_names.sort()

    disc_perms = db.query(DiscussionPermission).filter_by(
        discussion_id=discussion_id).join(Role, Permission).all()
    disc_perms_as_set = set((dp.role.name, dp.permission.name)
                            for dp in disc_perms)
    disc_perms_dict = {(dp.role.name, dp.permission.name): dp
                       for dp in disc_perms}
    local_roles = db.query(LocalUserRole).filter_by(
        discussion_id=discussion_id).join(Role, User).all()
    local_roles_as_set = set((lur.user.id, lur.role.name)
                             for lur in local_roles)
    local_roles_dict = {(lur.user.id, lur.role.name): lur
                        for lur in local_roles}
    users = set(lur.user for lur in local_roles)
    num_users = ''

    if request.POST:
        if 'submit_role_permissions' in request.POST:
            for role in role_names:
                if role == R_SYSADMIN:
                    continue
                for permission in permission_names:
                    allowed_text = 'allowed_%s_%s' % (role, permission)
                    if (role, permission) not in disc_perms_as_set and \
                            allowed_text in request.POST:
                        dp = DiscussionPermission(
                            role=roles_by_name[role],
                            permission=perms_by_name[permission],
                            discussion_id=discussion_id)
                        disc_perms_dict[(role, permission)] = dp
                        disc_perms_as_set.add((role, permission))
                        db.add(dp)
                    elif (role, permission) in disc_perms_as_set and \
                            allowed_text not in request.POST:
                        dp = disc_perms_dict[(role, permission)]
                        del disc_perms_dict[(role, permission)]
                        disc_perms_as_set.remove((role, permission))
                        db.delete(dp)
                if not role in SYSTEM_ROLES and\
                        'delete_'+role in request.POST:
                    db.delete(roles_by_name[role])
                    del roles_by_name[role]
                    role_names.remove(role)
        elif 'submit_add_role' in request.POST:
            #TODO: Sanitize role
            role = Role(name='r:'+request.POST['new_role'])
            roles_by_name[role.name] = role
            role_names.append(role.name)
            db.add(role)
        elif 'submit_user_roles' in request.POST:
            user_ids = {u.id for u in users}
            for role in role_names:
                if role == R_SYSADMIN:
                    continue
                prefix = 'has_'+role+'_'
                for name in request.POST:
                    if name.startswith(prefix):
                        a_user_id = int(name[len(prefix):])
                        if a_user_id not in user_ids:
                            users.add(User.get_instance(a_user_id))
                            user_ids.add(a_user_id)
                for user in users:
                    has_role_text = 'has_%s_%d' % (role, user.id)
                    if (user.id, role) not in local_roles_as_set and \
                            has_role_text in request.POST:
                        lur = LocalUserRole(
                            role=roles_by_name[role],
                            user=user,
                            discussion_id=discussion_id)
                        local_roles.append(lur)

                        # TODO revisit this if Roles and Subscription are
                        # de-coupled
                        if role == 'r:participant':
                            user.update_agent_status_subscribe(discussion)

                        local_roles_dict[(user.id, role)] = lur
                        local_roles_as_set.add((user.id, role))
                        db.add(lur)
                    elif (user.id, role) in local_roles_as_set and \
                            has_role_text not in request.POST:
                        lur = local_roles_dict[(user.id, role)]
                        del local_roles_dict[(user.id, role)]
                        local_roles_as_set.remove((user.id, role))
                        local_roles.remove(lur)

                        # TODO revisit this if Roles and Subscription are
                        # de-coupled
                        if role == 'r:participant':
                            user.update_agent_status_unsubscribe(discussion)

                        db.delete(lur)

        elif 'submit_look_for_user' in request.POST:
            search_string = '%' + request.POST['user_search'] + '%'
            other_users = db.query(User).outerjoin(Username).filter(
                AgentProfile.name.ilike(search_string)
                | Username.username.ilike(search_string)
                | User.preferred_email.ilike(search_string)).all()
            users.update(other_users)
        elif 'submit_user_file' in request.POST:
            role = request.POST['add_with_role'] or R_PARTICIPANT
            if role == R_SYSADMIN and not user_has_permission(
                    discussion_id, user_id, P_SYSADMIN):
                role = R_ADMINISTRATOR
            if 'user_csvfile' in request.POST:
                try:
                    num_users = add_multiple_users_csv(
                        request, request.POST['user_csvfile'].file,
                        discussion_id, role,
                        request.POST.get('send_invite', False),
                        request.POST['email_subject'],
                        request.POST['text_email_message'],
                        request.POST['html_email_message'],
                        request.POST['sender_name'],
                        request.POST.get('resend_notloggedin', False))
                except Exception as e:
                    error = repr(e)
                    transaction.doom()
            else:
                error = request.localizer.translate(_('No file given.'))

    def allowed(role, permission):
        if role == R_SYSADMIN:
            return True
        return (role, permission) in disc_perms_as_set

    def has_local_role(user_id, role):
        return (user_id, role) in local_roles_as_set

    users = list(users)
    users.sort(key=order_by_domain_and_name)

    context = dict(
        get_default_context(request),
        discussion=discussion,
        allowed=allowed,
        roles=role_names,
        permissions=permission_names,
        users=users,
        error=error,
        num_users=num_users,
        has_local_role=has_local_role,
        is_system_role=lambda r: r in SYSTEM_ROLES
    )

    return render_to_response(
        'admin/discussion_permissions.jinja2',
        context,
        request=request)
Ejemplo n.º 37
0
def create_post(request):
    """
    Create a new post in this discussion.

    We use post, not put, because we don't know the id of the post
    """
    localizer = request.localizer
    request_body = json.loads(request.body)
    user_id = request.authenticated_userid
    if not user_id:
        raise HTTPUnauthorized()

    user = Post.default_db.query(User).filter_by(id=user_id).one()

    body = request_body.get('body', None)
    html = request_body.get('html', None)  # BG: Is this used now? I cannot see it.
    reply_id = request_body.get('reply_id', None)
    idea_id = request_body.get('idea_id', None)
    subject = request_body.get('subject', None)
    publishes_synthesis_id = request_body.get('publishes_synthesis_id', None)
    message_classifier = request_body.get('message_classifier', None)

    if not body and not publishes_synthesis_id:
        # Should we allow empty messages otherwise?
        raise HTTPBadRequest(localizer.translate(
                _("Your message is empty")))

    if reply_id:
        in_reply_to_post = Post.get_instance(reply_id)
    else:
        in_reply_to_post = None

    if idea_id:
        in_reply_to_idea = Idea.get_instance(idea_id)
    else:
        in_reply_to_idea = None

    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound(localizer.translate(_(
            "No discussion found with id=%s")) % (discussion_id,)
        )

    ctx = DummyContext({Discussion: discussion})
    if html:
        log.warning("Still using html")
        # how to guess locale in this case?
        body = LangString.create(sanitize_html(html))
        # TODO: AssemblPosts are pure text right now.
        # Allowing HTML requires changes to the model.
    elif body:
        # TODO: Accept HTML body.
        for e in body['entries']:
            e['value'] = sanitize_text(e['value'])
        body = LangString.create_from_json(
            body, context=ctx, user_id=user_id)
    else:
        body = LangString.EMPTY(discussion.db)

    if subject:
        for e in subject['entries']:
            e['value'] = sanitize_text(e['value'])
        subject = LangString.create_from_json(
            subject, context=ctx, user_id=user_id)
    else:
        from assembl.models import Locale
        locale = Locale.UNDEFINED
        # print(in_reply_to_post.subject, discussion.topic)
        if in_reply_to_post and in_reply_to_post.get_title():
            original_subject = in_reply_to_post.get_title().first_original()
            if original_subject:
                locale = original_subject.locale_code
                subject = (
                    original_subject.value or ''
                    if in_reply_to_post.get_title() else '')
        elif in_reply_to_idea:
            # TODO:  THis should use a cascade like the frontend
            # also, some ideas have extra langstring titles
            subject = (in_reply_to_idea.short_title
                       if in_reply_to_idea.short_title else '')
            locale = discussion.main_locale
        else:
            subject = discussion.topic if discussion.topic else ''
            locale = discussion.main_locale
        # print subject
        if subject is not None and len(subject):
            new_subject = "Re: " + restrip_pat.sub('', subject).strip()
            if (in_reply_to_post and new_subject == subject and
                    in_reply_to_post.get_title()):
                # reuse subject and translations
                subject = in_reply_to_post.get_title().clone(discussion.db)
            else:
                # how to guess locale in this case?
                subject = LangString.create(new_subject, locale)
        else:
            capture_message(
                "A message is about to be written to the database with an "
                "empty subject.  This is not supposed to happen.")
            subject = LangString.EMPTY(discussion.db)

    post_constructor_args = {
        'discussion': discussion,
        'creator_id': user_id,
        'message_classifier': message_classifier,
        'subject': subject,
        'body': body
    }

    if publishes_synthesis_id:
        published_synthesis = Synthesis.get_instance(publishes_synthesis_id)
        post_constructor_args['publishes_synthesis'] = published_synthesis
        new_post = SynthesisPost(**post_constructor_args)
        new_post.finalize_publish()
    else:
        new_post = AssemblPost(**post_constructor_args)
    new_post.guess_languages()

    discussion.db.add(new_post)
    discussion.db.flush()

    if in_reply_to_post:
        new_post.set_parent(in_reply_to_post)
    if in_reply_to_idea:
        idea_post_link = IdeaRelatedPostLink(
            creator_id=user_id,
            content=new_post,
            idea=in_reply_to_idea
        )
        discussion.db.add(idea_post_link)
        idea = in_reply_to_idea
        while idea:
            idea.send_to_changes()
            parents = idea.get_parents()
            idea = next(iter(parents)) if parents else None
    else:
        discussion.root_idea.send_to_changes()
    for source in discussion.sources:
        if 'send_post' in dir(source):
            source.send_post(new_post)
    permissions = get_permissions(user_id, discussion_id)

    return new_post.generic_json('default', user_id, permissions)
Ejemplo n.º 38
0
def create_post(request):
    """
    We use post, not put, because we don't know the id of the post
    """
    localizer = request.localizer
    request_body = json.loads(request.body)
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized()

    user = Post.default_db.query(User).filter_by(id=user_id).one()

    message = request_body.get('message', None)
    html = request_body.get('html', None)
    reply_id = request_body.get('reply_id', None)
    idea_id = request_body.get('idea_id', None)
    subject = request_body.get('subject', None)
    publishes_synthesis_id = request_body.get('publishes_synthesis_id', None)

    if not message:
        raise HTTPBadRequest(localizer.translate(_("Your message is empty")))

    if reply_id:
        in_reply_to_post = Post.get_instance(reply_id)
    else:
        in_reply_to_post = None

    if idea_id:
        in_reply_to_idea = Idea.get_instance(idea_id)
    else:
        in_reply_to_idea = None

    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound(
            localizer.translate(
                _("No discussion found with id=%s" % discussion_id)))

    if subject:
        subject = subject
    else:
        #print(in_reply_to_post.subject, discussion.topic)
        if in_reply_to_post:
            subject = in_reply_to_post.get_title(
            ) if in_reply_to_post.get_title() else ''
        elif in_reply_to_idea:
            #TODO:  THis should use a cascade like the frontend
            subject = in_reply_to_idea.short_title if in_reply_to_idea.short_title else ''
        else:
            subject = discussion.topic if discussion.topic else ''
        #print subject
        subject = "Re: " + restrip_pat.sub('', subject)

    post_constructor_args = {
        'discussion': discussion,
        'message_id': uuid.uuid1().hex + "@" + config.get('public_hostname'),
        'creator_id': user_id,
        'subject': subject,
        'body': html if html else message
    }

    if publishes_synthesis_id:
        published_synthesis = Synthesis.get_instance(publishes_synthesis_id)
        post_constructor_args['publishes_synthesis'] = published_synthesis
        new_post = SynthesisPost(**post_constructor_args)
    else:
        new_post = AssemblPost(**post_constructor_args)

    discussion.db.add(new_post)
    discussion.db.flush()

    if in_reply_to_post:
        new_post.set_parent(in_reply_to_post)
    if in_reply_to_idea:
        idea_post_link = IdeaRelatedPostLink(creator_id=user_id,
                                             content=new_post,
                                             idea=in_reply_to_idea)
        discussion.db.add(idea_post_link)
    for source in discussion.sources:
        source.send_post(new_post)
    permissions = get_permissions(user_id, discussion_id)

    return new_post.generic_json('default', user_id, permissions)
Ejemplo n.º 39
0
def discussion_permissions(request):
    user_id = authenticated_userid(request)
    assert user_id
    db = Discussion.default_db
    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)
    error = ''

    if not discussion:
        raise HTTPNotFound("Discussion with id '%d' not found." %
                           (discussion_id, ))

    roles = db.query(Role).all()
    roles_by_name = {r.name: r for r in roles}
    role_names = [r.name for r in roles]
    role_names.sort()
    permissions = db.query(Permission).all()
    perms_by_name = {p.name: p for p in permissions}
    permission_names = [p.name for p in permissions]
    permission_names.sort()

    disc_perms = db.query(DiscussionPermission).filter_by(
        discussion_id=discussion_id).join(Role, Permission).all()
    disc_perms_as_set = set(
        (dp.role.name, dp.permission.name) for dp in disc_perms)
    disc_perms_dict = {(dp.role.name, dp.permission.name): dp
                       for dp in disc_perms}
    local_roles = db.query(LocalUserRole).filter_by(
        discussion_id=discussion_id).join(Role, User).all()
    local_roles_as_set = set(
        (lur.user.id, lur.role.name) for lur in local_roles)
    local_roles_dict = {(lur.user.id, lur.role.name): lur
                        for lur in local_roles}
    users = set(lur.user for lur in local_roles)
    num_users = ''

    if request.POST:
        if 'submit_role_permissions' in request.POST:
            for role in role_names:
                if role == R_SYSADMIN:
                    continue
                for permission in permission_names:
                    allowed_text = 'allowed_%s_%s' % (role, permission)
                    if (role, permission) not in disc_perms_as_set and \
                            allowed_text in request.POST:
                        dp = DiscussionPermission(
                            role=roles_by_name[role],
                            permission=perms_by_name[permission],
                            discussion_id=discussion_id)
                        disc_perms_dict[(role, permission)] = dp
                        disc_perms_as_set.add((role, permission))
                        db.add(dp)
                    elif (role, permission) in disc_perms_as_set and \
                            allowed_text not in request.POST:
                        dp = disc_perms_dict[(role, permission)]
                        del disc_perms_dict[(role, permission)]
                        disc_perms_as_set.remove((role, permission))
                        db.delete(dp)
                if not role in SYSTEM_ROLES and\
                        'delete_'+role in request.POST:
                    db.delete(roles_by_name[role])
                    del roles_by_name[role]
                    role_names.remove(role)
        elif 'submit_add_role' in request.POST:
            #TODO: Sanitize role
            role = Role(name='r:' + request.POST['new_role'])
            roles_by_name[role.name] = role
            role_names.append(role.name)
            db.add(role)
        elif 'submit_user_roles' in request.POST:
            user_ids = {u.id for u in users}
            for role in role_names:
                if role == R_SYSADMIN:
                    continue
                prefix = 'has_' + role + '_'
                for name in request.POST:
                    if name.startswith(prefix):
                        a_user_id = int(name[len(prefix):])
                        if a_user_id not in user_ids:
                            users.add(User.get_instance(a_user_id))
                            user_ids.add(a_user_id)
                for user in users:
                    has_role_text = 'has_%s_%d' % (role, user.id)
                    if (user.id, role) not in local_roles_as_set and \
                            has_role_text in request.POST:
                        lur = LocalUserRole(role=roles_by_name[role],
                                            user=user,
                                            discussion_id=discussion_id)
                        local_roles.append(lur)

                        # TODO revisit this if Roles and Subscription are
                        # de-coupled
                        if role == 'r:participant':
                            user.update_agent_status_subscribe(discussion)

                        local_roles_dict[(user.id, role)] = lur
                        local_roles_as_set.add((user.id, role))
                        db.add(lur)
                    elif (user.id, role) in local_roles_as_set and \
                            has_role_text not in request.POST:
                        lur = local_roles_dict[(user.id, role)]
                        del local_roles_dict[(user.id, role)]
                        local_roles_as_set.remove((user.id, role))
                        local_roles.remove(lur)

                        # TODO revisit this if Roles and Subscription are
                        # de-coupled
                        if role == 'r:participant':
                            user.update_agent_status_unsubscribe(discussion)

                        db.delete(lur)

        elif 'submit_look_for_user' in request.POST:
            search_string = '%' + request.POST['user_search'] + '%'
            other_users = db.query(User).outerjoin(Username).filter(
                AgentProfile.name.ilike(search_string)
                | Username.username.ilike(search_string)
                | User.preferred_email.ilike(search_string)).all()
            users.update(other_users)
        elif 'submit_user_file' in request.POST:
            role = request.POST['add_with_role'] or R_PARTICIPANT
            if role == R_SYSADMIN and not user_has_permission(
                    discussion_id, user_id, P_SYSADMIN):
                role = R_ADMINISTRATOR
            if 'user_csvfile' in request.POST:
                try:
                    num_users = add_multiple_users_csv(
                        request, request.POST['user_csvfile'].file,
                        discussion_id, role,
                        request.POST.get('send_invite',
                                         False), request.POST['email_subject'],
                        request.POST['text_email_message'],
                        request.POST['html_email_message'],
                        request.POST['sender_name'],
                        request.POST.get('resend_notloggedin', False))
                except Exception as e:
                    error = repr(e)
                    transaction.doom()
            else:
                error = request.localizer.translate(_('No file given.'))

    def allowed(role, permission):
        if role == R_SYSADMIN:
            return True
        return (role, permission) in disc_perms_as_set

    def has_local_role(user_id, role):
        return (user_id, role) in local_roles_as_set

    users = list(users)
    users.sort(key=order_by_domain_and_name)

    context = dict(get_default_context(request),
                   discussion=discussion,
                   allowed=allowed,
                   roles=role_names,
                   permissions=permission_names,
                   users=users,
                   error=error,
                   num_users=num_users,
                   has_local_role=has_local_role,
                   is_system_role=lambda r: r in SYSTEM_ROLES)

    return render_to_response('admin/discussion_permissions.jinja2',
                              context,
                              request=request)
Ejemplo n.º 40
0
def create_post(request):
    """
    We use post, not put, because we don't know the id of the post
    """
    localizer = request.localizer
    request_body = json.loads(request.body)
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized()

    user = Post.default_db.query(User).filter_by(id=user_id).one()

    message = request_body.get('message', None)
    html = request_body.get('html', None)
    reply_id = request_body.get('reply_id', None)
    idea_id = request_body.get('idea_id', None)
    subject = request_body.get('subject', None)
    publishes_synthesis_id = request_body.get('publishes_synthesis_id', None)

    if not message:
        raise HTTPBadRequest(localizer.translate(
                _("Your message is empty")))

    if reply_id:
        in_reply_to_post = Post.get_instance(reply_id)
    else:
        in_reply_to_post = None
    
    if idea_id:
        in_reply_to_idea = Idea.get_instance(idea_id)
    else:
        in_reply_to_idea = None

    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound(
            localizer.translate(_("No discussion found with id=%s" % discussion_id))
        )

    if subject:
        subject = subject
    else:
        #print(in_reply_to_post.subject, discussion.topic)
        if in_reply_to_post:
            subject = in_reply_to_post.get_title() if in_reply_to_post.get_title() else ''
        elif in_reply_to_idea:
            #TODO:  THis should use a cascade like the frontend   
            subject = in_reply_to_idea.short_title if in_reply_to_idea.short_title else ''
        else:
            subject = discussion.topic if discussion.topic else ''
        #print subject
        subject = "Re: " + restrip_pat.sub('', subject)

    post_constructor_args = {
        'discussion': discussion,
        'creator_id': user_id,
        'subject': subject,
        'body': html if html else message
        }

    if publishes_synthesis_id:
        published_synthesis = Synthesis.get_instance(publishes_synthesis_id)
        post_constructor_args['publishes_synthesis'] = published_synthesis
        new_post = SynthesisPost(**post_constructor_args)
    else:
        new_post = AssemblPost(**post_constructor_args)

    discussion.db.add(new_post)
    discussion.db.flush()

    if in_reply_to_post:
        new_post.set_parent(in_reply_to_post)
    if in_reply_to_idea:
        idea_post_link = IdeaRelatedPostLink(
            creator_id=user_id,
            content=new_post,
            idea=in_reply_to_idea
        )
        discussion.db.add(idea_post_link)
        idea = in_reply_to_idea
        while idea:
            idea.send_to_changes()
            parents = idea.get_parents()
            idea = next(iter(parents)) if parents else None
    else:
        discussion.root_idea.send_to_changes()
    for source in discussion.sources:
        if 'send_post' in dir(source):
            source.send_post(new_post)
    permissions = get_permissions(user_id, discussion_id)

    return new_post.generic_json('default', user_id, permissions)
Ejemplo n.º 41
0
def create_post(request):
    """
    Create a new post in this discussion.

    We use post, not put, because we don't know the id of the post
    """
    localizer = request.localizer
    request_body = json.loads(request.body)
    user_id = authenticated_userid(request)
    if not user_id:
        raise HTTPUnauthorized()

    user = Post.default_db.query(User).filter_by(id=user_id).one()

    body = request_body.get('body', None)
    html = request_body.get('html',
                            None)  # BG: Is this used now? I cannot see it.
    reply_id = request_body.get('reply_id', None)
    idea_id = request_body.get('idea_id', None)
    subject = request_body.get('subject', None)
    publishes_synthesis_id = request_body.get('publishes_synthesis_id', None)
    message_classifier = request_body.get('message_classifier', None)

    if not body and not publishes_synthesis_id:
        # Should we allow empty messages otherwise?
        raise HTTPBadRequest(localizer.translate(_("Your message is empty")))

    if reply_id:
        in_reply_to_post = Post.get_instance(reply_id)
    else:
        in_reply_to_post = None

    if idea_id:
        in_reply_to_idea = Idea.get_instance(idea_id)
    else:
        in_reply_to_idea = None

    discussion_id = int(request.matchdict['discussion_id'])
    discussion = Discussion.get_instance(discussion_id)

    if not discussion:
        raise HTTPNotFound(
            localizer.translate(_("No discussion found with id=%s")) %
            (discussion_id, ))

    ctx = DummyContext({Discussion: discussion})
    if html:
        log.warning("Still using html")
        # how to guess locale in this case?
        body = LangString.create(html)
    elif body:
        body = LangString.create_from_json(body, context=ctx, user_id=user_id)
    else:
        body = LangString.EMPTY(discussion.db)

    if subject:
        subject = LangString.create_from_json(subject,
                                              context=ctx,
                                              user_id=user_id)
    else:
        # print(in_reply_to_post.subject, discussion.topic)
        if in_reply_to_post:
            subject = (in_reply_to_post.get_title().first_original().value
                       or '' if in_reply_to_post.get_title() else '')
        elif in_reply_to_idea:
            # TODO:  THis should use a cascade like the frontend
            subject = (in_reply_to_idea.short_title
                       if in_reply_to_idea.short_title else '')
        else:
            subject = discussion.topic if discussion.topic else ''
        # print subject
        if subject is not None and len(subject):
            new_subject = "Re: " + restrip_pat.sub('', subject).strip()
            if (in_reply_to_post and new_subject == subject
                    and in_reply_to_post.get_title()):
                # reuse subject and translations
                subject = in_reply_to_post.get_title().clone(discussion.db)
            else:
                # how to guess locale in this case?
                subject = LangString.create(new_subject)
        else:
            capture_message(
                "A message is about to be written to the database with an "
                "empty subject.  This is not supposed to happen.")
            subject = LangString.EMPTY(discussion.db)

    post_constructor_args = {
        'discussion': discussion,
        'creator_id': user_id,
        'message_classifier': message_classifier,
        'subject': subject,
        'body': body
    }

    if publishes_synthesis_id:
        published_synthesis = Synthesis.get_instance(publishes_synthesis_id)
        post_constructor_args['publishes_synthesis'] = published_synthesis
        new_post = SynthesisPost(**post_constructor_args)
        new_post.finalize_publish()
    else:
        new_post = AssemblPost(**post_constructor_args)

    discussion.db.add(new_post)
    discussion.db.flush()

    if in_reply_to_post:
        new_post.set_parent(in_reply_to_post)
    if in_reply_to_idea:
        idea_post_link = IdeaRelatedPostLink(creator_id=user_id,
                                             content=new_post,
                                             idea=in_reply_to_idea)
        discussion.db.add(idea_post_link)
        idea = in_reply_to_idea
        while idea:
            idea.send_to_changes()
            parents = idea.get_parents()
            idea = next(iter(parents)) if parents else None
    else:
        discussion.root_idea.send_to_changes()
    for source in discussion.sources:
        if 'send_post' in dir(source):
            source.send_post(new_post)
    permissions = get_permissions(user_id, discussion_id)

    return new_post.generic_json('default', user_id, permissions)