Thu, 11 Jun 2026 16:01:47 +0200
fixes #882 - wrong redirect after version/component/variant form
--- a/src/main/kotlin/de/uapcore/lightpit/servlet/ProjectServlet.kt Thu Jun 11 14:54:23 2026 +0200 +++ b/src/main/kotlin/de/uapcore/lightpit/servlet/ProjectServlet.kt Thu Jun 11 16:01:47 2026 +0200 @@ -190,6 +190,48 @@ } } + private fun obtainIdAndProject(http: HttpRequest, dao: DataAccessObject): Pair<Int, Project>? { + val id = http.param("id")?.toIntOrNull() + val projectid = http.param("projectid")?.toIntOrNull() ?: -1 + val project = dao.findProject(projectid) + return if (id == null || project == null) { + http.response.sendError(400) + null + } else { + Pair(id, project) + } + } + + private fun sanitizeReturnLink( + http: HttpRequest, project: Project, + version: Version? = null, component: Component? = null, variant: Variant? = null + ): String { + val entity = if (version != null) "versions" else if (component != null) "components" else "variants" + val defaultPath = http.baseHref + "projects/${project.node}/${entity}/" + + // referer is bad, redirect to default path + val returnPath = http.sanitizeReferer(http.param("returnLink")) + ?.substring(http.baseHref.length) ?: return defaultPath + + // check if referer is a link to the project overview + if (PathPattern("projects/%project").matches(returnPath)) return http.baseHref + "projects/${project.node}" + + // check if referer is an issue list for a project and reconstruct the path with possibly updated nodes + val pattern = PathPattern("projects/%project/issues/%version/%component/%variant/") + if (!pattern.matches(returnPath)) return defaultPath + + val pathParams = pattern.obtainPathParameters(returnPath) + val project = project.node + val version = version?.node ?: pathParams["version"] + val component = component?.node ?: pathParams["component"] + val variant = variant?.node ?: pathParams["variant"] + + // probably unnecessary safeguard - this should never happen + if (version == null || component == null || variant == null) return defaultPath + + return http.baseHref + "projects/$project/issues/$version/$component/$variant/" + } + private fun versions(http: HttpRequest, dao: DataAccessObject) { withPathInfo(http, dao)?.let { path -> with(http) { @@ -210,8 +252,7 @@ val version = if (path.versionInfo is OptionalPathInfo.Specific) path.versionInfo.elem else Version(-1, path.project.id) - val returnLink = http.baseHref + if (http.referer?.endsWith("/versions/") ?: true) - "projects/${path.project.node}/versions/" else path.issuesHref + val returnLink = http.referer ?: "projects/${path.project.node}/versions/" with(http) { view = VersionEditView(path.projectInfo, version, returnLink) @@ -221,18 +262,6 @@ } } - private fun obtainIdAndProject(http: HttpRequest, dao: DataAccessObject): Pair<Int, Project>? { - val id = http.param("id")?.toIntOrNull() - val projectid = http.param("projectid")?.toIntOrNull() ?: -1 - val project = dao.findProject(projectid) - return if (id == null || project == null) { - http.response.sendError(400) - null - } else { - Pair(id, project) - } - } - private fun versionCommit(http: HttpRequest, dao: DataAccessObject) { val idParams = obtainIdAndProject(http, dao) ?: return val (id, project) = idParams @@ -264,7 +293,7 @@ dao.updateVersion(version) } - http.renderCommit(http.sanitizeReferer(http.param("returnLink")) ?: "projects/${project.node}/versions/") + http.renderCommit(sanitizeReturnLink(http, project, version = version)) } private fun versionPlanning(http: HttpRequest, dao: DataAccessObject) { @@ -332,8 +361,7 @@ val component = if (path.componentInfo is OptionalPathInfo.Specific) path.componentInfo.elem else Component(-1, path.project.id) - val returnLink = http.baseHref + if (http.referer?.endsWith("/components/") ?: true) - "projects/${path.project.node}/components/" else path.issuesHref + val returnLink = http.referer ?: "projects/${path.project.node}/components/" with(http) { view = ComponentEditView(path.projectInfo, component, dao.listUsers(), returnLink) @@ -370,7 +398,7 @@ dao.updateComponent(component) } - http.renderCommit(http.sanitizeReferer(http.param("returnLink")) ?: "projects/${project.node}/components/") + http.renderCommit(sanitizeReturnLink(http, project, component = component)) } private fun variants(http: HttpRequest, dao: DataAccessObject) { @@ -393,8 +421,7 @@ val variant = if (path.variantInfo is OptionalPathInfo.Specific) path.variantInfo.elem else Variant(-1, path.project.id) - val returnLink = http.baseHref + if (http.referer?.endsWith("/variants/") ?: true) - "projects/${path.project.node}/variants/" else path.issuesHref + val returnLink = http.referer ?: "projects/${path.project.node}/variants/" with(http) { view = VariantEditView(path.projectInfo, variant, returnLink) @@ -427,7 +454,7 @@ dao.updateVariant(variant) } - http.renderCommit(http.sanitizeReferer(http.param("returnLink")) ?: "projects/${project.node}/variants/") + http.renderCommit(sanitizeReturnLink(http, project, variant = variant)) } private fun issue(http: HttpRequest, dao: DataAccessObject) {
--- a/src/main/webapp/WEB-INF/changelogs/changelog-de.jspf Thu Jun 11 14:54:23 2026 +0200 +++ b/src/main/webapp/WEB-INF/changelogs/changelog-de.jspf Thu Jun 11 16:01:47 2026 +0200 @@ -29,6 +29,8 @@ <ul> <li>RSS Einträge für Kommentare enthalten nun die Kommentar-ID in der GUID.</li> <li>Regression bei der Darstellung von Markdown-Überschriften behoben.</li> + <li>Regression beim Speichern von Versionen, Komponenten und Varianten behoben, die eine fehlerhafte Weiterleitung zur Folge hat, wenn der Pfadname geändert wird.</li> + <li>Fehler behoben, bei dem die Formulare für Versionen, Komponenten und Varianten die Pfadinformationen über die Teile, die nicht zum Formular gehören, verloren haben.</li> </ul> <h3>Version 1.6.1</h3>
--- a/src/main/webapp/WEB-INF/changelogs/changelog.jspf Thu Jun 11 14:54:23 2026 +0200 +++ b/src/main/webapp/WEB-INF/changelogs/changelog.jspf Thu Jun 11 16:01:47 2026 +0200 @@ -29,6 +29,8 @@ <ul> <li>Add the comment ID to the GUID of RSS entries for comments.</li> <li>Fix regression with rendering Markdown headings.</li> + <li>Fix regression that caused a wrong redirect when changing the node name of a version/component/variant.</li> + <li>Fix that redirecting from a version/component/variant only retains the path info for what was edited in the form.</li> </ul> <h3>Version 1.6.1</h3>