mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-04 10:09:42 +00:00
locked IPs turned into permission object instead of server action
Locked IPs were previously not treated as SecuredSecurityType, but rather their actions were treated as separate ServerAction instances with the object in question remaining the server. To maintain permission granularity at the IP address level, Locked IP addresses have been made HasPermissions object in SecuredSecurityType with DefaultActions READ and DELETE serving as get and unlock method permissions respectively that can now be treated as the object wildcard of permission triples.
This commit is contained in:
1 parent
89edd71d65
commit
8ca8dd20eb
6 files changed
+104
-70
No files matched your search
+35
-49
@@ -23,11 +23,9 @@ import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.celltable.EntityIdentityComparator;
|
||||
import com.sap.sse.gwt.client.celltable.RefreshableSelectionModel;
|
||||
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
|
||||
import com.sap.sse.security.shared.AdminRole;
|
||||
import com.sap.sse.security.shared.ServerAdminRole;
|
||||
import com.sap.sse.security.shared.dto.RoleWithSecurityDTO;
|
||||
import com.sap.sse.security.shared.dto.UserDTO;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
|
||||
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
|
||||
import com.sap.sse.security.ui.client.UserService;
|
||||
import com.sap.sse.security.ui.client.component.SelectedElementsCountingButton;
|
||||
|
||||
@@ -35,7 +33,6 @@ abstract class IPBlocklistTableWrapper
|
||||
extends TableWrapper<IpToTimedLockDTO, RefreshableSelectionModel<IpToTimedLockDTO>> {
|
||||
private final UserService userService;
|
||||
private final LabeledAbstractFilterablePanel<IpToTimedLockDTO> filterField;
|
||||
private final ServerActions unlockAction;
|
||||
private final String errorMessageOnDataFailureString;
|
||||
|
||||
protected abstract void fetchData(AsyncCallback<HashMap<String, TimedLock>> callback);
|
||||
@@ -43,8 +40,8 @@ abstract class IPBlocklistTableWrapper
|
||||
protected abstract void unlockIP(String ip, AsyncCallback<Void> asyncCallback);
|
||||
|
||||
public IPBlocklistTableWrapper(final SailingServiceWriteAsync sailingServiceWrite, final UserService userService,
|
||||
final ServerActions unlockAction, final String errorMessageOnDataFailureString,
|
||||
final StringMessages stringMessages, final ErrorReporter errorReporter) {
|
||||
final String errorMessageOnDataFailureString, final StringMessages stringMessages,
|
||||
final ErrorReporter errorReporter) {
|
||||
super(sailingServiceWrite, stringMessages, errorReporter, true, true,
|
||||
new EntityIdentityComparator<IpToTimedLockDTO>() {
|
||||
@Override
|
||||
@@ -57,7 +54,6 @@ abstract class IPBlocklistTableWrapper
|
||||
return t.ip.hashCode();
|
||||
}
|
||||
});
|
||||
this.unlockAction = unlockAction;
|
||||
this.userService = userService;
|
||||
this.errorMessageOnDataFailureString = errorMessageOnDataFailureString;
|
||||
this.filterField = composeFilterField();
|
||||
@@ -81,26 +77,6 @@ abstract class IPBlocklistTableWrapper
|
||||
mainPanel.setSpacing(5);
|
||||
}
|
||||
|
||||
// admin, server admin and those with the permission can all unlock
|
||||
private boolean canUnlock() {
|
||||
final UserDTO user = userService.getCurrentUser();
|
||||
final Iterable<RoleWithSecurityDTO> roles = user.getRoles();
|
||||
boolean isAdmin = false;
|
||||
boolean isServerAdmin = false;
|
||||
final boolean hasUnlockPermission = userService.hasServerPermission(unlockAction);
|
||||
for (RoleWithSecurityDTO role : roles) {
|
||||
isAdmin = role.getName().equals(AdminRole.getInstance().getName());
|
||||
if (isAdmin) {
|
||||
break;
|
||||
}
|
||||
isServerAdmin = role.getName().equals(ServerAdminRole.getInstance().getName());
|
||||
if (isServerAdmin) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isAdmin || isServerAdmin || hasUnlockPermission;
|
||||
}
|
||||
|
||||
private Widget composeButtonPanel() {
|
||||
final HorizontalPanel buttonPanel = new HorizontalPanel();
|
||||
buttonPanel.setSpacing(5);
|
||||
@@ -112,32 +88,42 @@ abstract class IPBlocklistTableWrapper
|
||||
});
|
||||
refreshButton.ensureDebugId("refreshButton");
|
||||
buttonPanel.add(refreshButton);
|
||||
if (canUnlock()) {
|
||||
final Button unlockButton = new SelectedElementsCountingButton<IpToTimedLockDTO>(
|
||||
getStringMessages().unlock(), getSelectionModel(), new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
for (IpToTimedLockDTO e : getSelectionModel().getSelectedSet()) {
|
||||
unlockIP(e.ip, new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
errorReporter.reportError(errorMessageOnDataFailureString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
filterField.remove(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
if (hasUnlockPermission()) {
|
||||
final Button unlockButton = composeUnlockButton();
|
||||
unlockButton.ensureDebugId("unlockButton");
|
||||
buttonPanel.add(unlockButton);
|
||||
}
|
||||
return buttonPanel;
|
||||
}
|
||||
|
||||
private boolean hasUnlockPermission() {
|
||||
final WildcardPermission unlockIpPermission = SecuredSecurityTypes.LOCKED_IP
|
||||
.getPermission(DefaultActions.DELETE);
|
||||
return userService.hasPermission(unlockIpPermission, userService.getServerInfo().getOwnership());
|
||||
}
|
||||
|
||||
private SelectedElementsCountingButton<IpToTimedLockDTO> composeUnlockButton() {
|
||||
return new SelectedElementsCountingButton<IpToTimedLockDTO>(getStringMessages().unlock(), getSelectionModel(),
|
||||
new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
for (IpToTimedLockDTO e : getSelectionModel().getSelectedSet()) {
|
||||
unlockIP(e.ip, new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
errorReporter.reportError(errorMessageOnDataFailureString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
filterField.remove(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadDataAndPopulateTable() {
|
||||
final AsyncCallback<HashMap<String, TimedLock>> dataInitializationCallback = new AsyncCallback<HashMap<String, TimedLock>>() {
|
||||
@Override
|
||||
|
||||
-2
@@ -152,7 +152,6 @@ public class LocalServerManagementPanel extends SimplePanel {
|
||||
3);
|
||||
panel.ensureDebugId("bearerTokenAbusePanel");
|
||||
final IPBlocklistTableWrapper table = new IPBlocklistTableWrapper(sailingService, userService,
|
||||
ServerActions.UNLOCK_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE,
|
||||
stringMessages.unableToLoadIpsBlockedForBearerTokenAbuse(), stringMessages, errorReporter) {
|
||||
@Override
|
||||
protected void fetchData(AsyncCallback<HashMap<String, TimedLock>> callback) {
|
||||
@@ -173,7 +172,6 @@ public class LocalServerManagementPanel extends SimplePanel {
|
||||
3);
|
||||
panel.ensureDebugId("userCreationAbusePanel");
|
||||
final IPBlocklistTableWrapper table = new IPBlocklistTableWrapper(sailingService, userService,
|
||||
ServerActions.UNLOCK_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
|
||||
stringMessages.unableToLoadIpsBlockedForUserCreationAbuse(), stringMessages, errorReporter) {
|
||||
@Override
|
||||
protected void fetchData(AsyncCallback<HashMap<String, TimedLock>> callback) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.sap.sse.security.shared;
|
||||
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
|
||||
|
||||
public class IPAddress implements WithQualifiedObjectIdentifier {
|
||||
private static final long serialVersionUID = 8016397230668484898L;
|
||||
private final String ipAddress;
|
||||
|
||||
public IPAddress(final String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QualifiedObjectIdentifier getIdentifier() {
|
||||
return getPermissionType().getQualifiedObjectIdentifier(new TypeRelativeObjectIdentifier(ipAddress));
|
||||
}
|
||||
|
||||
@Override
|
||||
public HasPermissions getPermissionType() {
|
||||
return SecuredSecurityTypes.LOCKED_IP;
|
||||
}
|
||||
|
||||
}
|
||||
+7
-9
@@ -50,6 +50,12 @@ public class SecuredSecurityTypes extends HasPermissionsImpl {
|
||||
.plus(UserActions.FORCE_OVERWRITE_PASSWORD, PublicReadableActions.READ_PUBLIC,
|
||||
UserActions.ADD_SUBSCRIPTION, UserActions.BE_PREMIUM, UserActions.MANAGE_LOCK));
|
||||
|
||||
|
||||
/**
|
||||
* type-relative identifier is the {@link User#getName() ip}.
|
||||
*/
|
||||
public static final HasPermissions LOCKED_IP = new SecuredSecurityTypes("LOCKED_IP", DefaultActions.values());
|
||||
|
||||
/**
|
||||
* type-relative identifier is the {@link RoleDefinition#getId() role ID's} string representation
|
||||
*/
|
||||
@@ -75,12 +81,6 @@ public class SecuredSecurityTypes extends HasPermissionsImpl {
|
||||
CONFIGURE_LOCAL_SERVER,
|
||||
CONFIGURE_REMOTE_INSTANCES,
|
||||
CREATE_OBJECT,
|
||||
|
||||
GET_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
|
||||
GET_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE,
|
||||
|
||||
UNLOCK_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
|
||||
UNLOCK_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE,
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
CONFIGURE_CORS_FILTER
|
||||
;
|
||||
|
||||
private static final Action[] ALL_ACTIONS = new Action[] { GET_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
|
||||
GET_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE, UNLOCK_IPS_BLOCKED_FOR_USER_CREATION_ABUSE,
|
||||
UNLOCK_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE, CONFIGURE_FILE_STORAGE, CONFIGURE_LOCAL_SERVER,
|
||||
private static final Action[] ALL_ACTIONS = new Action[] { CONFIGURE_FILE_STORAGE, CONFIGURE_LOCAL_SERVER,
|
||||
CONFIGURE_REMOTE_INSTANCES, CREATE_OBJECT, CAN_IMPORT_MASTERDATA, CAN_EXPORT_MASTERDATA, DATA_MINING,
|
||||
REPLICATE, START_REPLICATION, READ_REPLICATOR, THREADS, CONFIGURE_AI_AGENT, CONFIGURE_CORS_FILTER,
|
||||
DefaultActions.CHANGE_OWNERSHIP, DefaultActions.CHANGE_ACL, DefaultActions.CREATE,
|
||||
|
||||
+25
-6
@@ -35,6 +35,7 @@ import com.sap.sse.security.interfaces.Credential;
|
||||
import com.sap.sse.security.shared.AccessControlListAnnotation;
|
||||
import com.sap.sse.security.shared.HasPermissions;
|
||||
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
|
||||
import com.sap.sse.security.shared.IPAddress;
|
||||
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
|
||||
import com.sap.sse.security.shared.UnauthorizedException;
|
||||
@@ -418,16 +419,34 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
|
||||
@Override
|
||||
public HashMap<String, TimedLock> getClientIPBasedTimedLocksForUserCreation() throws UnauthorizedException {
|
||||
final SecurityService securityService = getSecurityService();
|
||||
// throws UnauthorizedException if fails
|
||||
securityService.checkCurrentUserServerPermission(ServerActions.GET_IPS_BLOCKED_FOR_USER_CREATION_ABUSE);
|
||||
return securityService.getClientIPBasedTimedLocksForUserCreation();
|
||||
final HashMap<String, TimedLock> ipToLockMap = securityService.getClientIPBasedTimedLocksForUserCreation();
|
||||
// remove from Map, those where permission == FALSE
|
||||
ipToLockMap.entrySet().forEach(ipToLockPair -> {
|
||||
final String ip = ipToLockPair.getKey();
|
||||
final WildcardPermission userReadPermissionOnIp = SecuredSecurityTypes.LOCKED_IP
|
||||
.getPermissionForObject(DefaultActions.READ, new IPAddress(ip));
|
||||
final boolean isPermitted = SecurityUtils.getSubject().isPermitted(userReadPermissionOnIp.toString());
|
||||
if (!isPermitted) {
|
||||
ipToLockMap.remove(ip);
|
||||
}
|
||||
});
|
||||
return ipToLockMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, TimedLock> getClientIPBasedTimedLocksForBearerTokenAbuse() throws UnauthorizedException {
|
||||
final SecurityService securityService = getSecurityService();
|
||||
// throws UnauthorizedException if fails
|
||||
securityService.checkCurrentUserServerPermission(ServerActions.GET_IPS_BLOCKED_FOR_USER_CREATION_ABUSE);
|
||||
return securityService.getClientIPBasedTimedLocksForBearerTokenAbuse();
|
||||
final HashMap<String, TimedLock> ipToLockMap = securityService.getClientIPBasedTimedLocksForBearerTokenAbuse();
|
||||
// remove from Map, those where permission == FALSE
|
||||
ipToLockMap.entrySet().forEach(ipToLockPair -> {
|
||||
final String ip = ipToLockPair.getKey();
|
||||
final WildcardPermission userReadPermissionOnIp = SecuredSecurityTypes.LOCKED_IP
|
||||
.getPermissionForObject(DefaultActions.READ, new IPAddress(ip));
|
||||
final boolean isPermitted = SecurityUtils.getSubject().isPermitted(userReadPermissionOnIp.toString());
|
||||
if (!isPermitted) {
|
||||
ipToLockMap.remove(ip);
|
||||
}
|
||||
});
|
||||
return ipToLockMap;
|
||||
}
|
||||
}
|
||||
+9
-4
@@ -23,6 +23,7 @@ import com.sap.sse.common.media.TakedownNoticeRequestContext;
|
||||
import com.sap.sse.security.Action;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
|
||||
import com.sap.sse.security.shared.IPAddress;
|
||||
import com.sap.sse.security.shared.PermissionChecker;
|
||||
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.RoleDefinition;
|
||||
@@ -745,16 +746,20 @@ public class UserManagementWriteServiceImpl extends UserManagementServiceImpl im
|
||||
@Override
|
||||
public void releaseUserCreationLockOnIp(String ip) throws UnauthorizedException {
|
||||
final SecurityService securityService = getSecurityService();
|
||||
// throws if permission not granted
|
||||
securityService.checkCurrentUserServerPermission(ServerActions.UNLOCK_IPS_BLOCKED_FOR_USER_CREATION_ABUSE);
|
||||
final WildcardPermission userReadPermissionOnIp = SecuredSecurityTypes.LOCKED_IP
|
||||
.getPermissionForObject(DefaultActions.DELETE, new IPAddress(ip));
|
||||
// throws exception if not permitted
|
||||
SecurityUtils.getSubject().checkPermission(userReadPermissionOnIp.toString());
|
||||
securityService.releaseUserCreationLockOnIp(ip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseBearerTokenLockOnIp(String ip) throws UnauthorizedException {
|
||||
final SecurityService securityService = getSecurityService();
|
||||
// throws UnauthorizedException if fails
|
||||
securityService.checkCurrentUserServerPermission(ServerActions.UNLOCK_IPS_BLOCKED_FOR_BEARER_TOKEN_ABUSE);
|
||||
final WildcardPermission userReadPermissionOnIp = SecuredSecurityTypes.LOCKED_IP
|
||||
.getPermissionForObject(DefaultActions.DELETE, new IPAddress(ip));
|
||||
// throws exception if not permitted
|
||||
SecurityUtils.getSubject().checkPermission(userReadPermissionOnIp.toString());
|
||||
securityService.releaseBearerTokenLockOnIp(ip);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user