Esempio n. 1
0
def extra_log_info_from_req(req, add_user_info=True):

    extra = {"args": dict(req.args), "path": req.path, "method": req.method}

    if req.method == "POST":
        extra["form"] = dict(req.form)
        extra["files"] = [{
            "filename": f.filename,
            "tempname": f.tempname,
            "content_type": f.content_type,
            "filesize": os.path.getsize(f.filename)
        } for f in req.files.values()]

    if add_user_info:
        from core.users import user_from_session
        user = user_from_session(req.session)
        extra["user_is_anonymous"] = user.is_anonymous

        if not user.is_anonymous:
            extra["user_id"] = user.id
            extra["user_is_editor"] = user.is_editor
            extra["user_is_admin"] = user.is_admin

        extra["headers"] = {
            k.lower(): v
            for k, v in [h.split(": ", 1) for h in req.header]
        }

    return extra
Esempio n. 2
0
def _lookup_current_user():
    from core.users import user_from_session
    top = _request_ctx_stack.top
    if top is None:
        raise RuntimeError('working outside of request context')
    session = top.session
    return user_from_session(session)
Esempio n. 3
0
def extra_log_info_from_req(req, add_user_info=True):

    extra = {"args": dict(req.args),
             "path": req.path,
             "method": req.method}

    if req.method == "POST":
        extra["form"] = dict(req.form)
        extra["files"] = [{"filename": f.filename,
                           "tempname": f.tempname,
                           "content_type": f.content_type,
                           "filesize": f.filesize} for f in req.files.values()]

    if add_user_info:
        from core.users import user_from_session
        user = user_from_session(req.session)
        extra["user_is_anonymous"] = user.is_anonymous

        if not user.is_anonymous:
            extra["user_id"] = user.id
            extra["user_is_editor"] = user.is_editor
            extra["user_is_admin"] = user.is_admin

        extra["headers"] = {k.lower(): v for k, v in [h.split(": ", 1) for h in req.header]}

    return extra
Esempio n. 4
0
def login(req):

    if "LoginSubmit" in req.form:
        error = _handle_login_submit(req)
        if not error:
            return httpstatus.HTTP_MOVED_TEMPORARILY
    else:
        error = None

    _set_return_after_login(req)

    # show login form
    user = users.user_from_session(req.session)
    language = lang(req)
    ctx = {
        "error": error,
        "user": user,
        "email": config.get("email.support"),
        "language": language,
        "csrf": req.csrf_token.current_token
    }
    login_html = webconfig.theme.render_macro("login.j2.jade", "login", ctx)
    # following import is also needed for pytest monkeypatch for render_page
    from web.frontend.frame import render_page
    html = render_page(req, None, login_html)
    req.write(html)
    return httpstatus.HTTP_OK
Esempio n. 5
0
def pwdchange(req):
    user = users.user_from_session(req.session)
    error = 0

    if "ChangeSubmit" in req.form:
        if user.is_anonymous:
            req.request["Location"] = _make_collection_root_link()
            return httpstatus.HTTP_MOVED_TEMPORARILY

        else:
            password_old = req.form.get("password_old")
            password_new1 = req.form.get("password_new1")
            password_new2 = req.form.get("password_new2")

            try:
                auth.change_user_password(user, password_old, password_new1, password_new2, req)
            except WrongPassword:
                error = 1
            except PasswordsDoNotMatch:
                error = 2
            except PasswordChangeNotAllowed:
                error = 4
            else:
                req["Location"] = _make_collection_root_link()
                return httpstatus.HTTP_MOVED_TEMPORARILY

    content_html = webconfig.theme.render_macro("login.j2.jade", "change_pwd", {"error": error, "user": user, "csrf": req.csrf_token.current_token})
    # following import is also needed for pytest monkeypatch for render_page
    from web.frontend.frame import render_page
    html = render_page(req, None, content_html)
    req.write(html)
    return httpstatus.HTTP_OK
