Commit 3bd5cdcc authored by mrodzis's avatar mrodzis 🦊

Merge branch 'bugfix/#98-forking' into 'develop'

Fixes broken forking process.

Closes #98

See merge request !73
parents 848dd24f e6430c48
......@@ -7,6 +7,7 @@ xquery version "3.1";
:
: @author Mathias Göbel
: @author Stefan Hynek
: @author Michelle Weidling
: @version 0.3
: :)
......@@ -18,19 +19,23 @@ declare namespace expath="http://expath.org/ns/pkg";
declare namespace repo="http://exist-db.org/xquery/repo";
(:~
: Generates a password in the given length.
: Generates a random password in the given length. For compatibility reasons
: only ASCII characters are used. A password MUST have at least 10 characters.
: It is strongly recommended to change the password to a personalized one!
:
: @param $length the length of the resulting password
: @author Mathias Göbel
: @author Michelle Weidling
: @return A password of the requested length composed of ASCII characters
: @since 0.2
: :)
declare function local:passwordGenerator($length as xs:integer) {
if($length lt 10)
then error( QName("https://sade.textgrid.de/ns/error", "FORK04"), "Short password. Use at least 10 characters.")
declare function local:passwordGenerator($length as xs:integer) as xs:string {
if($length lt 10) then
error( QName("https://sade.textgrid.de/ns/error", "FORK04"), "Short password. Use at least 10 characters.")
else
(: charmap must not contain characters that do not evaluate against xs:anyURI
or a regular expression REPLACEMENT. :)
let $charset := string-to-codepoints('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz') => codepoints-to-string()
let $charset := string-to-codepoints('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz') => codepoints-to-string()
let $charsetLength := string-length($charset)
let $password :=
for $i in 1 to $length
......@@ -58,6 +63,7 @@ declare variable $repoConf :=
<description>{ $target }. A Fork of TextGrid: SADE.</description>
<author>Johannes Biermann</author>
<author>Mathias Göbel</author>
<author>Stefan Hynek</author>
<author>Markus Matoni</author>
<author>Ubbo Veentjer</author>
<author>Michelle Weidling</author>
......@@ -74,7 +80,17 @@ declare variable $repoConf :=
</meta>;
declare function local:xar($app-collection as xs:string, $expand-xincludes as xs:boolean) {
(:~
: Creates a XAR package of the newly forked SADE application.
:
: @param $app-collection The path to the newly created collection, e.g. ""/db/tmp/SADE-test"
: @param $expand-xincludes true() if eXist's XInclude expanding mechanism should be switched on
: @return A XAR package containing the newly forked SADE application
: @author Mathias Göbel
: @author Michelle Weidling
:)
declare function local:xar($app-collection as xs:string, $expand-xincludes as xs:boolean)
as xs:base64Binary* {
let $entries :=
dbutil:scan(xs:anyURI($app-collection), function($collection as xs:anyURI?, $resource as xs:anyURI?) {
let $resource-relative-path := substring-after($resource, $app-collection || "/")
......@@ -101,61 +117,64 @@ declare function local:xar($app-collection as xs:string, $expand-xincludes as xs
let $listTargetsNotAllowed := ("develop", xmldb:get-child-collections('/db/apps')[starts-with(., "sade-")] ! substring-after(., "sade-"))
if( $target = "" ) then
error( QName("https://sade.textgrid.de/ns/error", "FORK01"), "No target provided.")
else if ( $target = $listTargetsNotAllowed ) then
error( QName("https://sade.textgrid.de/ns/error", "FORK05"), "The fork must not be namend " || string-join($listTargetsNotAllowed, "; ") || ".")
else if ( $expathConf/string(@name) = (//expath:package/string(@name)) )
error( QName("https://sade.textgrid.de/ns/error", "FORK06"), "Target collection is available, but target name is not.")
else
let $expand-xincludes := request:get-parameter("expand-xincludes", "false") cast as xs:boolean
let $name := string($expathConf/@abbrev)
let $xar-name := $name || "-" || string($expathConf/@version) || ".xar"
let $source-collection := if(starts-with($config:app-root, "null")) then substring-after($config:app-root, "null") else $config:app-root
let $source-name := tokenize($source-collection, "/")[last()]
let $login := xmldb:login(
"/db",
request:get-parameter("forkUser", ""),
request:get-parameter("forkPassword", "")
)
return
if(not($login))
then error( QName("https://sade.textgrid.de/ns/error", "FORK03"), "Authentication not successful. :-(")
else
let $prepare as xs:string :=
(
xmldb:create-collection(xmldb:create-collection("/db", "tmp"), $name),
xmldb:copy-collection($source-collection, "/db/tmp/"||$name)
)
let $replace-the-configs := (
xmldb:store("/db/tmp/"||$name ||"/"||$source-name, "repo.xml", $repoConf),
xmldb:store("/db/tmp/"||$name ||"/"||$source-name, "expath-pkg.xml", $expathConf))
let $edit-config.xml :=
update replace doc( "/db/tmp/"||$name ||"/"||$source-name||"/config.xml" )//cf:param[@key = "project-title"]/text() with text {replace($target, "\-", " ")}
let $path-to-xar as xs:string :=
xmldb:store-as-binary(
"/db/tmp/"||$name,
$xar-name,
xs:base64Binary(local:xar( $prepare||"/"||$source-name, $expand-xincludes))
)
return
if($dry-run = "true")
then
(: this error is not an error, but in case of a dry run, we want to get
a status information, that tells us, that it was a dry run. :)
error( QName("https://sade.textgrid.de/ns/error", "FORK02"), "Dry run completed.")
if( $target = "" ) then
error( QName("https://sade.textgrid.de/ns/error", "FORK01"), "No target provided.")
else if ( $target = $listTargetsNotAllowed ) then
error( QName("https://sade.textgrid.de/ns/error", "FORK05"), "The fork must not be namend " || string-join($listTargetsNotAllowed, "; ") || ".")
else if ( $expathConf/string(@name) = (//expath:package/string(@name)) ) then
error( QName("https://sade.textgrid.de/ns/error", "FORK06"), "Target collection is available, but target name is not.")
else
(: we are using the repo addon because it handles all permissions
correct. :)
let $complete := repo:install-and-deploy-from-db($path-to-xar)
let $expand-xincludes := request:get-parameter("expand-xincludes", "false") cast as xs:boolean
let $name := string($expathConf/@abbrev)
let $xar-name := $name || "-" || string($expathConf/@version) || ".xar"
let $source-collection := if(starts-with($config:app-root, "null")) then substring-after($config:app-root, "null") else $config:app-root
let $source-name := tokenize($source-collection, "/")[last()]
let $login := xmldb:login(
"/db",
request:get-parameter("forkUser", ""),
request:get-parameter("forkPassword", "")
)
return
if(not($login)) then
error( QName("https://sade.textgrid.de/ns/error", "FORK03"), "Authentication not successful. :-(")
else
let $prepare as xs:string :=
(
xmldb:create-collection(xmldb:create-collection("/db", "tmp"), $name),
xmldb:copy-collection($source-collection, "/db/tmp/" || $name)
)
let $replace-the-configs :=
(
xmldb:store("/db/tmp/" || $name || "/" || $source-name, "repo.xml", $repoConf),
xmldb:store("/db/tmp/" || $name || "/" || $source-name, "expath-pkg.xml", $expathConf)
)
let $edit-config.xml :=
update replace doc( "/db/tmp/" || $name || "/" || $source-name || "/config.xml" )//cf:param[@key = "project-title"]/text() with text {replace($target, "\-", " ")}
let $path-to-xar as xs:string :=
xmldb:store-as-binary(
"/db/tmp/"||$name,
$xar-name,
(: $prepare results in two xs:string (which are identical.
thus we have to select one of them. :)
xs:base64Binary(local:xar( $prepare[1] || "/" || $source-name, $expand-xincludes))
)
return
if($dry-run = "true")
then
(: this error is not an error, but in case of a dry run, we want to get
a status information, that tells us that it was a dry run. :)
error( QName("https://sade.textgrid.de/ns/error", "FORK02"), "Dry run completed.")
else
(: we are using the repo addon because it handles all permissions
correct. :)
let $complete := repo:install-and-deploy-from-db($path-to-xar)
return
if( $complete/@result = "ok" )
then
let $replacement := "apps/" || replace($name, "SADE", "sade") || "/publish.html?newpw=" || $password
let $uri := replace(tokenize($referer, "\?")[1], "apps/.+/publish\.html", $replacement)
return
response:redirect-to(xs:anyURI($uri))
else $complete
return
if( $complete/@result = "ok" ) then
let $replacement := "apps/" || replace($name, "SADE", "sade") || "/publish.html?newpw=" || $password
let $uri := replace(tokenize($referer, "\?")[1], "apps/.+/publish\.html", $replacement)
return
response:redirect-to(xs:anyURI($uri))
else
$complete
......@@ -14,6 +14,20 @@
<prepare>pre-install.xq</prepare>
<finish>post-install.xq</finish>
<changelog>
<change version="4.2.0">
<ul xmlns="http://www.w3.org/1999/xhtml">
<li class="feat">Features
<ul>
<li/>
</ul>
</li>
<li class="bugs">Bugfixes
<ul>
<li>Fix broken forking process</li>
</ul>
</li>
</ul>
</change>
<change version="4.1.0">
<ul xmlns="http://www.w3.org/1999/xhtml">
<li class="feat">Features
......
......@@ -8,10 +8,11 @@
<div class="panel-body">
<p>By default your data will be published in the Project »<span data-template="app:title"/>«. If you want to create a new project based on the current, you can enter the title below. This will create a fork of the current project.</p>
<form class="form-group input-group" style="width: 100%;" action="modules/fork.xq" method="post">
<p>Enter the new project name <span style="font-family:mono;">[a-zA-Z0-9\-\.]</span>:</p>
<p><em>Caution:</em> Since all new projects get the prefix "sade-" you should refrain from naming your new project "sade-test" or the like.</p>
<p>Allowed characters are: <span style="font-family:mono;">[a-zA-Z0-9\-\.]</span></p>
<input type="hidden" name="forkUser" value="admin"/>
<input type="hidden" name="forkPassword" value=""/>
<input class="form-control" name="target" type="text" required="true" pattern="[a-zA-Z0-9\-\.]+" style="width:calc(100%-75px);"/>
<input class="form-control" name="target" type="text" required="true" pattern="[a-zA-Z0-9\-\.]+" style="width:calc(100%-75px);" placeholder="New project name (allowed characters: [a-zA-Z0-9\-\.])" />
<span class="input-group-btn">
<button class="btn btn-default" type="submit" style="vertical-align:bottom;bottom:0;position:absolute;right:0;width:75px;">Create</button>
</span>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment