Skip to content

Commit 80d9753

Browse files
committed
[feature] Adds new xmldb-api security services
Signed-off-by: Patrick Reinhart <patrick@reini.net>
1 parent 9057c82 commit 80d9753

20 files changed

Lines changed: 1991 additions & 62 deletions
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* eXist-db Open Source Native XML Database
3+
* Copyright (C) 2001 The eXist-db Authors
4+
*
5+
* info@exist-db.org
6+
* http://www.exist-db.org
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2.1 of the License, or (at your option) any later version.
12+
*
13+
* This library is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public
19+
* License along with this library; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
*/
22+
package org.exist.xmldb;
23+
24+
import org.xmldb.api.security.AclEntry;
25+
import org.xmldb.api.security.Attributes;
26+
import org.xmldb.api.security.GroupPrincipal;
27+
import org.xmldb.api.security.Permission;
28+
import org.xmldb.api.security.Permissions;
29+
import org.xmldb.api.security.UserPrincipal;
30+
31+
import java.util.List;
32+
import java.util.Set;
33+
34+
record EXistAttributes(org.exist.security.Permission permission) implements Attributes {
35+
@Override
36+
public UserPrincipal owner() {
37+
return new EXistUserPrincipal(permission.getOwner());
38+
}
39+
40+
@Override
41+
public GroupPrincipal group() {
42+
return new EXistGroupPrincipal(permission.getGroup());
43+
}
44+
45+
@Override
46+
public Set<Permission> permissions() {
47+
return Permissions.fromOctal(permission.getMode());
48+
}
49+
50+
@Override
51+
public List<AclEntry> acl() {
52+
// no supported by eXist?
53+
return List.of();
54+
}
55+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* eXist-db Open Source Native XML Database
3+
* Copyright (C) 2001 The eXist-db Authors
4+
*
5+
* info@exist-db.org
6+
* http://www.exist-db.org
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2.1 of the License, or (at your option) any later version.
12+
*
13+
* This library is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public
19+
* License along with this library; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
*/
22+
package org.exist.xmldb;
23+
24+
import org.exist.security.Group;
25+
import org.xmldb.api.security.GroupPrincipal;
26+
27+
record EXistGroupPrincipal(Group group) implements GroupPrincipal {
28+
@Override
29+
public String getName() {
30+
return group.getName();
31+
}
32+
}
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*
2+
* eXist-db Open Source Native XML Database
3+
* Copyright (C) 2001 The eXist-db Authors
4+
*
5+
* info@exist-db.org
6+
* http://www.exist-db.org
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2.1 of the License, or (at your option) any later version.
12+
*
13+
* This library is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public
19+
* License along with this library; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
*/
22+
package org.exist.xmldb;
23+
24+
import org.exist.security.Account;
25+
import org.exist.security.Group;
26+
import org.exist.security.PermissionDeniedException;
27+
import org.xmldb.api.base.Collection;
28+
import org.xmldb.api.base.ErrorCodes;
29+
import org.xmldb.api.base.Resource;
30+
import org.xmldb.api.base.XMLDBException;
31+
import org.xmldb.api.security.AclEntry;
32+
import org.xmldb.api.security.Attributes;
33+
import org.xmldb.api.security.GroupPrincipal;
34+
import org.xmldb.api.security.Permission;
35+
import org.xmldb.api.security.Permissions;
36+
import org.xmldb.api.security.UserPrincipal;
37+
38+
import java.util.List;
39+
import java.util.Set;
40+
41+
record EXistPermissionManagement(EXistUserManagementService userManagementService) {
42+
43+
Account asUser(UserPrincipal userPrincipal) throws XMLDBException {
44+
if (userPrincipal instanceof EXistUserPrincipal(Account account)) {
45+
return account;
46+
} else {
47+
return userManagementService.getAccount(userPrincipal.getName());
48+
}
49+
}
50+
51+
Group asGroup(GroupPrincipal groupPrincipal) throws XMLDBException {
52+
if (groupPrincipal instanceof EXistGroupPrincipal(Group group)) {
53+
return group;
54+
} else {
55+
return userManagementService.getGroup(groupPrincipal.getName());
56+
}
57+
}
58+
59+
@FunctionalInterface
60+
interface PermissionAction {
61+
void accept(org.exist.security.Permission permission) throws PermissionDeniedException, XMLDBException;
62+
}
63+
64+
void withPermission(Collection collection, PermissionAction action) throws XMLDBException {
65+
try {
66+
action.accept(userManagementService.getPermissions(collection));
67+
} catch (PermissionDeniedException e) {
68+
throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, e);
69+
}
70+
}
71+
72+
void withPermission(Resource resource, PermissionAction action) throws XMLDBException {
73+
try {
74+
action.accept(userManagementService.getPermissions(resource));
75+
} catch (PermissionDeniedException e) {
76+
throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, e);
77+
}
78+
}
79+
80+
/*
81+
* to be replaced with the Permissions method as soon as available.
82+
*/
83+
int toOctal(Set<Permission> permissions) {
84+
int octal = 0;
85+
// Handle special bits
86+
if (permissions.contains(Permission.SET_UID)) {
87+
octal |= 04000; // SUID
88+
}
89+
if (permissions.contains(Permission.SET_GID)) {
90+
octal |= 02000; // SGID
91+
}
92+
if (permissions.contains(Permission.STICKY_BIT)) {
93+
octal |= 01000; // Sticky bit
94+
}
95+
// Handle owner permissions
96+
if (permissions.contains(Permission.OWNER_READ)) {
97+
octal |= 0400; // Owner read
98+
}
99+
if (permissions.contains(Permission.OWNER_WRITE)) {
100+
octal |= 0200; // Owner write
101+
}
102+
if (permissions.contains(Permission.OWNER_EXECUTE)) {
103+
octal |= 0100; // Owner execute
104+
}
105+
// Handle group permissions
106+
if (permissions.contains(Permission.GROUP_READ)) {
107+
octal |= 040; // Group read
108+
}
109+
if (permissions.contains(Permission.GROUP_WRITE)) {
110+
octal |= 020; // Group write
111+
}
112+
if (permissions.contains(Permission.GROUP_EXECUTE)) {
113+
octal |= 010; // Group execute
114+
}
115+
// Handle others permissions
116+
if (permissions.contains(Permission.OTHERS_READ)) {
117+
octal |= 04; // Others read
118+
}
119+
if (permissions.contains(Permission.OTHERS_WRITE)) {
120+
octal |= 02; // Others write
121+
}
122+
if (permissions.contains(Permission.OTHERS_EXECUTE)) {
123+
octal |= 01; // Others execute
124+
}
125+
return octal;
126+
}
127+
128+
Attributes getAttributes(Collection collection) throws XMLDBException {
129+
return new EXistAttributes(userManagementService.getPermissions(collection));
130+
}
131+
132+
Attributes getAttributes(Resource resource) throws XMLDBException {
133+
return new EXistAttributes(userManagementService.getPermissions(resource));
134+
}
135+
136+
Set<Permission> getPermissions(Collection collection) throws XMLDBException {
137+
return Permissions.fromOctal(userManagementService.getPermissions(collection).getMode());
138+
}
139+
140+
void setPermissions(Collection collection, Set<Permission> permissionSet) throws XMLDBException {
141+
withPermission(collection, permission -> permission.setMode(toOctal(permissionSet)));
142+
}
143+
144+
Set<Permission> getPermissions(Resource resource) throws XMLDBException {
145+
return Permissions.fromOctal(userManagementService.getPermissions(resource).getMode());
146+
}
147+
148+
void setPermissions(Resource resource, Set<Permission> permissionSet) throws XMLDBException {
149+
withPermission(resource, permission -> permission.setMode(toOctal(permissionSet)));
150+
}
151+
152+
List<AclEntry> getAcl(Collection collection) {
153+
// no supported by eXist?
154+
return List.of();
155+
}
156+
157+
void setAcl(Collection collection, List<AclEntry> list) {
158+
// no supported by eXist?
159+
}
160+
161+
List<AclEntry> getAcl(Resource resource) {
162+
// no supported by eXist?
163+
return List.of();
164+
}
165+
166+
void setAcl(Resource resource, List<AclEntry> list) {
167+
// no supported by eXist?
168+
}
169+
170+
UserPrincipal getOwner(Collection collection) throws XMLDBException {
171+
return new EXistUserPrincipal(userManagementService.getPermissions(collection).getOwner());
172+
}
173+
174+
void setOwner(Collection collection, UserPrincipal userPrincipal) throws XMLDBException {
175+
withPermission(collection, permission -> permission.setOwner(asUser(userPrincipal)));
176+
}
177+
178+
UserPrincipal getOwner(Resource resource) throws XMLDBException {
179+
return new EXistUserPrincipal(userManagementService.getPermissions(resource).getOwner());
180+
}
181+
182+
void setOwner(Resource resource, UserPrincipal userPrincipal) throws XMLDBException {
183+
withPermission(resource, permission -> permission.setOwner(asUser(userPrincipal)));
184+
}
185+
186+
GroupPrincipal getGroup(Collection collection) throws XMLDBException {
187+
return new EXistGroupPrincipal(userManagementService.getPermissions(collection).getGroup());
188+
}
189+
190+
void setGroup(Collection collection, GroupPrincipal groupPrincipal) throws XMLDBException {
191+
withPermission(collection, permission -> permission.setGroup(asGroup(groupPrincipal)));
192+
}
193+
194+
GroupPrincipal getGroup(Resource resource) throws XMLDBException {
195+
return new EXistGroupPrincipal(userManagementService.getPermissions(resource).getGroup());
196+
}
197+
198+
void setGroup(Resource resource, GroupPrincipal groupPrincipal) throws XMLDBException {
199+
withPermission(resource, permission -> permission.setGroup(asGroup(groupPrincipal)));
200+
}
201+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* eXist-db Open Source Native XML Database
3+
* Copyright (C) 2001 The eXist-db Authors
4+
*
5+
* info@exist-db.org
6+
* http://www.exist-db.org
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2.1 of the License, or (at your option) any later version.
12+
*
13+
* This library is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public
19+
* License along with this library; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
*/
22+
package org.exist.xmldb;
23+
24+
import org.exist.security.Account;
25+
import org.xmldb.api.security.UserPrincipal;
26+
27+
record EXistUserPrincipal(Account account) implements UserPrincipal {
28+
@Override
29+
public String getName() {
30+
return account.getName();
31+
}
32+
}