Esempio n. 6
0
def logout(req):
    # if the session has expired, there may be no user in the session dictionary
    user = users.user_from_session(req.session)
    if not user.is_anonymous:
        auth.logout_user(user, req)
        if "user_id" in req.session:
            del req.session["user_id"]

    req.request["Location"] = '/'
    # return to caching
    req.setCookie("nocache", "0", path="/")
    return httpstatus.HTTP_MOVED_TEMPORARILY
Esempio n. 7
0
def logout(req):
    # if the session has expired, there may be no user in the session dictionary
    user = users.user_from_session(req.session)
    if not user.is_anonymous:
        auth.logout_user(user, req)
        if "user_id" in req.session:
            del req.session["user_id"]

    req.request["Location"] = '/'
    # return to caching
    req.setCookie("nocache", "0", path="/")
    return httpstatus.HTTP_MOVED_TEMPORARILY
Esempio n. 8
0
def show_content(req, op):
    from core.users import user_from_session
    user = user_from_session(req.session)

    if not user.is_admin:
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL("web/admin/frame.html", {}, macro="errormessage")
    else:
        if op == "" or op not in q(Root).one().system_attrs.get("admin.menu", ""):
            if op != "memstats":
                op = "menumain"
        module = findmodule(op.split("_")[0])

        if op.find("_") > -1:
            return module.spc(req, op)
        else:
            return module.validate(req, op)
Esempio n. 9
0
def show_content(req, op):
    from core.users import user_from_session
    user = user_from_session(req.session)

    if not user.is_admin:
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL("web/admin/frame.html", {}, macro="errormessage")
    else:
        if op == "" or op not in q(Root).one().system_attrs.get(
                "admin.menu", ""):
            op = "menumain"
        module = findmodule(op.split("_")[0])

        if op.find("_") > -1:
            return module.spc(req, op)
        else:
            return module.validate(req, op)
Esempio n. 10
0
    def req_has_access_to_node_id(node_id, accesstype, req=None, date=func.current_date()):
        # XXX: the database-independent code could move to core.node
        from core.transition import request
        from core.users import user_from_session

        if req is None:
            req = request

        user = user_from_session(req.session)

        # XXX: like in mysql version, what's the real solution?
        try:
            ip = IPv4Address(req.remote_addr)
        except AddressValueError:
            logg.warn("illegal IP address %s, refusing IP-based access", req.remote_addr)
            ip = None

        return Node.has_access_to_node_id(node_id, accesstype, user, ip, date)
Esempio n. 11
0
def login(req):

    if "LoginSubmit" in req.form:
        error = _handle_login_submit(req)
        if not error:
            return httpstatus.HTTP_MOVED_TEMPORARILY
    else:
        error = None

    _set_return_after_login(req)

    # show login form
    user = users.user_from_session(req.session)
    language = lang(req)
    ctx = {"error": error, "user": user, "email": config.get("email.support"), "language": language, "csrf": req.csrf_token.current_token}
    login_html = webconfig.theme.render_macro("login.j2.jade", "login", ctx)
    # following import is also needed for pytest monkeypatch for render_page
    from web.frontend.frame import render_page
    html = render_page(req, None, login_html)
    req.write(html)
    return httpstatus.HTTP_OK
Esempio n. 12
0
def build_accessfunc_arguments(user=None, ip=None, date=None, req=None):
    """Build the expected arguments for the DB permission procedures has_*_access_to_node()
    IP and date are returned unchanged when passed to this function. 
    For missing arguments, default values are set from request information or current date.
    :returns: 3-tuple of group_ids, ip and date
        For admin users, it returns (None, None, None) which means: ignore all access checks.
        Users can test for this and skip permission checks completely.
    """
    from core.users import get_guest_user

    if user is None and ip is None:
        if req is None:
            req = request

        from core.users import user_from_session

        user = user_from_session(req.session)
        # XXX: like in mysql version, what's the real solution?
        try:
            ip = IPv4Address(req.remote_addr)
        except AddressValueError:
            logg.warn("illegal IP address %s, refusing IP-based access",
                      req.remote_addr)
            ip = None

    if user is None:
        user = get_guest_user()

    # admin sees everything ;)
    if user.is_admin:
        return (None, None, None)

    if ip is None:
        ip = IPv4Address("0.0.0.0")

    if date is None:
        date = sqlfunc.current_date()

    return user.group_ids, ip, date
