1
1
xquery version "3.1" ;
2
2
3
- import module namespace config="http://exist-db.org/xquery/apps/config" at "modules/config.xqm" ;
4
3
import module namespace login="http://exist-db.org/xquery/login" at "resource:org/exist/xquery/modules/persistentlogin/login.xql" ;
5
4
5
+ import module namespace config="http://exist-db.org/xquery/apps/config" at "modules/config.xqm" ;
6
+
6
7
declare namespace sm="http://exist-db.org/xquery/securitymanager" ;
7
8
8
9
declare variable $exist:path external ;
@@ -17,82 +18,98 @@ declare variable $app-root-absolute-url :=
17
18
|| $exist:controller
18
19
;
19
20
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
+ :)
21
37
22
- if ($exist:path eq "" ) then
38
+ if (request:get-method () eq "GET" and $exist:path eq "" ) then
23
39
<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>
25
53
</dispatch>
26
54
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 :)
29
58
<dispatch xmlns = "http://exist.sourceforge.net/NS/exist" >
30
- <redirect url = "index.html " />
59
+ <redirect url = "{$app-root-absolute-url} / " />
31
60
</dispatch>
32
61
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
34
64
<dispatch xmlns = "http://exist.sourceforge.net/NS/exist" >
35
65
<forward url = "{$exist:controller} /modules/list.xq" />
36
66
</dispatch>
37
67
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 ()} " />
76
73
</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
80
77
<dispatch xmlns = "http://exist.sourceforge.net/NS/exist" >
78
+ <forward url = "{$exist:controller} /packages.html" />
81
79
<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} " />
84
83
</forward>
85
84
</view>
86
85
</dispatch>
87
86
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
89
97
<dispatch xmlns = "http://exist.sourceforge.net/NS/exist" >
90
98
<forward url = "{$exist:controller} /modules/get-package.xq" >
91
99
<add-parameter name = "filename" value = "{$exist:resource} " />
92
100
</forward>
93
101
</dispatch>
94
102
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
96
113
<dispatch xmlns = "http://exist.sourceforge.net/NS/exist" >
97
114
<forward url = "{$exist:controller} /modules/get-icon.xq" >
98
115
<add-parameter name = "filename" value = "{$exist:resource} " />
@@ -105,37 +122,92 @@ else if (contains($exist:path, "/public/") and (ends-with($exist:resource, ".png
105
122
: - 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.
106
123
: - 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.
107
124
:)
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 :)
109
127
<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 ()} " />
111
129
</dispatch>
112
130
113
- else if ($exist:path eq "/find" ) then
131
+ else if (request:get-method () eq "GET" and $exist:path eq "/find" ) then
114
132
<dispatch xmlns = "http://exist.sourceforge.net/NS/exist" >
115
- <forward url = "modules/find.xq" >
133
+ <forward url = "{$exist:controller} / modules/find.xq" >
116
134
<add-parameter name = "app-root-absolute-url" value = "{$app-root-absolute-url} " />
117
135
</forward>
118
136
</dispatch>
119
137
120
- else if ($exist:resource eq "feed.xml" ) then
138
+ else if (request:get-method () eq "GET" and $exist:path eq "/ feed.xml" ) then
121
139
<dispatch xmlns = "http://exist.sourceforge.net/NS/exist" >
122
- <forward url = "modules/feed.xq" />
140
+ <forward url = "{$exist:controller} / modules/feed.xq" />
123
141
</dispatch>
124
142
125
- else if (contains ($exist:path, "/$shared/" )) then
143
+ else if (request:get-method () eq "GET" and contains ($exist:path, "/$shared/" )) then
126
144
<dispatch xmlns = "http://exist.sourceforge.net/NS/exist" >
127
145
<forward url = "/shared-resources/{substring-after ($exist:path, '/$shared/' )} " >
128
146
<set-header name = "Cache-Control" value = "max-age=3600, must-revalidate" />
129
147
</forward>
130
148
</dispatch>
131
149
132
- else if (contains ($exist:path, "/resources/" )) then
150
+ else if (request:get-method () eq "GET" and contains ($exist:path, "/resources/" )) then
133
151
<dispatch xmlns = "http://exist.sourceforge.net/NS/exist" >
134
152
<set-header name = "Cache-Control" value = "max-age=3600, must-revalidate" />
135
153
</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
139
167
<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>
141
187
</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
+ )
0 commit comments