Skip to content

Commit 567dcdf

Browse files
authored
Merge pull request #20 from evolvedbinary/fix-explorer-permission-denied
Explorer API should return HTTP 403 Forbidden when user does not have permission
2 parents 7c929da + 48d3494 commit 567dcdf

File tree

8 files changed

+287
-4
lines changed

8 files changed

+287
-4
lines changed

pom.xml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
<project.build.source>1.8</project.build.source>
4949
<project.build.target>1.8</project.build.target>
5050

51+
<rest-assured.version>4.3.1</rest-assured.version>
52+
5153
<!-- default supported exist-db version -->
5254
<exist.version>5.0.0</exist.version>
5355

@@ -72,7 +74,21 @@
7274
<dependency>
7375
<groupId>io.rest-assured</groupId>
7476
<artifactId>rest-assured</artifactId>
75-
<version>4.3.1</version>
77+
<version>${rest-assured.version}</version>
78+
<scope>test</scope>
79+
</dependency>
80+
81+
<dependency>
82+
<groupId>io.rest-assured</groupId>
83+
<artifactId>json-schema-validator</artifactId>
84+
<version>${rest-assured.version}</version>
85+
<scope>test</scope>
86+
</dependency>
87+
88+
<dependency>
89+
<groupId>org.apache.httpcomponents</groupId>
90+
<artifactId>httpcore</artifactId>
91+
<version>4.4.6</version>
7692
<scope>test</scope>
7793
</dependency>
7894

@@ -91,6 +107,10 @@
91107
</resources>
92108

93109
<testResources>
110+
<testResource>
111+
<directory>src/test/resources</directory>
112+
<filtering>false</filtering>
113+
</testResource>
94114
<testResource>
95115
<directory>src/test/resources-filtered</directory>
96116
<filtering>true</filtering>