Esempio n. 13
0
    def req_has_access_to_node_id(node_id,
                                  accesstype,
                                  req=None,
                                  date=func.current_date()):
        # XXX: the database-independent code could move to core.node
        from core.transition import request
        from core.users import user_from_session

        if req is None:
            req = request

        user = user_from_session(req.session)

        # XXX: like in mysql version, what's the real solution?
        try:
            ip = IPv4Address(req.remote_addr)
        except AddressValueError:
            logg.warn("illegal IP address %s, refusing IP-based access",
                      req.remote_addr)
            ip = None

        return Node.has_access_to_node_id(node_id, accesstype, user, ip, date)
Esempio n. 14
0
def pwdchange(req):
    user = users.user_from_session(req.session)
    error = 0

    if "ChangeSubmit" in req.form:
        if user.is_anonymous:
            req.request["Location"] = _make_collection_root_link()
            return httpstatus.HTTP_MOVED_TEMPORARILY

        else:
            password_old = req.form.get("password_old")
            password_new1 = req.form.get("password_new1")
            password_new2 = req.form.get("password_new2")

            try:
                auth.change_user_password(user, password_old, password_new1,
                                          password_new2, req)
            except WrongPassword:
                error = 1
            except PasswordsDoNotMatch:
                error = 2
            except PasswordChangeNotAllowed:
                error = 4
            else:
                req["Location"] = _make_collection_root_link()
                return httpstatus.HTTP_MOVED_TEMPORARILY

    content_html = webconfig.theme.render_macro(
        "login.j2.jade", "change_pwd", {
            "error": error,
            "user": user,
            "csrf": req.csrf_token.current_token
        })
    # following import is also needed for pytest monkeypatch for render_page
    from web.frontend.frame import render_page
    html = render_page(req, None, content_html)
    req.write(html)
    return httpstatus.HTTP_OK
Esempio n. 15
0
def build_accessfunc_arguments(user=None, ip=None, date=None, req=None):
    """Build the expected arguments for the DB permission procedures has_*_access_to_node()
    IP and date are returned unchanged when passed to this function. 
    For missing arguments, default values are set from request information or current date.
    :returns: 3-tuple of group_ids, ip and date
        For admin users, it returns (None, None, None) which means: ignore all access checks.
        Users can test for this and skip permission checks completely.
    """
    from core.users import get_guest_user

    if user is None and ip is None:
        if req is None:
            req = request

        from core.users import user_from_session

        user = user_from_session(req.session)
        # XXX: like in mysql version, what's the real solution?
        try:
            ip = IPv4Address(req.remote_addr)
        except AddressValueError:
            logg.warn("illegal IP address %s, refusing IP-based access", req.remote_addr)
            ip = None

    if user is None:
        user = get_guest_user()

    # admin sees everything ;)
    if user.is_admin:
        return (None, None, None)

    if ip is None:
        ip = IPv4Address("0.0.0.0")
    
    if date is None:
        date = sqlfunc.current_date()

    return user.group_ids, ip, date
Esempio n. 16
0
def getContent(req, ids):
    ret = ""
    user = user_from_session(req.session)

    if "metadata" in user.hidden_edit_functions:
        print "error 1"
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL("web/edit/edit.html", {}, macro="access_error")

    metatypes = []
    nodes = []
    masklist = []
    err = 0

    # flag indicating change of node.name (fancytree node may have to be updated)
    # keep as integer
    # negative -> no change
    # else -> id of changed node
    flag_nodename_changed = -1

    for nid in ids:
        node = q(Node).get(nid)
        if not node.has_write_access():
            req.setStatus(httpstatus.HTTP_FORBIDDEN)
            return req.getTAL("web/edit/edit.html", {}, macro="access_error")

        schema = node.schema
        if schema not in metatypes:
            metatypes.append(schema)
        if len(nodes) == 0 or nodes[0].schema == schema:
            nodes += [node]

    idstr = ",".join(ids)
    action = req.params.get('action', '').strip()

    if len(ids) > 1 and len(metatypes) > 1:
        logg.info("%s in editor metadata (action=%r) multiple documents not supported: %r",
                  user.login_name, action, [[n.id, n.name, n.type]for n in nodes])
        return req.getTAL("web/edit/modules/metadata.html", {}, macro="multiple_documents_not_supported")

    logg.info("%s in editor metadata (action=%r): %r", user.login_name, action, [[n.id, n.name, n.type]for n in nodes])

    metadatatype = node.metadatatype

    if metadatatype:
        for m in metadatatype.filter_masks(masktype='edit'):
            if m.has_read_access():
                masklist.append(m)

    if hasattr(node, "metaFields"):

        masklist = [SystemMask(
            "settings", t(req, "settings"), node.metaFields(lang(req)))] + masklist

    default = None
    for m in masklist:
        if m.getDefaultMask():
            default = m
            break
    if not default and len(masklist):
        default = masklist[0]

    maskname = req.params.get("mask", node.system_attrs.get("edit.lastmask") or "editmask")
    if maskname == "":
        maskname = default.name

    mask = None
    for m in masklist:
        if maskname == m.name:
            mask = m
            break

    if not mask and default:
        mask = default
        maskname = default.name

    for n in nodes:
        n.system_attrs["edit.lastmask"] = maskname

    db.session.commit()

    if not mask:
        return req.getTAL("web/edit/modules/metadata.html", {}, macro="no_mask")

    # context default for TAL interpreter
    ctx = {}
    ctx["user"] = user
    ctx["metatypes"] = metatypes
    ctx["idstr"] = idstr
    ctx["node"] = nodes[0]  # ?
    ctx["flag_nodename_changed"] = flag_nodename_changed
    ctx["nodes"] = nodes
    ctx["masklist"] = masklist
    ctx["maskname"] = maskname
    ctx["language"] = lang(req)
    ctx["t"] = t
    ctx["csrf"] = req.csrf_token.current_token

    if action == 'restore':
        raise NotImplementedError("restore version not implemented, later...")

    if action == 'delete':
        raise NotImplementedError("delete version not implemented, later...")

    if "edit_metadata" in req.params:
        flag_nodename_changed = _handle_edit_metadata(req, mask, nodes)
        logg.debug("%s change metadata %s", user.login_name, idstr)
        logg.debug(pf(req.params))

    if "edit_metadata" in req.params or node.system_attrs.get("faulty") == "true":
        if not hasattr(mask, "i_am_not_a_mask"):
            req.params["errorlist"] = mask.validate(nodes)

    update_date, creation_date = get_datelists(nodes)
    data = {}
    
    # version handling
    current_version = nodes[0].versions[-1]
    tagged_node_versions = nodes[0].tagged_versions.all()
    published_version = nodes[0].get_published_version()
    
    data["untagged_current_version"] = current_version
    data["published_version"] = published_version

    if tagged_node_versions:
        data["tagged_versions"] = tagged_node_versions[::-1] # descending version tag
        if current_version == tagged_node_versions[-1]:
            data["untagged_current_version"] = None
    else:
        data["tagged_versions"] = []
        
    data["creation_date"] = creation_date
    data["update_date"] = update_date
    data["err"] = err

    _maskform, _fields = get_maskform_and_fields(nodes, mask, req)
    data["maskform"] = _maskform
    data["fields"] = _fields

    data.update(ctx)
    data["flag_nodename_changed"] = flag_nodename_changed

    ret += req.getTAL("web/edit/modules/metadata.html",
                      data, macro="edit_metadata")
    return ret
