Skip to content

Commit a96f4dd

Browse files
authored
Merge pull request #62 from line-o/feat/publish-route
Improve routes and logging
2 parents 09e9ade + a028344 commit a96f4dd

17 files changed

+288
-314
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ build/*
22
expath-pkg.xml
33
.existdb.json
44
.DS_Store
5+
6+
# IDE settings
7+
.vscode
8+
.idea

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ The application:
1111
- Exposes an Atom feed with all package updates
1212
- Allows administrators to log in, upload new packages, and refresh the package metadata
1313

14-
By default, eXist-db's Dashboard > Package Manager is configured to access the eXist-db Public Application Repository at https://demo.exist-db.org/exist/apps/public-repo/index.html.
14+
By default, eXist-db's Dashboard > Package Manager is configured to access the eXist-db Public Application Repository at https://exist-db.org/exist/apps/public-repo.

admin.html

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,16 @@ <h3><span data-template="app:package-group-abbrev"/></h3>
5050
</div>
5151
<div class="col-md-4">
5252
<p>
53-
<a href="index.html" class="btn btn-primary">
53+
<a href="" class="btn btn-primary">
5454
<i class="glyphicon glyphicon-share"/> Return to list
5555
</a>
5656
</p>
5757
<p>
58-
<a href="?rebuild-package-groups-metadata=true" class="btn btn-default">
58+
<a href="admin?rebuild-package-groups-metadata=true" class="btn btn-default">
5959
<i class="glyphicon glyphicon-repeat"/> Rebuild package-groups metadata
6060
</a>
6161
</p>
62-
<a href="index.html?logout=true" class="btn btn-default">
62+
<a href="?logout=true" class="btn btn-default">
6363
<i class="glyphicon glyphicon-log-out"/> Log out</a>
6464
<h2>Upload Packages</h2>
6565
<p>Upload xar packages to the public repository. New packages will appear in the list of
@@ -85,14 +85,14 @@ <h2>Upload Packages</h2>
8585
</table>
8686
</div>
8787
</div>
88-
<script type="text/javascript" src="resources/scripts/jquery.ui.widget.js"/>
89-
<script type="text/javascript" src="resources/scripts/jquery.iframe-transport.js"/>
90-
<script type="text/javascript" src="resources/scripts/jquery.fileupload.js"/>
88+
<script type="text/javascript" src="resources/scripts/jquery.ui.widget.js"></script>
89+
<script type="text/javascript" src="resources/scripts/jquery.iframe-transport.js"></script>
90+
<script type="text/javascript" src="resources/scripts/jquery.fileupload.js"></script>
9191
<script type="text/javascript">
9292
$(function () {
9393
'use strict';
9494
$('#fileupload').fileupload({
95-
url: "put-package",
95+
url: "publish",
9696
dataType: 'json',
9797
done: function (e, data) {
9898
$.each(data.result.files, function (index, file) {

build.xml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<property file="local.build.properties"/>
44
<property file="build.properties"/>
55
<property name="build" value="./build"/>
6-
<property name="server.url" value="http://demo.exist-db.org/exist/apps/public-repo/public/"/>
6+
<!-- <property name="server.url" value="http://exist-db.org/exist/apps/public-repo/publish"/> -->
77
<condition property="git.commit" value="${git.commit}" else="">
88
<isset property="git.commit"/>
99
</condition>
@@ -24,26 +24,27 @@
2424
<zip destfile="${build}/${project.name}-${project.version}${git.commit}.xar">
2525
<fileset dir=".">
2626
<include name="*.*"/>
27+
<exclude name=".*"/>
2728
<include name="modules/**"/>
2829
<include name="resources/**"/>
2930
<include name="templates/**"/>
3031
<include name="meta/*"/>
3132
<exclude name="${build}/*"/>
32-
<exclude name=".git*"/>
3333
<exclude name="*.tmpl"/>
3434
<exclude name="*.properties"/>
35-
<exclude name=".project"/>
3635
<exclude name="public/*"/>
3736
</fileset>
3837
</zip>
3938
</target>
39+
<!--
4040
<target name="upload">
4141
<input message="Enter password:" addproperty="server.pass" defaultvalue="">
4242
<handler type="secure"/>
4343
</input>
4444
<property name="xar" value="${project.name}-${project.version}${git.commit}.xar"/>
4545
<exec executable="curl">
46-
<arg line="-T ${build}/${xar} -u admin:${server.pass} ${server.url}/${xar}"/>
46+
<arg line="-T ${build}/${xar} -u repo:${server.pass} ${server.url}/${xar}"/>
4747
</exec>
4848
</target>
49+
-->
4950
</project>

controller.xql

Lines changed: 137 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
xquery version "3.1";
22

3-
import module namespace config="http://exist-db.org/xquery/apps/config" at "modules/config.xqm";
43
import module namespace login="http://exist-db.org/xquery/login" at "resource:org/exist/xquery/modules/persistentlogin/login.xql";
54

5+
import module namespace config="http://exist-db.org/xquery/apps/config" at "modules/config.xqm";
6+
67
declare namespace sm="http://exist-db.org/xquery/securitymanager";
78

89
declare variable $exist:path external;
@@ -17,82 +18,98 @@ declare variable $app-root-absolute-url :=
1718
|| $exist:controller
1819
;
1920

20-
login:set-user("org.exist.public-repo.login", (), false()),
21+
declare function local:is-authorized-user() as xs:boolean {
22+
let $user := request:get-attribute($config:login-domain || ".user")
23+
return
24+
(
25+
exists($user) and
26+
sm:get-user-groups($user) = config:repo-permissions()?group
27+
)
28+
};
29+
30+
login:set-user($config:login-domain, (), false()),
31+
32+
(:
33+
: =============
34+
: Public routes
35+
: =============
36+
:)
2137

22-
if ($exist:path eq "") then
38+
if (request:get-method() eq "GET" and $exist:path eq "") then
2339
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
24-
<redirect url="{request:get-uri()}/"/>
40+
<redirect url="{$app-root-absolute-url}/"/>
41+
</dispatch>
42+
43+
(: Landing page with package listing :)
44+
else if (request:get-method() eq "GET" and $exist:path eq "/") then
45+
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
46+
<forward url="{$exist:controller}/index.html"/>
47+
<view>
48+
<forward url="{$exist:controller}/modules/view.xq">
49+
<set-header name="Cache-Control" value="no-cache"/>
50+
<add-parameter name="base-url" value="{$app-root-absolute-url}"/>
51+
</forward>
52+
</view>
2553
</dispatch>
2654

27-
else if ($exist:path eq "/") then
28-
(: forward root path to index.xql :)
55+
(: Redirect request for legacy "/index.html" page to "/" :)
56+
else if (request:get-method() eq "GET" and $exist:path eq "/index.html") then
57+
(: TODO make the redirect issue a 301 :)
2958
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
30-
<redirect url="index.html"/>
59+
<redirect url="{$app-root-absolute-url}/"/>
3160
</dispatch>
3261

33-
else if ($exist:path eq "/public/apps.xml") then
62+
(: List apps for packageservice. See https://github.com/eXist-db/existdb-packageservice/blob/master/modules/packages.xqm#L285-L286. :)
63+
else if (request:get-method() eq "GET" and $exist:path eq "/public/apps.xml") then
3464
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
3565
<forward url="{$exist:controller}/modules/list.xq"/>
3666
</dispatch>
3767

38-
(: Protected resource: user is required to log in with valid credentials.
39-
If the login fails or no credentials were provided, the request is redirected
40-
to the login.html page. :)
41-
else if ($exist:path eq "/admin.html") then
42-
let $user := request:get-attribute("org.exist.public-repo.login.user")
43-
return
44-
if (exists($user) and sm:get-user-groups($user) = config:repo-permissions()?group) then
45-
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
46-
<view>
47-
<forward url="{$exist:controller}/modules/view.xq">
48-
<set-header name="Cache-Control" value="no-cache"/>
49-
</forward>
50-
</view>
51-
</dispatch>
52-
else
53-
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
54-
<forward url="login.html"/>
55-
<view>
56-
<forward url="{$exist:controller}/modules/view.xq">
57-
<set-header name="Cache-Control" value="no-cache"/>
58-
</forward>
59-
</view>
60-
</dispatch>
61-
62-
(: Protected resource :)
63-
else if ($exist:path eq "/put-package") then
64-
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
65-
<forward url="{$exist:controller}/modules/put-package.xq"/>
66-
</dispatch>
67-
68-
else if (ends-with($exist:resource, ".html") and starts-with($exist:path, "/packages")) then
69-
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
70-
<forward url="{concat($exist:controller, '/packages.html')}"/>
71-
<view>
72-
<forward url="{concat($exist:controller, '/modules/view.xq')}">
73-
<add-parameter name="abbrev" value="{substring-before($exist:resource, '.html')}"/>
74-
</forward>
75-
</view>
68+
(: Redirect request for package detail with legacy ".html" extension to new canonical pattern without the extension :)
69+
else if (request:get-method() eq "GET" and starts-with($exist:path, "/packages") and ends-with($exist:resource, ".html")) then
70+
(: TODO make the redirect issue a 301 :)
71+
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
72+
<redirect url="{$app-root-absolute-url}/packages/{substring-before($exist:resource, ".html")}?{request:get-query-string()}"/>
7673
</dispatch>
77-
78-
else if (ends-with($exist:resource, ".html")) then
79-
(: the html page is run through view.xq to expand templates :)
74+
75+
(: Serve package detail - without the legacy ".html" extension :)
76+
else if (request:get-method() eq "GET" and starts-with($exist:path, "/packages")) then
8077
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
78+
<forward url="{$exist:controller}/packages.html"/>
8179
<view>
82-
<forward url="modules/view.xq">
83-
<set-header name="Cache-Control" value="no-cache"/>
80+
<forward url="{$exist:controller}/modules/view.xq">
81+
<add-parameter name="abbrev" value="{$exist:resource}"/>
82+
<add-parameter name="base-url" value="{$app-root-absolute-url}"/>
8483
</forward>
8584
</view>
8685
</dispatch>
8786

88-
else if (contains($exist:path, "/public/") and ends-with($exist:resource, ".xar") or ends-with($exist:resource, ".zip")) then
87+
(: Serve requests for packages as ".xar" or ".zip" :)
88+
else if
89+
(
90+
request:get-method() eq "GET" and
91+
starts-with($exist:path, "/public/") and
92+
(
93+
ends-with($exist:resource, ".xar") or
94+
ends-with($exist:resource, ".zip")
95+
)
96+
) then
8997
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
9098
<forward url="{$exist:controller}/modules/get-package.xq">
9199
<add-parameter name="filename" value="{$exist:resource}"/>
92100
</forward>
93101
</dispatch>
94102

95-
else if (contains($exist:path, "/public/") and (ends-with($exist:resource, ".png") or ends-with($exist:resource, ".svg"))) then
103+
(: Serve requests for icons in the supported formats :)
104+
else if
105+
(
106+
request:get-method() eq "GET" and
107+
starts-with($exist:path, "/public/") and
108+
(
109+
ends-with($exist:resource, ".png") or
110+
ends-with($exist:resource, ".svg")
111+
)
112+
) then
96113
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
97114
<forward url="{$exist:controller}/modules/get-icon.xq">
98115
<add-parameter name="filename" value="{$exist:resource}"/>
@@ -105,37 +122,92 @@ else if (contains($exist:path, "/public/") and (ends-with($exist:resource, ".png
105122
: - existdb-packageservice v1.3.9 and earlier (fixed in https://github.com/eXist-db/existdb-packageservice/releases/tag/v1.3.10) --> and thus all versions of eXist up to and including v5.2.0.
106123
: - shared-resources v0.8.4 and earlier (fixed in https://github.com/eXist-db/shared-resources/releases/tag/v0.8.5) --> and thus all versions of eXist up to and including v4.7.0.
107124
:)
108-
else if ($exist:path eq "/modules/find.xql") then
125+
else if (request:get-method() eq "GET" and $exist:path eq "/modules/find.xql") then
126+
(: TODO make the redirect issue a 301 :)
109127
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
110-
<redirect url="../find?{request:get-query-string()}"/>
128+
<redirect url="{$app-root-absolute-url}/find?{request:get-query-string()}"/>
111129
</dispatch>
112130

113-
else if ($exist:path eq "/find") then
131+
else if (request:get-method() eq "GET" and $exist:path eq "/find") then
114132
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
115-
<forward url="modules/find.xq">
133+
<forward url="{$exist:controller}/modules/find.xq">
116134
<add-parameter name="app-root-absolute-url" value="{$app-root-absolute-url}"/>
117135
</forward>
118136
</dispatch>
119137

120-
else if ($exist:resource eq "feed.xml") then
138+
else if (request:get-method() eq "GET" and $exist:path eq "/feed.xml") then
121139
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
122-
<forward url="modules/feed.xq"/>
140+
<forward url="{$exist:controller}/modules/feed.xq"/>
123141
</dispatch>
124142

125-
else if (contains($exist:path, "/$shared/")) then
143+
else if (request:get-method() eq "GET" and contains($exist:path, "/$shared/")) then
126144
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
127145
<forward url="/shared-resources/{substring-after($exist:path, '/$shared/')}">
128146
<set-header name="Cache-Control" value="max-age=3600, must-revalidate"/>
129147
</forward>
130148
</dispatch>
131149

132-
else if (contains($exist:path, "/resources/")) then
150+
else if (request:get-method() eq "GET" and contains($exist:path, "/resources/")) then
133151
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
134152
<set-header name="Cache-Control" value="max-age=3600, must-revalidate"/>
135153
</dispatch>
136-
137-
else
138-
(: everything else is passed through :)
154+
155+
(:
156+
: ================
157+
: Protected routes
158+
: ================
159+
:)
160+
161+
(: User is required to be logged in and member of a specific group. Redirect unauthorized requests to the login page. :)
162+
else if
163+
(
164+
not(local:is-authorized-user()) and
165+
$exist:path = ("/admin", "/publish")
166+
) then
139167
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
140-
<cache-control cache="yes"/>
168+
<forward url="{$exist:controller}/login.html"/>
169+
<view>
170+
<forward url="{$exist:controller}/modules/view.xq">
171+
<set-header name="Cache-Control" value="no-cache"/>
172+
<add-parameter name="base-url" value="{$app-root-absolute-url}"/>
173+
</forward>
174+
</view>
175+
</dispatch>
176+
177+
(: Allow authenticated users into admin page :)
178+
else if (request:get-method() = ("GET", "POST") and $exist:path eq "/admin") then
179+
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
180+
<forward url="{$exist:controller}/admin.html"/>
181+
<view>
182+
<forward url="{$exist:controller}/modules/view.xq">
183+
<set-header name="Cache-Control" value="no-cache"/>
184+
<add-parameter name="base-url" value="{$app-root-absolute-url}"/>
185+
</forward>
186+
</view>
141187
</dispatch>
188+
189+
(: Redirect requests for legacy "/admin.html" page to "/admin" :)
190+
else if (request:get-method() = ("GET", "POST") and $exist:path eq "/admin.html") then
191+
(: TODO make the redirect issue a 301 :)
192+
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
193+
<redirect url="{$app-root-absolute-url}/admin"/>
194+
</dispatch>
195+
196+
(: Accept package uploads at the "/publish" endpoint :)
197+
else if (request:get-method() eq "POST" and $exist:path eq "/publish") then
198+
<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
199+
<forward url="{$exist:controller}/modules/publish-package.xq"/>
200+
</dispatch>
201+
202+
(:
203+
: ==============
204+
: Fallback route
205+
: ==============
206+
:)
207+
208+
(: Respond with a 404 Not Found error :)
209+
else
210+
(
211+
response:set-status-code(404),
212+
<data>Not found</data>
213+
)

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ <h2>Packages</h2>
3030
<div class="col-md-4">
3131
<h2>Admin</h2>
3232
<p>
33-
<a href="admin.html" class="btn btn-primary">
33+
<a href="./admin" class="btn btn-primary">
3434
<i class="glyphicon glyphicon-open"/> Upload</a>
3535
</p>
3636
<p>(requires login)</p>

0 commit comments

Comments
 (0)