java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/IPBlocklistTableWrapper.java
... ...
@@ -23,11 +23,9 @@ import com.sap.sse.gwt.client.ErrorReporter;
23 23
import com.sap.sse.gwt.client.celltable.EntityIdentityComparator;
24 24
import com.sap.sse.gwt.client.celltable.RefreshableSelectionModel;
25 25
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
26
-import com.sap.sse.security.shared.AdminRole;
27
-import com.sap.sse.security.shared.ServerAdminRole;
28
-import com.sap.sse.security.shared.dto.RoleWithSecurityDTO;
29
-import com.sap.sse.security.shared.dto.UserDTO;
30
-import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
26
+import com.sap.sse.security.shared.HasPermissions.DefaultActions;
27
+import com.sap.sse.security.shared.WildcardPermission;
28
+import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
31 29
import com.sap.sse.security.ui.client.UserService;
32 30
import com.sap.sse.security.ui.client.component.SelectedElementsCountingButton;
33 31
... ...
@@ -35,7 +33,6 @@ abstract class IPBlocklistTableWrapper
35 33
extends TableWrapper<IpToTimedLockDTO, RefreshableSelectionModel<IpToTimedLockDTO>> {
36 34
private final UserService userService;
37 35
private final LabeledAbstractFilterablePanel<IpToTimedLockDTO> filterField;
38
- private final ServerActions unlockAction;
39 36
private final String errorMessageOnDataFailureString;
40 37
41 38
protected abstract void fetchData(AsyncCallback<HashMap<String, TimedLock>> callback);
... ...
@@ -43,8 +40,8 @@ abstract class IPBlocklistTableWrapper
43 40
protected abstract void unlockIP(String ip, AsyncCallback<Void> asyncCallback);
44 41
45 42
public IPBlocklistTableWrapper(final SailingServiceWriteAsync sailingServiceWrite, final UserService userService,
46
- final ServerActions unlockAction, final String errorMessageOnDataFailureString,
47
- final StringMessages stringMessages, final ErrorReporter errorReporter) {
43
+ final String errorMessageOnDataFailureString, final StringMessages stringMessages,
44
+ final ErrorReporter errorReporter) {
48 45
super(sailingServiceWrite, stringMessages, errorReporter, true, true,
49 46
new EntityIdentityComparator<IpToTimedLockDTO>() {
50 47
@Override
... ...
@@ -57,7 +54,6 @@ abstract class IPBlocklistTableWrapper
57 54
return t.ip.hashCode();
58 55
}
59 56
});
60
- this.unlockAction = unlockAction;
61 57
this.userService = userService;
62 58
this.errorMessageOnDataFailureString = errorMessageOnDataFailureString;
63 59
this.filterField = composeFilterField();
... ...
@@ -81,26 +77,6 @@ abstract class IPBlocklistTableWrapper
81 77
mainPanel.setSpacing(5);
82 78
}
83 79
84
- // admin, server admin and those with the permission can all unlock
85
- private boolean canUnlock() {
86
- final UserDTO user = userService.getCurrentUser();
87
- final Iterable<RoleWithSecurityDTO> roles = user.getRoles();
88
- boolean isAdmin = false;
89
- boolean isServerAdmin = false;
90
- final boolean hasUnlockPermission = userService.hasServerPermission(unlockAction);
91
- for (RoleWithSecurityDTO role : roles) {
92
- isAdmin = role.getName().equals(AdminRole.getInstance().getName());
93
- if (isAdmin) {
94
- break;
95
- }
96
- isServerAdmin = role.getName().equals(ServerAdminRole.getInstance().getName());
97
- if (isServerAdmin) {
98
- break;
99
- }
100
- }
101
- return isAdmin || isServerAdmin || hasUnlockPermission;
102
- }
103
-
104 80
private Widget composeButtonPanel() {
105 81
final HorizontalPanel buttonPanel = new HorizontalPanel();
106 82
buttonPanel.setSpacing(5);
... ...
@@ -112,32 +88,42 @@ abstract class IPBlocklistTableWrapper
112 88
});
113 89
refreshButton.ensureDebugId("refreshButton");
114 90
buttonPanel.add(refreshButton);
115
- if (canUnlock()) {
116
- final Button unlockButton = new SelectedElementsCountingButton<IpToTimedLockDTO>(
117
- getStringMessages().unlock(), getSelectionModel(), new ClickHandler() {
118
- @Override
119
- public void onClick(ClickEvent event) {
120
- for (IpToTimedLockDTO e : getSelectionModel().getSelectedSet()) {
121
- unlockIP(e.ip, new AsyncCallback<Void>() {
122
- @Override
123
- public void onFailure(Throwable caught) {
124
- errorReporter.reportError(errorMessageOnDataFailureString);
125
- }
126
-
127
- @Override
128
- public void onSuccess(Void result) {
129
- filterField.remove(e);
130
- }
131
- });
132
- }
133
- }
134
- });
91
+ if (hasUnlockPermission()) {
92
+ final Button unlockButton = composeUnlockButton();
135 93
unlockButton.ensureDebugId("unlockButton");
136 94
buttonPanel.add(unlockButton);
137 95
}
138 96
return buttonPanel;
139 97
}
140 98
99
+ private boolean hasUnlockPermission() {
100
+ final WildcardPermission unlockIpPermission = SecuredSecurityTypes.LOCKED_IP
101
+ .getPermission(DefaultActions.DELETE);
102
+ return userService.hasPermission(unlockIpPermission, userService.getServerInfo().getOwnership());
103
+ }
104
+
105
+ private SelectedElementsCountingButton<IpToTimedLockDTO> composeUnlockButton() {
106
+ return new SelectedElementsCountingButton<IpToTimedLockDTO>(getStringMessages().unlock(), getSelectionModel(),
107
+ new ClickHandler() {
108
+ @Override
109
+ public void onClick(ClickEvent event) {
110
+ for (IpToTimedLockDTO e : getSelectionModel().getSelectedSet()) {
111
+ unlockIP(e.ip, new AsyncCallback<Void>() {
112
+ @Override
113
+ public void onFailure(Throwable caught) {
114
+ errorReporter.reportError(errorMessageOnDataFailureString);
115
+ }
116
+
117
+ @Override
118
+ public void onSuccess(Void result) {
119
+ filterField.remove(e);
120
+ }
121
+ });
122
+ }
123
+ }
124
+ });
125
+ }
126
+
141 127
private void loadDataAndPopulateTable() {
142 128
final AsyncCallback<HashMap<String, TimedLock>> dataInitializationCallback = new AsyncCallback<HashMap<String, TimedLock>>() {
143 129
@Override
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LocalServerManagementPanel.java
... ...
@@ -152,7 +152,6 @@ public class LocalServerManagementPanel extends SimplePanel {
152 152
3);
153 153
panel.ensureDebugId("bearerTokenAbusePanel");
154 154
final IPBlocklistTableWrapper table = new IPBlocklistTableWrapper(sailingService, userService,
155
- ServerActions.UNLOCK_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE,
156 155
stringMessages.unableToLoadIpsBlockedForBearerTokenAbuse(), stringMessages, errorReporter) {
157 156
@Override
158 157
protected void fetchData(AsyncCallback<HashMap<String, TimedLock>> callback) {
... ...
@@ -173,7 +172,6 @@ public class LocalServerManagementPanel extends SimplePanel {
173 172
3);
174 173
panel.ensureDebugId("userCreationAbusePanel");
175 174
final IPBlocklistTableWrapper table = new IPBlocklistTableWrapper(sailingService, userService,
176
- ServerActions.UNLOCK_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
177 175
stringMessages.unableToLoadIpsBlockedForUserCreationAbuse(), stringMessages, errorReporter) {
178 176
@Override
179 177
protected void fetchData(AsyncCallback<HashMap<String, TimedLock>> callback) {
java/com.sap.sse.security.common/src/com/sap/sse/security/shared/IPAddress.java
... ...
@@ -0,0 +1,28 @@
1
+package com.sap.sse.security.shared;
2
+
3
+import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
4
+
5
+public class IPAddress implements WithQualifiedObjectIdentifier {
6
+ private static final long serialVersionUID = 8016397230668484898L;
7
+ private final String ipAddress;
8
+
9
+ public IPAddress(final String ipAddress) {
10
+ this.ipAddress = ipAddress;
11
+ }
12
+
13
+ @Override
14
+ public String getName() {
15
+ return ipAddress;
16
+ }
17
+
18
+ @Override
19
+ public QualifiedObjectIdentifier getIdentifier() {
20
+ return getPermissionType().getQualifiedObjectIdentifier(new TypeRelativeObjectIdentifier(ipAddress));
21
+ }
22
+
23
+ @Override
24
+ public HasPermissions getPermissionType() {
25
+ return SecuredSecurityTypes.LOCKED_IP;
26
+ }
27
+
28
+}
java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecuredSecurityTypes.java
... ...
@@ -50,6 +50,12 @@ public class SecuredSecurityTypes extends HasPermissionsImpl {
50 50
.plus(UserActions.FORCE_OVERWRITE_PASSWORD, PublicReadableActions.READ_PUBLIC,
51 51
UserActions.ADD_SUBSCRIPTION, UserActions.BE_PREMIUM, UserActions.MANAGE_LOCK));
52 52
53
+
54
+ /**
55
+ * type-relative identifier is the {@link User#getName() ip}.
56
+ */
57
+ public static final HasPermissions LOCKED_IP = new SecuredSecurityTypes("LOCKED_IP", DefaultActions.values());
58
+
53 59
/**
54 60
* type-relative identifier is the {@link RoleDefinition#getId() role ID's} string representation
55 61
*/
... ...
@@ -75,12 +81,6 @@ public class SecuredSecurityTypes extends HasPermissionsImpl {
75 81
CONFIGURE_LOCAL_SERVER,
76 82
CONFIGURE_REMOTE_INSTANCES,
77 83
CREATE_OBJECT,
78
-
79
- GET_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
80
- GET_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE,
81
-
82
- UNLOCK_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
83
- UNLOCK_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE,
84 84
85 85
/**
86 86
* This permission is used to check READ-permission on different things. For that the object type to determine
... ...
@@ -118,9 +118,7 @@ public class SecuredSecurityTypes extends HasPermissionsImpl {
118 118
CONFIGURE_CORS_FILTER
119 119
;
120 120
121
- private static final Action[] ALL_ACTIONS = new Action[] { GET_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
122
- GET_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE, UNLOCK_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
123
- UNLOCK_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE, CONFIGURE_FILE_STORAGE, CONFIGURE_LOCAL_SERVER,
121
+ private static final Action[] ALL_ACTIONS = new Action[] { CONFIGURE_FILE_STORAGE, CONFIGURE_LOCAL_SERVER,
124 122
CONFIGURE_REMOTE_INSTANCES, CREATE_OBJECT, CAN_IMPORT_MASTERDATA, CAN_EXPORT_MASTERDATA, DATA_MINING,
125 123
REPLICATE, START_REPLICATION, READ_REPLICATOR, THREADS, CONFIGURE_AI_AGENT, CONFIGURE_CORS_FILTER,
126 124
DefaultActions.CHANGE_OWNERSHIP, DefaultActions.CHANGE_ACL, DefaultActions.CREATE,
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/UserManagementServiceImpl.java
... ...
@@ -35,6 +35,7 @@ import com.sap.sse.security.interfaces.Credential;
35 35
import com.sap.sse.security.shared.AccessControlListAnnotation;
36 36
import com.sap.sse.security.shared.HasPermissions;
37 37
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
38
+import com.sap.sse.security.shared.IPAddress;
38 39
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
39 40
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
40 41
import com.sap.sse.security.shared.UnauthorizedException;
... ...
@@ -418,16 +419,34 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
418 419
@Override
419 420
public HashMap<String, TimedLock> getClientIPBasedTimedLocksForUserCreation() throws UnauthorizedException {
420 421
final SecurityService securityService = getSecurityService();
421
- // throws UnauthorizedException if fails
422
- securityService.checkCurrentUserServerPermission(ServerActions.GET_IPS_BLOCKED_FOR_USER_CREATION_ABUSE);
423
- return securityService.getClientIPBasedTimedLocksForUserCreation();
422
+ final HashMap<String, TimedLock> ipToLockMap = securityService.getClientIPBasedTimedLocksForUserCreation();
423
+ // remove from Map, those where permission == FALSE
424
+ ipToLockMap.entrySet().forEach(ipToLockPair -> {
425
+ final String ip = ipToLockPair.getKey();
426
+ final WildcardPermission userReadPermissionOnIp = SecuredSecurityTypes.LOCKED_IP
427
+ .getPermissionForObject(DefaultActions.READ, new IPAddress(ip));
428
+ final boolean isPermitted = SecurityUtils.getSubject().isPermitted(userReadPermissionOnIp.toString());
429
+ if (!isPermitted) {
430
+ ipToLockMap.remove(ip);
431
+ }
432
+ });
433
+ return ipToLockMap;
424 434
}
425 435
426 436
@Override
427 437
public HashMap<String, TimedLock> getClientIPBasedTimedLocksForBearerTokenAbuse() throws UnauthorizedException {
428 438
final SecurityService securityService = getSecurityService();
429
- // throws UnauthorizedException if fails
430
- securityService.checkCurrentUserServerPermission(ServerActions.GET_IPS_BLOCKED_FOR_USER_CREATION_ABUSE);
431
- return securityService.getClientIPBasedTimedLocksForBearerTokenAbuse();
439
+ final HashMap<String, TimedLock> ipToLockMap = securityService.getClientIPBasedTimedLocksForBearerTokenAbuse();
440
+ // remove from Map, those where permission == FALSE
441
+ ipToLockMap.entrySet().forEach(ipToLockPair -> {
442
+ final String ip = ipToLockPair.getKey();
443
+ final WildcardPermission userReadPermissionOnIp = SecuredSecurityTypes.LOCKED_IP
444
+ .getPermissionForObject(DefaultActions.READ, new IPAddress(ip));
445
+ final boolean isPermitted = SecurityUtils.getSubject().isPermitted(userReadPermissionOnIp.toString());
446
+ if (!isPermitted) {
447
+ ipToLockMap.remove(ip);
448
+ }
449
+ });
450
+ return ipToLockMap;
432 451
}
433 452
}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/UserManagementWriteServiceImpl.java
... ...
@@ -23,6 +23,7 @@ import com.sap.sse.common.media.TakedownNoticeRequestContext;
23 23
import com.sap.sse.security.Action;
24 24
import com.sap.sse.security.SecurityService;
25 25
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
26
+import com.sap.sse.security.shared.IPAddress;
26 27
import com.sap.sse.security.shared.PermissionChecker;
27 28
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
28 29
import com.sap.sse.security.shared.RoleDefinition;
... ...
@@ -745,16 +746,20 @@ public class UserManagementWriteServiceImpl extends UserManagementServiceImpl im
745 746
@Override
746 747
public void releaseUserCreationLockOnIp(String ip) throws UnauthorizedException {
747 748
final SecurityService securityService = getSecurityService();
748
- // throws if permission not granted
749
- securityService.checkCurrentUserServerPermission(ServerActions.UNLOCK_IPS_BLOCKED_FOR_USER_CREATION_ABUSE);
749
+ final WildcardPermission userReadPermissionOnIp = SecuredSecurityTypes.LOCKED_IP
750
+ .getPermissionForObject(DefaultActions.DELETE, new IPAddress(ip));
751
+ // throws exception if not permitted
752
+ SecurityUtils.getSubject().checkPermission(userReadPermissionOnIp.toString());
750 753
securityService.releaseUserCreationLockOnIp(ip);
751 754
}
752 755
753 756
@Override
754 757
public void releaseBearerTokenLockOnIp(String ip) throws UnauthorizedException {
755 758
final SecurityService securityService = getSecurityService();
756
- // throws UnauthorizedException if fails
757
- securityService.checkCurrentUserServerPermission(ServerActions.UNLOCK_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE);
759
+ final WildcardPermission userReadPermissionOnIp = SecuredSecurityTypes.LOCKED_IP
760
+ .getPermissionForObject(DefaultActions.DELETE, new IPAddress(ip));
761
+ // throws exception if not permitted
762
+ SecurityUtils.getSubject().checkPermission(userReadPermissionOnIp.toString());
758 763
securityService.releaseBearerTokenLockOnIp(ip);
759 764
}
760 765
}