Esempio n. 17
0
def getContent(req, ids):
    ret = ""
    user = user_from_session(req.session)

    if "metadata" in user.hidden_edit_functions:
        print "error 1"
        req.setStatus(httpstatus.HTTP_FORBIDDEN)
        return req.getTAL("web/edit/edit.html", {}, macro="access_error")

    metatypes = []
    nodes = []
    masklist = []
    err = 0

    # flag indicating change of node.name (fancytree node may have to be updated)
    # keep as integer
    # negative -> no change
    # else -> id of changed node
    flag_nodename_changed = -1

    for nid in ids:
        node = q(Node).get(nid)
        if not node.has_write_access():
            req.setStatus(httpstatus.HTTP_FORBIDDEN)
            return req.getTAL("web/edit/edit.html", {}, macro="access_error")

        schema = node.schema
        if schema not in metatypes:
            metatypes.append(schema)
        if len(nodes) == 0 or nodes[0].schema == schema:
            nodes += [node]

    idstr = ",".join(ids)
    action = req.params.get('action', '').strip()

    if len(ids) > 1 and len(metatypes) > 1:
        logg.info("%s in editor metadata (action=%r) multiple documents not supported: %r",
                  user.login_name, action, [[n.id, n.name, n.type]for n in nodes])
        return req.getTAL("web/edit/modules/metadata.html", {}, macro="multiple_documents_not_supported")

    logg.info("%s in editor metadata (action=%r): %r", user.login_name, action, [[n.id, n.name, n.type]for n in nodes])

    metadatatype = node.metadatatype

    if metadatatype:
        for m in metadatatype.filter_masks(masktype='edit'):
            if m.has_read_access():
                masklist.append(m)

    if hasattr(node, "metaFields"):

        masklist = [SystemMask(
            "settings", t(req, "settings"), node.metaFields(lang(req)))] + masklist

    default = None
    for m in masklist:
        if m.getDefaultMask():
            default = m
            break
    if not default and len(masklist):
        default = masklist[0]

    maskname = req.params.get("mask", node.system_attrs.get("edit.lastmask") or "editmask")
    if maskname == "":
        maskname = default.name

    mask = None
    for m in masklist:
        if maskname == m.name:
            mask = m
            break

    if not mask and default:
        mask = default
        maskname = default.name

    for n in nodes:
        n.system_attrs["edit.lastmask"] = maskname

    db.session.commit()

    if not mask:
        return req.getTAL("web/edit/modules/metadata.html", {}, macro="no_mask")

    # context default for TAL interpreter
    ctx = {}
    ctx["user"] = user
    ctx["metatypes"] = metatypes
    ctx["idstr"] = idstr
    ctx["node"] = nodes[0]  # ?
    ctx["flag_nodename_changed"] = flag_nodename_changed
    ctx["nodes"] = nodes
    ctx["masklist"] = masklist
    ctx["maskname"] = maskname
    ctx["language"] = lang(req)
    ctx["t"] = t

    if action == 'restore':
        raise NotImplementedError("restore version not implemented, later...")

    if action == 'delete':
        raise NotImplementedError("delete version not implemented, later...")

    if "edit_metadata" in req.params:
        flag_nodename_changed = _handle_edit_metadata(req, mask, nodes)
        logg.debug("%s change metadata %s", user.login_name, idstr)
        logg.debug(pf(req.params))

    if "edit_metadata" in req.params or node.system_attrs.get("faulty") == "true":
        if not hasattr(mask, "i_am_not_a_mask"):
            req.params["errorlist"] = mask.validate(nodes)

    update_date, creation_date = get_datelists(nodes)
    data = {}
    
    # version handling
    current_version = nodes[0].versions[-1]
    tagged_node_versions = nodes[0].tagged_versions.all()
    published_version = nodes[0].get_published_version()
    
    data["untagged_current_version"] = current_version
    data["published_version"] = published_version

    if tagged_node_versions:
        data["tagged_versions"] = tagged_node_versions[::-1] # descending version tag
        if current_version == tagged_node_versions[-1]:
            data["untagged_current_version"] = None
    else:
        data["tagged_versions"] = []
        
    data["creation_date"] = creation_date
    data["update_date"] = update_date
    data["err"] = err

    _maskform, _fields = get_maskform_and_fields(nodes, mask, req)
    data["maskform"] = _maskform
    data["fields"] = _fields

    data.update(ctx)
    data["flag_nodename_changed"] = flag_nodename_changed

    ret += req.getTAL("web/edit/modules/metadata.html",
                      data, macro="edit_metadata")
    return ret