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
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)
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
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
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
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
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)
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)
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)
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
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
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
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
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