src/main/xar-resources/api.xqm

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,23 @@ declare
7575
%rest:produces("application/json")
7676
%output:method("json")
7777
function api:explorer($uri) {
78-
api:cors-allow(
79-
exp:describe($uri)
80-
)
78+
api:with-valid-uri-ex($uri, function($uri) {
79+
if (sm:has-access($uri, "r-x"))
80+
then
81+
[
82+
(),
83+
exp:describe($uri)
84+
]
85+
else
86+
[
87+
map {
88+
"code": $hsc:forbidden,
89+
"reason": "User: " || (sm:id()//sm:username)[1] || " is not permitted to access: " || $uri
90+
},
91+
()
92+
]
93+
94+
})
8195
};
8296

8397
declare
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Fusion Studio API - API for Fusion Studio
3+
* Copyright © 2017 Evolved Binary ([email protected])
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Affero General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Affero General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Affero General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package com.fusiondb.studio.api;
19+
20+
import org.junit.jupiter.api.Test;
21+
22+
import static com.fusiondb.studio.api.API.getApiBaseUri;
23+
import static io.restassured.RestAssured.when;
24+
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
25+
import static org.apache.http.HttpStatus.SC_FORBIDDEN;
26+
import static org.apache.http.HttpStatus.SC_OK;
27+
28+
public class ExplorerIT {
29+
30+
@Test
31+
public void root() {
32+
when().
33+
get(getApiBaseUri() + "/explorer?uri=/db").
34+
then().
35+
statusCode(SC_OK).
36+
assertThat().
37+
body(matchesJsonSchemaInClasspath("explorer-schema.json"));
38+
}
39+
40+
/**
41+
* Attempt to access a non-public Collection as guest user.
42+
*/
43+
@Test
44+
public void insufficientPermissions() {
45+
when().
46+
get(getApiBaseUri() + "/explorer?uri=/db/system/security").
47+
then().
48+
statusCode(SC_FORBIDDEN);
49+
}
50+
}

src/test/resources/ace-schema.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "ACE",
4+
"type": "object",
5+
"required" : [ "accessType", "mode", "target", "who" ],
6+
"properties" : {
7+
"mode" : {
8+
"pattern" : "[rwx-]{3}",
9+
"type" : "string",
10+
"example" : "-wx"
11+
},
12+
"target" : {
13+
"type" : "string",
14+
"example" : "USER",
15+
"enum" : [ "USER", "GROUP" ]
16+
},
17+
"accessType" : {
18+
"type" : "string",
19+
"example" : "DENIED",
20+
"enum" : [ "ALLOWED", "DENIED" ]
21+
},
22+
"who" : {
23+
"type" : "string",
24+
"example" : "a-read-only-user"
25+
}
26+
}
27+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "Collection",
4+
"type": "object",
5+
"required": [
6+
"acl",
7+
"created",
8+
"group",
9+
"mode",
10+
"owner",
11+
"uri"
12+
],
13+
"properties": {
14+
"uri": {
15+
"type": "string",
16+
"format": "uri",
17+
"example": "/db/col1"
18+
},
19+
"created": {
20+
"type": "string",
21+
"format": "date-time",
22+
"example": "2018-11-14T15:45:26.539+08:00"
23+
},
24+
"owner": {
25+
"type": "string",
26+
"example": "SYSTEM"
27+
},
28+
"group": {
29+
"type": "string",
30+
"example": "dba"
31+
},
32+
"mode": {
33+
"type": "string",
34+
"example": "rwxr-xr-x"
35+
},
36+
"acl": {
37+
"type": "array",
38+
"items": {
39+
"$ref": "ace-schema.json"
40+
}
41+
},
42+
"collections": {
43+
"type": "array",
44+
"items": {
45+
"$ref": "sub-collection-schema.json"
46+
}
47+
},
48+
"documents": {
49+
"type": "array",
50+
"items": {
51+
"$ref": "document-schema.json"
52+
}
53+
}
54+
}
55+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "Document",
4+
"type": "object",
5+
"required" : [ "acl", "binaryDoc", "created", "group", "lastModified", "mediaType", "mode", "owner", "size", "uri" ],
6+
"properties" : {
7+
"uri" : {
8+
"type" : "string",
9+
"format" : "uri",
10+
"example" : "/db/doc1.xml"
11+
},
12+
"created" : {
13+
"type" : "string",
14+
"format" : "date-time",
15+
"example" : "2018-11-14T15:45:26.539+08:00"
16+
},
17+
"lastModified" : {
18+
"type" : "string",
19+
"format" : "date-time",
20+
"example" : "2018-11-14T15:45:26.539+08:00"
21+
},
22+
"mediaType" : {
23+
"type" : "string",
24+
"example" : "application/xml"
25+
},
26+
"binaryDoc" : {
27+
"type" : "boolean",
28+
"example" : false
29+
},
30+
"size" : {
31+
"type" : "integer",
32+
"format" : "int64",
33+
"example" : 8192
34+
},
35+
"owner" : {
36+
"type" : "string",
37+
"example" : "SYSTEM"
38+
},
39+
"group" : {
40+
"type" : "string",
41+
"example" : "dba"
42+
},
43+
"mode" : {
44+
"type" : "string",
45+
"example" : "rwxr-xr-x"
46+
},
47+
"acl" : {
48+
"type" : "array",
49+
"items" : {
50+
"$ref" : "ace-schema.json"
51+
}
52+
}
53+
}
54+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "Explorer Response",
4+
"type" : "object",
5+
"required" : [ "collections", "documents" ],
6+
"properties" : {
7+
"collections" : {
8+
"type" : "array",
9+
"items" : {
10+
"$ref" : "collection-schema.json"
11+
}
12+
},
13+
"documents" : {
14+
"type" : "array",
15+
"items" : {
16+
"$ref" : "document-schema.json"
17+
}
18+
}
19+
}
20+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "SubCollection",
4+
"type": "object",
5+
"required": [
6+
"acl",
7+
"created",
8+
"group",
9+
"mode",
10+
"owner",
11+
"uri"
12+
],
13+
"properties": {
14+
"uri": {
15+
"type": "string",
16+
"format": "uri",
17+
"example": "/db/col1"
18+
},
19+
"created": {
20+
"type": "string",
21+
"format": "date-time",
22+
"example": "2018-11-14T15:45:26.539+08:00"
23+
},
24+
"owner": {
25+
"type": "string",
26+
"example": "SYSTEM"
27+
},
28+
"group": {
29+
"type": "string",
30+
"example": "dba"
31+
},
32+
"mode": {
33+
"type": "string",
34+
"example": "rwxr-xr-x"
35+
},
36+
"acl": {
37+
"type": "array",
38+
"items": {
39+
"$ref": "ace-schema.json"
40+
}
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)