exist-core/src/main/java/org/exist/xmldb/LocalCollection.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
import org.xmldb.api.modules.XPathQueryService;
6060
import org.xmldb.api.modules.XQueryService;
6161
import org.xmldb.api.modules.XUpdateQueryService;
62+
import org.xmldb.api.security.PermissionManagementService;
63+
import org.xmldb.api.security.UserPrincipalLookupService;
6264

6365
import static com.evolvedbinary.j8fu.Try.Try;
6466
import static org.xmldb.api.base.ResourceType.BINARY_RESOURCE;
@@ -403,6 +405,8 @@ protected void registerProvders(ProviderRegistry registry) {
403405
registry.add(XUpdateQueryService.class, () -> new LocalXUpdateQueryService(user, brokerPool, this));
404406
registry.add(IndexQueryService.class, () -> new LocalIndexQueryService(user, brokerPool, this));
405407
registry.add(EXistRestoreService.class, () -> new LocalRestoreService(user, brokerPool, this));
408+
registry.add(UserPrincipalLookupService.class, () -> new LocalUserPrincipalLookupService(user, brokerPool, this));
409+
registry.add(PermissionManagementService.class, () -> new LocalPermissionManagementService(user, brokerPool, this));
406410
}
407411

408412
@Override

0 commit comments

Comments
 (0)