mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-17 11:19:15 +00:00
added unlock button per user
also renamed LockingAndBanning to TImedLock
This commit is contained in:
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
@@ -22,7 +22,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
subjectDAO = com.sap.sse.security.NoSessionStorageForUnauthenticatedSessionsSessionDAO
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
+2
-2
@@ -51,7 +51,7 @@ import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.interfaces.UserStore;
|
||||
import com.sap.sse.security.shared.UserGroupManagementException;
|
||||
import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
import com.sap.sse.security.userstore.mongodb.UserStoreImpl;
|
||||
@@ -111,7 +111,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
|
||||
UserStore userStore = new UserStoreImpl("defaultTenant");
|
||||
userStore.clear();
|
||||
UserGroup defaultTenant = userStore.createUserGroup(UUID.randomUUID(), "admin"+SecurityService.TENANT_SUFFIX);
|
||||
User user = userStore.createUser("admin", "", new LockingAndBanningImpl());
|
||||
User user = userStore.createUser("admin", "", new TimedLockImpl());
|
||||
defaultTenant.add(user);
|
||||
userStore.updateUserGroup(defaultTenant);
|
||||
user.getDefaultTenantMap().put("testserver", defaultTenant);
|
||||
|
||||
@@ -22,7 +22,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
subjectDAO = com.sap.sse.security.NoSessionStorageForUnauthenticatedSessionsSessionDAO
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
@@ -24,7 +24,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
subjectDAO = com.sap.sse.security.NoSessionStorageForUnauthenticatedSessionsSessionDAO
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
@@ -32,7 +32,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Authentication Filter Configurations
|
||||
|
||||
+3
-3
@@ -53,7 +53,7 @@ import com.sap.sse.rest.StreamingOutputUtil;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.interfaces.UserImpl;
|
||||
import com.sap.sse.security.shared.Account;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
|
||||
public class RegattasResourceTest extends AbstractJaxRsApiTest {
|
||||
@@ -160,7 +160,7 @@ public class RegattasResourceTest extends AbstractJaxRsApiTest {
|
||||
public void testCompetitorRegistrationByAdmin() throws Exception {
|
||||
doReturn(securityService).when(regattasResource).getService(SecurityService.class);
|
||||
doReturn(true).when(securityService).hasCurrentUserUpdatePermission(Mockito.any());
|
||||
User user = new UserImpl("admin", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null, new LockingAndBanningImpl());
|
||||
User user = new UserImpl("admin", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null, new TimedLockImpl());
|
||||
setUser(user);
|
||||
when(securityService.getCurrentUser()).thenReturn(user);
|
||||
Response response = regattasResource.createAndAddCompetitor(closedRegattaName, boatClassName, null, "GER",
|
||||
@@ -218,7 +218,7 @@ public class RegattasResourceTest extends AbstractJaxRsApiTest {
|
||||
@Test
|
||||
public void testCompetitorRegistrationAuthenticatedOnOpenRegatta() throws Exception {
|
||||
doReturn(securityService).when(regattasResource).getService(SecurityService.class);
|
||||
User user = new UserImpl("max", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null, new LockingAndBanningImpl());
|
||||
User user = new UserImpl("max", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null, new TimedLockImpl());
|
||||
setUser(user);
|
||||
Regatta regatta = racingEventService.getRegattaByName(openRegattaName);
|
||||
Response response = regattasResource.createAndAddCompetitor(openRegattaName, boatClassName, null, "GER", "#F00",
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
+2
-2
@@ -64,7 +64,7 @@ import com.sap.sse.replication.FullyInitializedReplicableTracker;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.interfaces.UserImpl;
|
||||
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.PublicReadableActions;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
@@ -248,7 +248,7 @@ public class MediaReplicationTest extends AbstractServerReplicationTest {
|
||||
@Test
|
||||
public void testMasterDataImportForMediaTracks() throws Exception {
|
||||
UserGroupImpl defaultTenant = new UserGroupImpl(new UUID(0, 1), "defaultTenant");
|
||||
User currentUser = new UserImpl("test", "email@test", Collections.emptyMap(), null, new LockingAndBanningImpl());
|
||||
User currentUser = new UserImpl("test", "email@test", Collections.emptyMap(), null, new TimedLockImpl());
|
||||
SecurityService securityService = Mockito.mock(SecurityService.class);
|
||||
Mockito.doReturn(defaultTenant).when(securityService).getServerGroup();
|
||||
Mockito.doReturn(currentUser).when(securityService).getCurrentUser();
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 381 B |
@@ -11,6 +11,9 @@ public interface IconResources extends ClientBundle {
|
||||
@Source("images/change-acl.png")
|
||||
ImageResource changeACLIcon();
|
||||
|
||||
@Source("images/unlock.png")
|
||||
ImageResource resetLockIcon();
|
||||
|
||||
@Source("images/change-ownership.png")
|
||||
ImageResource changeOwnershipIcon();
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ import java.util.UUID;
|
||||
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
|
||||
@@ -60,7 +60,7 @@ public interface BasicUserStore extends UserGroupProvider, Named {
|
||||
|
||||
User getUserByAccessToken(String accessToken);
|
||||
|
||||
User createUser(String name, String email, LockingAndBanning lockingAndBanning, Account... accounts)
|
||||
User createUser(String name, String email, TimedLock timedLock, Account... accounts)
|
||||
throws UserManagementException;
|
||||
|
||||
void addUser(User user) throws UserManagementException;
|
||||
|
||||
+1
-1
@@ -136,7 +136,7 @@ public interface HasPermissions extends Named {
|
||||
*
|
||||
*/
|
||||
public enum DefaultActions implements Action {
|
||||
CREATE, READ, UPDATE, DELETE, CHANGE_OWNERSHIP, CHANGE_ACL;
|
||||
CREATE, READ, UPDATE, DELETE, CHANGE_OWNERSHIP, CHANGE_ACL, MANAGE_LOCK;
|
||||
|
||||
public static final Action[] MUTATION_ACTIONS = new Action[] { CREATE, UPDATE, DELETE, CHANGE_OWNERSHIP,
|
||||
CHANGE_ACL };
|
||||
|
||||
+6
-6
@@ -10,8 +10,8 @@ import com.sap.sse.common.TimePoint;
|
||||
* <p>
|
||||
*
|
||||
* For example, failed password authentication requests shall be logged by the realm using calls to
|
||||
* {@link #failedPasswordAuthentication()}, successful ones with {@link #successfulPasswordAuthentication()}. Using the
|
||||
* {@link #isAuthenticationLocked()} method, a realm can determine if the user account to which this object belongs
|
||||
* {@link #extendLockDuration()}, successful ones with {@link #resetLock()}. Using the
|
||||
* {@link #isLocked()} method, a realm can determine if the user account to which this object belongs
|
||||
* shall currently accept password authentication.
|
||||
* <p>
|
||||
*
|
||||
@@ -21,15 +21,15 @@ import com.sap.sse.common.TimePoint;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface LockingAndBanning extends Serializable {
|
||||
void failedPasswordAuthentication();
|
||||
public interface TimedLock extends Serializable {
|
||||
void extendLockDuration();
|
||||
|
||||
/**
|
||||
* @return {@code true} if this locking and banning record changed due to this call
|
||||
*/
|
||||
boolean successfulPasswordAuthentication();
|
||||
boolean resetLock();
|
||||
|
||||
boolean isAuthenticationLocked();
|
||||
boolean isLocked();
|
||||
|
||||
TimePoint getLockedUntil();
|
||||
}
|
||||
+9
-9
@@ -4,31 +4,31 @@ import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class LockingAndBanningImpl implements LockingAndBanning {
|
||||
public class TimedLockImpl implements TimedLock {
|
||||
private static final long serialVersionUID = 3547356744366236677L;
|
||||
|
||||
public static final Duration DEFAULT_INITIAL_LOCKING_DELAY = Duration.ONE_SECOND;
|
||||
|
||||
/**
|
||||
* An always valid time point which may be in the past. If it is in the future,
|
||||
* {@link #isAuthenticationLocked()} will return {@code true}.
|
||||
* {@link #isLocked()} will return {@code true}.
|
||||
*/
|
||||
private TimePoint lockedUntil;
|
||||
|
||||
/**
|
||||
* An always valid, non-zero duration that indicates for how long into the future the {@link #lockedUntil} time
|
||||
* point will be set in case a {@link #failedPasswordAuthentication() failed password authentication} is notified.
|
||||
* point will be set in case a {@link #extendLockDuration() failed password authentication} is notified.
|
||||
*/
|
||||
private Duration nextLockingDelay;
|
||||
|
||||
/**
|
||||
* Creates an instance that is unlocked and has a "last locking delay" of one second
|
||||
*/
|
||||
public LockingAndBanningImpl() {
|
||||
public TimedLockImpl() {
|
||||
this(TimePoint.BeginningOfTime, DEFAULT_INITIAL_LOCKING_DELAY);
|
||||
}
|
||||
|
||||
public LockingAndBanningImpl(TimePoint lockedUntil, Duration nextLockingDelay) {
|
||||
public TimedLockImpl(TimePoint lockedUntil, Duration nextLockingDelay) {
|
||||
super();
|
||||
this.lockedUntil = lockedUntil;
|
||||
this.nextLockingDelay = nextLockingDelay;
|
||||
@@ -38,13 +38,13 @@ public class LockingAndBanningImpl implements LockingAndBanning {
|
||||
* Locks for the {@link #nextLockingDelay} and doubles the delay for the next failed attempt.
|
||||
*/
|
||||
@Override
|
||||
public void failedPasswordAuthentication() {
|
||||
public void extendLockDuration() {
|
||||
lockedUntil = TimePoint.now().plus(nextLockingDelay);
|
||||
nextLockingDelay = nextLockingDelay.times(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean successfulPasswordAuthentication() {
|
||||
public boolean resetLock() {
|
||||
final Duration oldLockingDelay = nextLockingDelay;
|
||||
nextLockingDelay = DEFAULT_INITIAL_LOCKING_DELAY;
|
||||
final TimePoint oldLockedUntil = lockedUntil;
|
||||
@@ -53,7 +53,7 @@ public class LockingAndBanningImpl implements LockingAndBanning {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthenticationLocked() {
|
||||
public boolean isLocked() {
|
||||
return TimePoint.now().before(lockedUntil);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class LockingAndBanningImpl implements LockingAndBanning {
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
if (isAuthenticationLocked()) {
|
||||
if (isLocked()) {
|
||||
result.append("locked until ");
|
||||
result.append(getLockedUntil());
|
||||
} else {
|
||||
@@ -125,5 +125,5 @@ public interface User extends SecurityUser<RoleDefinition, Role, UserGroup> {
|
||||
|
||||
Subscription getSubscriptionById(String subscriptionId);
|
||||
|
||||
LockingAndBanning getLockingAndBanning();
|
||||
TimedLock getTimedLock();
|
||||
}
|
||||
|
||||
+10
-10
@@ -24,7 +24,7 @@ import com.sap.sse.security.shared.Account.AccountType;
|
||||
import com.sap.sse.security.shared.RoleDefinition;
|
||||
import com.sap.sse.security.shared.UserGroupProvider;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.SecurityUserImpl;
|
||||
@@ -101,25 +101,25 @@ public class UserImpl extends SecurityUserImpl<RoleDefinition, Role, UserGroup,
|
||||
|
||||
private Subscription[] subscriptions;
|
||||
|
||||
private final LockingAndBanning lockingAndBanning;
|
||||
private final TimedLock timedLock;
|
||||
|
||||
public UserImpl(String name, String email, Map<String, UserGroup> defaultTenantForServer,
|
||||
UserGroupProvider userGroupProvider, LockingAndBanning lockingAndBanning, Account... accounts) {
|
||||
this(name, email, defaultTenantForServer, Arrays.asList(accounts), userGroupProvider, lockingAndBanning);
|
||||
UserGroupProvider userGroupProvider, TimedLock timedLock, Account... accounts) {
|
||||
this(name, email, defaultTenantForServer, Arrays.asList(accounts), userGroupProvider, timedLock);
|
||||
}
|
||||
|
||||
public UserImpl(String name, String email, Map<String, UserGroup> defaultTenantForServer,
|
||||
Collection<Account> accounts, UserGroupProvider userGroupProvider, LockingAndBanning lockingAndBanning) {
|
||||
Collection<Account> accounts, UserGroupProvider userGroupProvider, TimedLock timedLock) {
|
||||
this(name, email, /* fullName */ null, /* company */ null, /* locale */ null, /* is email validated */ false,
|
||||
/* password reset secret */ null, /* validation secret */ null, defaultTenantForServer, accounts,
|
||||
userGroupProvider, lockingAndBanning);
|
||||
userGroupProvider, timedLock);
|
||||
}
|
||||
|
||||
public UserImpl(String name, String email, String fullName, String company, Locale locale, Boolean emailValidated,
|
||||
String passwordResetSecret, String validationSecret, Map<String, UserGroup> defaultTenantForServer,
|
||||
Collection<Account> accounts, UserGroupProvider userGroupProvider, LockingAndBanning lockingAndBanning) {
|
||||
Collection<Account> accounts, UserGroupProvider userGroupProvider, TimedLock timedLock) {
|
||||
super(name);
|
||||
this.lockingAndBanning = lockingAndBanning;
|
||||
this.timedLock = timedLock;
|
||||
this.defaultTenantForServer = defaultTenantForServer;
|
||||
this.fullName = fullName;
|
||||
this.company = company;
|
||||
@@ -469,7 +469,7 @@ public class UserImpl extends SecurityUserImpl<RoleDefinition, Role, UserGroup,
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingAndBanning getLockingAndBanning() {
|
||||
return lockingAndBanning;
|
||||
public TimedLock getTimedLock() {
|
||||
return timedLock;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public class SimpleSecurityReplicationTest extends AbstractSecurityReplicationTe
|
||||
assertEquals(ERNIE, replicatedErnie.getName());
|
||||
assertFalse(replica.checkPassword(ERNIE, BERT_MY_FRIEND));
|
||||
// checking with incorrect password locks user for some time; wait long enough before retrying with correct password
|
||||
final TimePoint lockedUntil = replicatedErnie.getLockingAndBanning().getLockedUntil();
|
||||
final TimePoint lockedUntil = replicatedErnie.getTimedLock().getLockedUntil();
|
||||
Thread.sleep(Math.max(0, TimePoint.now().until(lockedUntil).asMillis()+10));
|
||||
assertTrue(replica.checkPassword(ERNIE, newPassword));
|
||||
}
|
||||
|
||||
+4
-4
@@ -12,7 +12,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.interfaces.UserImpl;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
import com.sap.sse.security.shared.impl.UserGroupImpl;
|
||||
@@ -51,7 +51,7 @@ public class TestGroupIdentity {
|
||||
final UUID uuid2 = UUID.randomUUID();
|
||||
final String username = "user";
|
||||
final UserGroup g1 = new UserGroupImpl(uuid1, username+SecurityService.TENANT_SUFFIX);
|
||||
final User user = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new LockingAndBanningImpl());
|
||||
final User user = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new TimedLockImpl());
|
||||
g1.add(user);
|
||||
final UserGroup g2 = new UserGroupImpl(uuid2, username+SecurityService.TENANT_SUFFIX);
|
||||
assertFalse(SecurityStoreMerger.considerGroupsIdentical(g1, g2, Collections.emptyMap()));
|
||||
@@ -63,10 +63,10 @@ public class TestGroupIdentity {
|
||||
final UUID uuid2 = UUID.randomUUID();
|
||||
final String username = "user";
|
||||
final UserGroup g1 = new UserGroupImpl(uuid1, username+SecurityService.TENANT_SUFFIX);
|
||||
final User user1 = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new LockingAndBanningImpl());
|
||||
final User user1 = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new TimedLockImpl());
|
||||
g1.add(user1);
|
||||
final UserGroup g2 = new UserGroupImpl(uuid2, username+SecurityService.TENANT_SUFFIX);
|
||||
final User user2 = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new LockingAndBanningImpl());
|
||||
final User user2 = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new TimedLockImpl());
|
||||
g2.add(user2);
|
||||
final Map<User, User> userMap = new HashMap<>();
|
||||
userMap.put(user2, user1); // user2 assumed to get merged with user1
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
|
||||
import com.sap.sse.security.shared.UserGroupManagementException;
|
||||
import com.sap.sse.security.shared.UserStoreManagementException;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.QualifiedObjectIdentifierImpl;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
@@ -69,7 +69,7 @@ public class AccessControlStoreTest {
|
||||
Map<String, UserGroup> defaultTenantForUser = new HashMap<>();
|
||||
defaultTenantForUser.put("dummyServer", adminTenant);
|
||||
testOwner = new UserImpl("admin", "admin@sapsailing.com", defaultTenantForUser,
|
||||
/* userGroupProvider */ null, new LockingAndBanningImpl());
|
||||
/* userGroupProvider */ null, new TimedLockImpl());
|
||||
}
|
||||
|
||||
private void newStores() {
|
||||
|
||||
@@ -44,7 +44,7 @@ import com.sap.sse.security.shared.UserStoreManagementException;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.impl.AccessControlList;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.QualifiedObjectIdentifierImpl;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
@@ -242,7 +242,7 @@ public class LoginTest {
|
||||
|
||||
@Test
|
||||
public void rolesTest() throws UserStoreManagementException {
|
||||
userStore.createUser("me", "me@sap.com", new LockingAndBanningImpl());
|
||||
userStore.createUser("me", "me@sap.com", new TimedLockImpl());
|
||||
RoleDefinition testRoleDefinition = userStore.createRoleDefinition(UUID.randomUUID(), "testRole",
|
||||
Collections.emptySet());
|
||||
final Role testRole = new Role(testRoleDefinition, true);
|
||||
@@ -254,7 +254,7 @@ public class LoginTest {
|
||||
@Test
|
||||
public void roleWithQualifiersTest() throws UserStoreManagementException {
|
||||
UserGroupImpl userDefaultTenant = userStore.createUserGroup(UUID.randomUUID(), "me-tenant");
|
||||
User meUser = userStore.createUser("me", "me@sap.com", new LockingAndBanningImpl());
|
||||
User meUser = userStore.createUser("me", "me@sap.com", new TimedLockImpl());
|
||||
RoleDefinition testRoleDefinition = userStore.createRoleDefinition(UUID.randomUUID(), "testRole",
|
||||
Collections.emptySet());
|
||||
final Role testRole = new Role(testRoleDefinition, userDefaultTenant, meUser, true);
|
||||
@@ -268,7 +268,7 @@ public class LoginTest {
|
||||
|
||||
@Test
|
||||
public void permissionsTest() throws UserStoreManagementException {
|
||||
userStore.createUser("me", "me@sap.com", new LockingAndBanningImpl());
|
||||
userStore.createUser("me", "me@sap.com", new TimedLockImpl());
|
||||
userStore.addPermissionForUser("me", new WildcardPermission("a:b:c"));
|
||||
UserStoreImpl store2 = createAndLoadUserStore();
|
||||
User allUser = userStore.getUserByName(SecurityService.ALL_USERNAME);
|
||||
|
||||
+2
-2
@@ -39,7 +39,7 @@ import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.AccessControlList;
|
||||
import com.sap.sse.security.shared.impl.HasPermissionsImpl;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
@@ -94,7 +94,7 @@ public class PermissionCheckerTest {
|
||||
userStore.deleteUser("jonas");
|
||||
}
|
||||
userTenant = userStore.createUserGroup(userTenantId, "jonas-tenant");
|
||||
user = userStore.createUser("jonas", "jonas@dann.io", new LockingAndBanningImpl());
|
||||
user = userStore.createUser("jonas", "jonas@dann.io", new TimedLockImpl());
|
||||
userTenant.add(user);
|
||||
userStore.updateUserGroup(userTenant);
|
||||
ownership = new Ownership(user, userTenant);
|
||||
|
||||
+6
-6
@@ -25,7 +25,7 @@ import com.sap.sse.security.interfaces.UserImpl;
|
||||
import com.sap.sse.security.interfaces.UserStore;
|
||||
import com.sap.sse.security.shared.UserGroupManagementException;
|
||||
import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
import com.sap.sse.security.userstore.mongodb.UserStoreImpl;
|
||||
@@ -191,7 +191,7 @@ public class PreferenceObjectBasedNotificationSetTest {
|
||||
|
||||
@Test
|
||||
public void userWithNonVerifiedEmailIsSkippedTest() throws UserManagementException, UserGroupManagementException {
|
||||
store.createUser(user1, mail, new LockingAndBanningImpl());
|
||||
store.createUser(user1, mail, new TimedLockImpl());
|
||||
store.registerPreferenceConverter(prefKey, prefConverter);
|
||||
store.setPreferenceObject(user1, prefKey, values1);
|
||||
PreferenceObjectBasedNotificationSetImpl notificationSet = new PreferenceObjectBasedNotificationSetImpl(prefKey, store);
|
||||
@@ -238,7 +238,7 @@ public class PreferenceObjectBasedNotificationSetTest {
|
||||
*/
|
||||
@Test
|
||||
public void deleteUserWithMappingTest() throws UserManagementException, UserGroupManagementException {
|
||||
store.createUser(user1, mail, new LockingAndBanningImpl());
|
||||
store.createUser(user1, mail, new TimedLockImpl());
|
||||
store.registerPreferenceConverter(prefKey, prefConverter);
|
||||
store.setPreferenceObject(user1, prefKey, values1);
|
||||
PreferenceObjectBasedNotificationSetImpl notificationSet = new PreferenceObjectBasedNotificationSetImpl(prefKey, store);
|
||||
@@ -250,7 +250,7 @@ public class PreferenceObjectBasedNotificationSetTest {
|
||||
|
||||
@Test
|
||||
public void removePreferenceConverterTest() throws UserManagementException, UserGroupManagementException {
|
||||
store.createUser(user1, mail, new LockingAndBanningImpl());
|
||||
store.createUser(user1, mail, new TimedLockImpl());
|
||||
store.registerPreferenceConverter(prefKey, prefConverter);
|
||||
store.setPreferenceObject(user1, prefKey, values1);
|
||||
PreferenceObjectBasedNotificationSetImpl notificationSet = new PreferenceObjectBasedNotificationSetImpl(prefKey, store);
|
||||
@@ -272,9 +272,9 @@ public class PreferenceObjectBasedNotificationSetTest {
|
||||
UserGroup defaultTenantForSingleServer = store.createUserGroup(UUID.randomUUID(), username + "-tenant");
|
||||
Map<String, UserGroup> defaultTenantForServer = new ConcurrentHashMap<>();
|
||||
defaultTenantForServer.put(serverName, defaultTenantForSingleServer);
|
||||
store.createUser(username, email, new LockingAndBanningImpl());
|
||||
store.createUser(username, email, new TimedLockImpl());
|
||||
store.updateUser(new UserImpl(username, email, null, null, null, true, null, null, defaultTenantForServer,
|
||||
Collections.emptySet(), /* userGroupProvider */ null, new LockingAndBanningImpl()));
|
||||
Collections.emptySet(), /* userGroupProvider */ null, new TimedLockImpl()));
|
||||
}
|
||||
|
||||
private static class PreferenceObjectBasedNotificationSetImpl extends PreferenceObjectBasedNotificationSet<HashSet<String>, String> {
|
||||
|
||||
+3
-3
@@ -26,7 +26,7 @@ import com.sap.sse.security.shared.UserStoreManagementException;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.AccessControlList;
|
||||
import com.sap.sse.security.shared.impl.HasPermissionsImpl;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
|
||||
@@ -65,8 +65,8 @@ public class PrivilegeEscalationTest {
|
||||
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), TEST_DEFAULT_TENANT);
|
||||
userStore.ensureDefaultRolesExist();
|
||||
userStore.loadAndMigrateUsers();
|
||||
user = userStore.createUser(USER_USERNAME, null, new LockingAndBanningImpl());
|
||||
user2 = userStore.createUser(USER2_USERNAME, null, new LockingAndBanningImpl());
|
||||
user = userStore.createUser(USER_USERNAME, null, new TimedLockImpl());
|
||||
user2 = userStore.createUser(USER2_USERNAME, null, new TimedLockImpl());
|
||||
userGroup = userStore.createUserGroup(USER_GROUP_UUID, USER_USERNAME+"-tenant");
|
||||
userGroup.add(user);
|
||||
userGroup.add(user2);
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ import com.sap.sse.security.interfaces.UserStore;
|
||||
import com.sap.sse.security.shared.RoleDefinition;
|
||||
import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.UserStoreManagementException;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
@@ -37,7 +37,7 @@ public class RoleDefinitionsTest {
|
||||
@BeforeEach
|
||||
public void doBefore() throws UserStoreManagementException {
|
||||
userStore.clear();
|
||||
user = userStore.createUser(username, email, new LockingAndBanningImpl());
|
||||
user = userStore.createUser(username, email, new TimedLockImpl());
|
||||
roleDefinition = userStore.createRoleDefinition(testRoleUUID, TEST_ROLE, Collections.emptySet());
|
||||
userGroup = userStore.createUserGroup(testGroupUUID, groupName);
|
||||
}
|
||||
|
||||
+3
-3
@@ -13,7 +13,7 @@ import com.sap.sse.mongodb.MongoDBConfiguration;
|
||||
import com.sap.sse.mongodb.MongoDBService;
|
||||
import com.sap.sse.security.shared.UserGroupManagementException;
|
||||
import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.userstore.mongodb.UserStoreImpl;
|
||||
import com.sap.sse.security.userstore.mongodb.impl.CollectionNames;
|
||||
|
||||
@@ -115,7 +115,7 @@ public class UserPreferenceObjectAndConverterTest {
|
||||
*/
|
||||
@Test
|
||||
public void deleteUserWithPreferenceObjectTest() throws UserManagementException, UserGroupManagementException {
|
||||
store.createUser(user1, email, new LockingAndBanningImpl());
|
||||
store.createUser(user1, email, new TimedLockImpl());
|
||||
store.registerPreferenceConverter(prefKey1, prefConverter);
|
||||
store.setPreferenceObject(user1, prefKey1, pref1);
|
||||
store.deleteUser(user1);
|
||||
@@ -124,7 +124,7 @@ public class UserPreferenceObjectAndConverterTest {
|
||||
|
||||
@Test
|
||||
public void removeConverterTest() throws UserManagementException, UserGroupManagementException {
|
||||
store.createUser(user1, email, new LockingAndBanningImpl());
|
||||
store.createUser(user1, email, new TimedLockImpl());
|
||||
store.registerPreferenceConverter(prefKey1, prefConverter);
|
||||
store.setPreference(user1, prefKey1, serializedPref1);
|
||||
store.removePreferenceConverter(prefKey1);
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test;
|
||||
import com.sap.sse.security.interfaces.UserStore;
|
||||
import com.sap.sse.security.shared.UserGroupManagementException;
|
||||
import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.userstore.mongodb.UserStoreImpl;
|
||||
|
||||
public class UserStoreTest {
|
||||
@@ -26,7 +26,7 @@ public class UserStoreTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws UserManagementException, UserGroupManagementException {
|
||||
userStore.createUser(username, email, new LockingAndBanningImpl());
|
||||
userStore.createUser(username, email, new TimedLockImpl());
|
||||
userStore.setAccessToken(username, accessToken);
|
||||
userStore.setPreference(username, prefKey, prefValue);
|
||||
}
|
||||
|
||||
+12
-12
@@ -34,7 +34,7 @@ import com.sap.sse.security.shared.SecurityUser;
|
||||
import com.sap.sse.security.shared.UserGroupManagementException;
|
||||
import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.UserStoreManagementException;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
@@ -92,7 +92,7 @@ public class UserStoreWithPersistenceTest {
|
||||
|
||||
@Test
|
||||
public void testCreateUser() throws UserManagementException {
|
||||
store.createUser(username, email, new LockingAndBanningImpl());
|
||||
store.createUser(username, email, new TimedLockImpl());
|
||||
assertNotNull(store.getUserByName(username));
|
||||
assertNotNull(store.getUserByEmail(email));
|
||||
|
||||
@@ -103,12 +103,12 @@ public class UserStoreWithPersistenceTest {
|
||||
|
||||
@Test
|
||||
public void testMasterdataIsSaved() throws UserStoreManagementException {
|
||||
store.createUser(username, email, new LockingAndBanningImpl());
|
||||
store.createUser(username, email, new TimedLockImpl());
|
||||
UserGroupImpl defaultTenant = createUserGroup();
|
||||
HashMap<String, UserGroup> defaultTenantForServers = new HashMap<>();
|
||||
defaultTenantForServers.put(serverName, defaultTenant);
|
||||
store.updateUser(new UserImpl(username, email, fullName, company, Locale.GERMAN, false, null, null,
|
||||
defaultTenantForServers, Collections.emptySet(), /* userGroupProvider */ null, new LockingAndBanningImpl()));
|
||||
defaultTenantForServers, Collections.emptySet(), /* userGroupProvider */ null, new TimedLockImpl()));
|
||||
newStore();
|
||||
User savedUser = store.getUserByName(username);
|
||||
assertEquals(username, savedUser.getName());
|
||||
@@ -123,7 +123,7 @@ public class UserStoreWithPersistenceTest {
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteUser() throws UserManagementException {
|
||||
store.createUser(username, email, new LockingAndBanningImpl());
|
||||
store.createUser(username, email, new TimedLockImpl());
|
||||
store.deleteUser(username);
|
||||
assertNull(store.getUserByName(username));
|
||||
assertNull(store.getUserByEmail(email));
|
||||
@@ -135,7 +135,7 @@ public class UserStoreWithPersistenceTest {
|
||||
|
||||
@Test
|
||||
public void testSetPreferences() throws UserManagementException {
|
||||
store.createUser(username, email, new LockingAndBanningImpl());
|
||||
store.createUser(username, email, new TimedLockImpl());
|
||||
store.setPreference(username, prefKey, prefValue);
|
||||
assertEquals(prefValue, store.getPreference(username, prefKey));
|
||||
newStore();
|
||||
@@ -144,7 +144,7 @@ public class UserStoreWithPersistenceTest {
|
||||
|
||||
@Test
|
||||
public void testUnsetPreferences() throws UserManagementException {
|
||||
store.createUser(username, email, new LockingAndBanningImpl());
|
||||
store.createUser(username, email, new TimedLockImpl());
|
||||
store.setPreference(username, prefKey, prefValue);
|
||||
store.unsetPreference(username, prefKey);
|
||||
assertNull(store.getPreference(username, prefKey));
|
||||
@@ -157,7 +157,7 @@ public class UserStoreWithPersistenceTest {
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteUserWithPreferences() throws UserManagementException {
|
||||
store.createUser(username, email, new LockingAndBanningImpl());
|
||||
store.createUser(username, email, new TimedLockImpl());
|
||||
store.setPreference(username, prefKey, prefValue);
|
||||
store.deleteUser(username);
|
||||
assertNull(store.getPreference(username, prefKey));
|
||||
@@ -167,7 +167,7 @@ public class UserStoreWithPersistenceTest {
|
||||
|
||||
@Test
|
||||
public void testCreateUserGroup() throws UserGroupManagementException, UserManagementException {
|
||||
final User user = store.createUser(username, email, new LockingAndBanningImpl());
|
||||
final User user = store.createUser(username, email, new TimedLockImpl());
|
||||
UserGroupImpl createUserGroup = createUserGroup();
|
||||
createUserGroup.add(user);
|
||||
store.updateUserGroup(createUserGroup);
|
||||
@@ -196,7 +196,7 @@ public class UserStoreWithPersistenceTest {
|
||||
@Test
|
||||
public void testTenantUsers() throws UserManagementException, UserGroupManagementException {
|
||||
UserGroupImpl defaultTenant = createUserGroup();
|
||||
final User user = store.createUser(username, email, new LockingAndBanningImpl());
|
||||
final User user = store.createUser(username, email, new TimedLockImpl());
|
||||
defaultTenant.add(user);
|
||||
store.updateUserGroup(defaultTenant);
|
||||
user.getDefaultTenantMap().put(serverName, defaultTenant);
|
||||
@@ -218,7 +218,7 @@ public class UserStoreWithPersistenceTest {
|
||||
|
||||
@Test
|
||||
public void testUserGroups() throws UserManagementException, UserGroupManagementException {
|
||||
final User user = store.createUser(username, email, new LockingAndBanningImpl());
|
||||
final User user = store.createUser(username, email, new TimedLockImpl());
|
||||
final String GROUP_NAME = "group";
|
||||
final UserGroupImpl group = store.createUserGroup(UUID.randomUUID(), GROUP_NAME);
|
||||
group.add(user);
|
||||
@@ -242,7 +242,7 @@ public class UserStoreWithPersistenceTest {
|
||||
@Test
|
||||
public void testGetExistingQualificationsForRoleDefinition()
|
||||
throws UserManagementException, UserGroupManagementException {
|
||||
User user = store.createUser("def", "d@test.de", new LockingAndBanningImpl());
|
||||
User user = store.createUser("def", "d@test.de", new TimedLockImpl());
|
||||
RoleDefinitionImpl roleDefinition = new RoleDefinitionImpl(UUID.randomUUID(), "My-Test-Role");
|
||||
store.createRoleDefinition(roleDefinition.getId(), roleDefinition.getName(), new ArrayList<>());
|
||||
UserGroupImpl userGroup = store.createUserGroup(UUID.randomUUID(), "Test-Usergroup");
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ import com.sap.sse.security.shared.dto.SecuredDTO;
|
||||
import com.sap.sse.security.shared.dto.StrippedUserGroupDTO;
|
||||
import com.sap.sse.security.shared.dto.UserDTO;
|
||||
import com.sap.sse.security.shared.dto.UserGroupDTO;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.ui.oauth.client.CredentialDTO;
|
||||
import com.sap.sse.security.ui.shared.SecurityServiceSharingDTO;
|
||||
import com.sap.sse.security.ui.shared.SuccessInfo;
|
||||
@@ -33,7 +34,7 @@ public interface UserManagementService extends RemoteService {
|
||||
throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
|
||||
|
||||
Collection<UserGroupDTO> getUserGroups() throws org.apache.shiro.authz.UnauthorizedException;
|
||||
|
||||
|
||||
UserGroupDTO getUserGroupByName(String userGroupName)
|
||||
throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
|
||||
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ import com.sap.sse.security.shared.dto.SecuredDTO;
|
||||
import com.sap.sse.security.shared.dto.StrippedUserGroupDTO;
|
||||
import com.sap.sse.security.shared.dto.UserDTO;
|
||||
import com.sap.sse.security.shared.dto.UserGroupDTO;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.ui.oauth.client.CredentialDTO;
|
||||
import com.sap.sse.security.ui.shared.SecurityServiceSharingDTO;
|
||||
import com.sap.sse.security.ui.shared.SuccessInfo;
|
||||
|
||||
+2
@@ -79,6 +79,8 @@ public interface UserManagementWriteService extends UserManagementService {
|
||||
|
||||
SuccessInfo deleteUser(String username) throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
|
||||
|
||||
SuccessInfo unlockUser(String username) throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
|
||||
|
||||
Set<SuccessInfo> deleteUsers(Set<String> usernames)
|
||||
throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
|
||||
|
||||
|
||||
+2
@@ -61,6 +61,8 @@ public interface UserManagementWriteServiceAsync extends UserManagementServiceAs
|
||||
void updateRoleDefinition(RoleDefinitionDTO roleWithNewProperties, AsyncCallback<Void> callback);
|
||||
|
||||
void deleteUser(String username, AsyncCallback<SuccessInfo> callback);
|
||||
|
||||
void unlockUser(String username, AsyncCallback<SuccessInfo> callback);
|
||||
|
||||
void deleteUsers(Set<String> usernames, AsyncCallback<Set<SuccessInfo>> callback);
|
||||
|
||||
|
||||
+10
-1
@@ -14,6 +14,7 @@ public class DefaultActionsImagesBarCell extends ImagesBarCell {
|
||||
public static final String ACTION_CHANGE_OWNERSHIP = DefaultActions.CHANGE_OWNERSHIP.name();
|
||||
public static final String ACTION_MIGRATE_GROUP_OWNERSHIP_HIERARCHY = "MIGRATE_GROUP_OWNERSHIP_HIERARCHY";
|
||||
public static final String ACTION_CHANGE_ACL = DefaultActions.CHANGE_ACL.name();
|
||||
public static final String ACTION_MANAGE_LOCK = DefaultActions.MANAGE_LOCK.name();
|
||||
|
||||
protected final StringMessages stringMessages;
|
||||
|
||||
@@ -24,7 +25,7 @@ public class DefaultActionsImagesBarCell extends ImagesBarCell {
|
||||
@Override
|
||||
protected Iterable<ImageSpec> getImageSpecs() {
|
||||
return Arrays.asList(getUpdateImageSpec(), getDeleteImageSpec(), getChangeOwnershipImageSpec(),
|
||||
getChangeACLImageSpec());
|
||||
getChangeACLImageSpec(), getResetLockImageSpec());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,4 +66,12 @@ public class DefaultActionsImagesBarCell extends ImagesBarCell {
|
||||
IconResources.INSTANCE.changeACLIcon());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link ImageSpec} for {@link DefaultActions#CHANGE_ACL reset lock} action
|
||||
*/
|
||||
protected ImageSpec getResetLockImageSpec() {
|
||||
return new ImageSpec(ACTION_MANAGE_LOCK, stringMessages.resetLock(),
|
||||
IconResources.INSTANCE.resetLockIcon());
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -150,6 +150,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages {
|
||||
String groups();
|
||||
String group();
|
||||
String errorDeletingUser(String username, String message);
|
||||
String doYouReallyWantToUnlockUser(String name);
|
||||
String doYouReallyWantToRemoveUser(String name);
|
||||
String errorTryingToUpdateUser(String username, String message);
|
||||
String ownership();
|
||||
@@ -161,6 +162,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages {
|
||||
String userNotFound(String username);
|
||||
String usergroupNotFound(String userGroupName);
|
||||
String actionChangeACL();
|
||||
String resetLock();
|
||||
String editACLForObject(String objectName);
|
||||
String acl();
|
||||
String errorUpdatingAcl(String name);
|
||||
|
||||
+2
@@ -157,6 +157,7 @@ groups=Groups
|
||||
group=Group
|
||||
errorDeletingUser=Error deleting user {0}: {1}
|
||||
doYouReallyWantToRemoveUser=Really remove user {0}?
|
||||
doYouReallyWantToUnlockUser=Really allow locked user {0} to access SAP Sailing Analytics again?
|
||||
errorTryingToUpdateUser=Error trying to update user {0}: {1}
|
||||
ownership=Ownership
|
||||
editObjectOwnership=Edit object ownership
|
||||
@@ -167,6 +168,7 @@ pleaseWaitUntilUserGroupNameIsResolved=Please wait until user group name is reso
|
||||
userNotFound=User {0} not found
|
||||
usergroupNotFound=User group {0} not found
|
||||
actionChangeACL=Change ACL
|
||||
resetLock=Reset Lock
|
||||
editACLForObject=Edit ACL for ''{0}''
|
||||
acl=ACL
|
||||
errorUpdatingAcl=Error updating ACL: {0}.
|
||||
|
||||
+79
-36
@@ -14,6 +14,7 @@ import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.gwt.cell.client.SafeHtmlCell;
|
||||
import com.google.gwt.core.client.Callback;
|
||||
@@ -45,6 +46,7 @@ import com.sap.sse.security.shared.dto.RoleWithSecurityDTO;
|
||||
import com.sap.sse.security.shared.dto.StrippedUserGroupDTO;
|
||||
import com.sap.sse.security.shared.dto.UserDTO;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.ui.client.EntryPointLinkFactory;
|
||||
import com.sap.sse.security.ui.client.UserManagementServiceAsync;
|
||||
import com.sap.sse.security.ui.client.UserManagementWriteServiceAsync;
|
||||
@@ -162,42 +164,8 @@ extends TableWrapper<UserDTO, S, StringMessages, TR> {
|
||||
user->user.getLockedUntil() != null && user.getLockedUntil().after(TimePoint.now()) ?
|
||||
DateAndTimeFormatterUtil.dateTimeMedium.render(user.getLockedUntil().asDate()) : "",
|
||||
userColumnListHandler);
|
||||
final HasPermissions type = SecuredSecurityTypes.USER;
|
||||
final AccessControlledActionsColumn<UserDTO, DefaultActionsImagesBarCell> userActionColumn = create(
|
||||
new DefaultActionsImagesBarCell(stringMessages), userService);
|
||||
userActionColumn.addAction(ACTION_UPDATE, UPDATE, user -> editUser(user));
|
||||
userActionColumn.addAction(ACTION_DELETE, DELETE, user -> {
|
||||
if (Window.confirm(stringMessages.doYouReallyWantToRemoveUser(user.getName()))) {
|
||||
getUserManagementWriteService().deleteUser(user.getName(), new AsyncCallback<SuccessInfo>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
deletingUserFailed(user, caught.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(SuccessInfo result) {
|
||||
if (result.isSuccessful()) {
|
||||
filterField.remove(user);
|
||||
} else {
|
||||
deletingUserFailed(user, result.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void deletingUserFailed(UserDTO user, String message) {
|
||||
errorReporter.reportError(stringMessages.errorDeletingUser(user.getName(), message));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
final EditOwnershipDialog.DialogConfig<UserDTO> configOwnership = EditOwnershipDialog.create(
|
||||
userService.getUserManagementWriteService(), type,
|
||||
user -> refreshUserList((Callback<Iterable<UserDTO>, Throwable>) null), stringMessages);
|
||||
final EditACLDialog.DialogConfig<UserDTO> configACL = EditACLDialog.create(
|
||||
userService.getUserManagementWriteService(), type,
|
||||
user -> user.getAccessControlList(), stringMessages);
|
||||
userActionColumn.addAction(ACTION_CHANGE_OWNERSHIP, CHANGE_OWNERSHIP, configOwnership::openOwnershipDialog);
|
||||
userActionColumn.addAction(DefaultActionsImagesBarCell.ACTION_CHANGE_ACL, DefaultActions.CHANGE_ACL,
|
||||
u -> configACL.openDialog(u));
|
||||
final AccessControlledActionsColumn<UserDTO, DefaultActionsImagesBarCell> userActionColumn = composeUserActionColumn(
|
||||
stringMessages, errorReporter);
|
||||
filterField = new LabeledAbstractFilterablePanel<UserDTO>(new Label(stringMessages.filterUsers()),
|
||||
new ArrayList<UserDTO>(), dataProvider, stringMessages) {
|
||||
@Override
|
||||
@@ -234,6 +202,81 @@ extends TableWrapper<UserDTO, S, StringMessages, TR> {
|
||||
table.addColumn(userActionColumn, stringMessages.actions());
|
||||
table.ensureDebugId("UsersTable");
|
||||
}
|
||||
|
||||
private AccessControlledActionsColumn<UserDTO, DefaultActionsImagesBarCell> composeUserActionColumn(
|
||||
StringMessages stringMessages, ErrorReporter errorReporter) {
|
||||
final HasPermissions type = SecuredSecurityTypes.USER;
|
||||
final AccessControlledActionsColumn<UserDTO, DefaultActionsImagesBarCell> userActionColumn = create(
|
||||
new DefaultActionsImagesBarCell(stringMessages), userService);
|
||||
userActionColumn.addAction(ACTION_UPDATE, UPDATE, user -> editUser(user));
|
||||
userActionColumn.addAction(ACTION_DELETE, DELETE, user -> {
|
||||
if (Window.confirm(stringMessages.doYouReallyWantToRemoveUser(user.getName()))) {
|
||||
getUserManagementWriteService().deleteUser(user.getName(), new AsyncCallback<SuccessInfo>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
deletingUserFailed(user, caught.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(SuccessInfo result) {
|
||||
if (result.isSuccessful()) {
|
||||
filterField.remove(user);
|
||||
} else {
|
||||
deletingUserFailed(user, result.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void deletingUserFailed(UserDTO user, String message) {
|
||||
errorReporter.reportError(stringMessages.errorDeletingUser(user.getName(), message));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
final EditOwnershipDialog.DialogConfig<UserDTO> configOwnership = EditOwnershipDialog.create(
|
||||
userService.getUserManagementWriteService(), type,
|
||||
user -> refreshUserList((Callback<Iterable<UserDTO>, Throwable>) null), stringMessages);
|
||||
userActionColumn.addAction(ACTION_CHANGE_OWNERSHIP, CHANGE_OWNERSHIP, configOwnership::openOwnershipDialog);
|
||||
final EditACLDialog.DialogConfig<UserDTO> configACL = EditACLDialog.create(
|
||||
userService.getUserManagementWriteService(), type,
|
||||
user -> user.getAccessControlList(), stringMessages);
|
||||
userActionColumn.addAction(DefaultActionsImagesBarCell.ACTION_CHANGE_ACL, DefaultActions.CHANGE_ACL,
|
||||
u -> configACL.openDialog(u));
|
||||
userActionColumn.addAction(
|
||||
DefaultActionsImagesBarCell.ACTION_MANAGE_LOCK,
|
||||
DefaultActions.MANAGE_LOCK,
|
||||
onManageLockPressed(stringMessages, errorReporter)
|
||||
);
|
||||
return userActionColumn;
|
||||
}
|
||||
|
||||
private Consumer<UserDTO> onManageLockPressed(StringMessages stringMessages, ErrorReporter errorReporter) {
|
||||
return user -> {
|
||||
final boolean isLocked = user.getLockedUntil().after(TimePoint.now());
|
||||
if (isLocked) {
|
||||
final String userName = user.getName();
|
||||
final boolean didConfirm = Window.confirm(stringMessages.doYouReallyWantToUnlockUser(userName));
|
||||
if (didConfirm) {
|
||||
getUserManagementWriteService().unlockUser(
|
||||
userName,
|
||||
new AsyncCallback<SuccessInfo>() {
|
||||
@Override
|
||||
public void onSuccess(SuccessInfo result) {
|
||||
Window.alert("Unlock succeeded for user " + userName + ".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
Window.alert("Unlock failed for user " + userName + ".");
|
||||
errorReporter.reportError(caught.getMessage());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
Window.alert("This user is already unlocked.");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Iterable<UserDTO> getAllUsers() {
|
||||
return filterField.getAll();
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ public class SecurityDTOFactory {
|
||||
/* default tenant filled in later */ null,
|
||||
getSecuredPermissions(filteredPermissions, user, securityService),
|
||||
createStrippedUserGroupDTOsFromUserGroups(securityService.getUserGroupsOfUser(user),
|
||||
fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup), user.getLockingAndBanning().getLockedUntil());
|
||||
fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup), user.getTimedLock().getLockedUntil());
|
||||
userDTO.setDefaultTenantForCurrentServer(createStrippedUserGroupDTOFromUserGroup(
|
||||
securityService.getDefaultTenantForCurrentUser(),
|
||||
fromOriginalToStrippedDownUserGroup));
|
||||
|
||||
+19
@@ -374,6 +374,25 @@ public class UserManagementWriteServiceImpl extends UserManagementServiceImpl im
|
||||
return new SuccessInfo(false, "Could not delete user.", /* redirectURL */ null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SuccessInfo unlockUser(String username) throws UnauthorizedException {
|
||||
User user = getSecurityService().getUserByName(username);
|
||||
if (user != null) {
|
||||
if (!getSecurityService().hasCurrentUserExplicitPermissions(user, DefaultActions.MANAGE_LOCK)) {
|
||||
return new SuccessInfo(false, "You are not permitted to manage locking on user " + username,
|
||||
/* redirectURL */ null, null);
|
||||
}
|
||||
try {
|
||||
getSecurityService().resetUserTimedLock(username);
|
||||
return new SuccessInfo(true, "Reset lock on user: " + username + ".", /* redirectURL */ null, null);
|
||||
} catch (UserManagementException e) {
|
||||
return new SuccessInfo(false, "Could not reset lock on user " + username, /* redirectURL */ null, null);
|
||||
}
|
||||
} else {
|
||||
return new SuccessInfo(false, "Could not reset lock on user " + username, /* redirectURL */ null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SuccessInfo> deleteUsers(Set<String> usernames) throws UnauthorizedException {
|
||||
|
||||
@@ -24,7 +24,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
subjectDAO = com.sap.sse.security.NoSessionStorageForUnauthenticatedSessionsSessionDAO
|
||||
|
||||
+3
-3
@@ -34,7 +34,7 @@ import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.UserRole;
|
||||
import com.sap.sse.security.shared.UserStoreManagementException;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
@@ -854,12 +854,12 @@ public class UserStoreImpl implements UserStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public User createUser(String name, String email, LockingAndBanning lockingAndBanning, Account... accounts)
|
||||
public User createUser(String name, String email, TimedLock timedLock, Account... accounts)
|
||||
throws UserManagementException {
|
||||
return LockUtil.executeWithWriteLockAndResultExpectException(usersLock, () -> {
|
||||
checkUsernameUniqueness(name);
|
||||
final Map<String, UserGroup> tenantsForServer = new ConcurrentHashMap<>();
|
||||
final User user = new UserImpl(name, email, tenantsForServer, /* user group provider */ this, lockingAndBanning, accounts);
|
||||
final User user = new UserImpl(name, email, tenantsForServer, /* user group provider */ this, timedLock, accounts);
|
||||
logger.info("Creating user: " + user + " with e-mail " + email);
|
||||
addAndStoreUserInternal(user);
|
||||
return user;
|
||||
|
||||
+5
-5
@@ -37,8 +37,8 @@ import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.UsernamePasswordAccount;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.AccessControlList;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.QualifiedObjectIdentifierImpl;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
@@ -289,9 +289,9 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
final String validationSecret = (String) userDBObject.get(FieldNames.User.VALIDATION_SECRET.name());
|
||||
final Long lockedUntilMillis = userDBObject.getLong(FieldNames.User.LOCKED_UNTIL_MILLIS.name());
|
||||
final Long nextLockingDurationMillis = userDBObject.getLong(FieldNames.User.NEXT_LOCKING_DURATION_MILLIS.name());
|
||||
final LockingAndBanning lockingAndBanning = new LockingAndBanningImpl(
|
||||
final TimedLock timedLock = new TimedLockImpl(
|
||||
lockedUntilMillis == null ? TimePoint.BeginningOfTime : TimePoint.of(lockedUntilMillis),
|
||||
nextLockingDurationMillis == null ? LockingAndBanningImpl.DEFAULT_INITIAL_LOCKING_DELAY : Duration.ofMillis(nextLockingDurationMillis));
|
||||
nextLockingDurationMillis == null ? TimedLockImpl.DEFAULT_INITIAL_LOCKING_DELAY : Duration.ofMillis(nextLockingDurationMillis));
|
||||
final Set<Role> roles = new HashSet<>();
|
||||
final Set<String> permissions = new HashSet<>();
|
||||
final List<?> rolesO = (List<?>) userDBObject.get(FieldNames.User.ROLE_IDS.name());
|
||||
@@ -358,7 +358,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
Map<AccountType, Account> accounts = createAccountMapFromdDBObject(accountsMap);
|
||||
User result = new UserImpl(username, email, fullName, company, locale,
|
||||
emailValidated == null ? false : emailValidated, passwordResetSecret, validationSecret, defaultTenant,
|
||||
accounts.values(), userGroupProvider, lockingAndBanning);
|
||||
accounts.values(), userGroupProvider, timedLock);
|
||||
for (final Role role : roles) {
|
||||
result.addRole(role);
|
||||
}
|
||||
|
||||
+7
-7
@@ -27,7 +27,7 @@ import com.sap.sse.security.shared.SocialUserAccount;
|
||||
import com.sap.sse.security.shared.UsernamePasswordAccount;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.AccessControlList;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
@@ -216,13 +216,13 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
dbUser.put(FieldNames.User.PASSWORD_RESET_SECRET.name(), user.getPasswordResetSecret());
|
||||
dbUser.put(FieldNames.User.VALIDATION_SECRET.name(), user.getValidationSecret());
|
||||
dbUser.put(FieldNames.User.ACCOUNTS.name(), createAccountMapObject(user.getAllAccounts()));
|
||||
if (user.getLockingAndBanning() instanceof LockingAndBanningImpl) {
|
||||
final LockingAndBanningImpl lockingAndBanning = ((LockingAndBanningImpl) user.getLockingAndBanning());
|
||||
dbUser.put(FieldNames.User.LOCKED_UNTIL_MILLIS.name(), lockingAndBanning.getLockedUntil().asMillis());
|
||||
dbUser.put(FieldNames.User.NEXT_LOCKING_DURATION_MILLIS.name(), lockingAndBanning.getNextLockingDelay().asMillis());
|
||||
if (user.getTimedLock() instanceof TimedLockImpl) {
|
||||
final TimedLockImpl timedLock = ((TimedLockImpl) user.getTimedLock());
|
||||
dbUser.put(FieldNames.User.LOCKED_UNTIL_MILLIS.name(), timedLock.getLockedUntil().asMillis());
|
||||
dbUser.put(FieldNames.User.NEXT_LOCKING_DURATION_MILLIS.name(), timedLock.getNextLockingDelay().asMillis());
|
||||
} else {
|
||||
logger.warning("Expected user locking/banning to be of type "+LockingAndBanningImpl.class.getSimpleName()
|
||||
+" but was of type "+user.getLockingAndBanning().getClass().getSimpleName()+"; not storing to DB");
|
||||
logger.warning("Expected user locking/banning to be of type "+TimedLockImpl.class.getSimpleName()
|
||||
+" but was of type "+user.getTimedLock().getClass().getSimpleName()+"; not storing to DB");
|
||||
}
|
||||
BasicDBList dbRoles = new BasicDBList();
|
||||
for (Role role : user.getRoles()) {
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ import com.sap.sse.security.shared.HasPermissions;
|
||||
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.UserGroupProvider;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
@@ -242,7 +242,7 @@ public class UserProxy implements User {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingAndBanning getLockingAndBanning() {
|
||||
public TimedLock getTimedLock() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
+10
-10
@@ -14,16 +14,16 @@ import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
|
||||
import org.apache.shiro.realm.Realm;
|
||||
|
||||
import com.sap.sse.security.impl.Activator;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.util.ServiceTrackerFactory;
|
||||
|
||||
public class AtLeastOneSuccessfulStrategyWithLockingAndBanning extends AtLeastOneSuccessfulStrategy {
|
||||
private static final Logger logger = Logger.getLogger(AtLeastOneSuccessfulStrategyWithLockingAndBanning.class.getName());
|
||||
public class AtLeastOneSuccessfulStrategyWithTimedLocks extends AtLeastOneSuccessfulStrategy {
|
||||
private static final Logger logger = Logger.getLogger(AtLeastOneSuccessfulStrategyWithTimedLocks.class.getName());
|
||||
|
||||
private final Future<SecurityService> securityService;
|
||||
|
||||
public AtLeastOneSuccessfulStrategyWithLockingAndBanning() {
|
||||
public AtLeastOneSuccessfulStrategyWithTimedLocks() {
|
||||
if (Activator.getContext() != null) {
|
||||
securityService = ServiceTrackerFactory.createServiceFuture(Activator.getContext(), SecurityService.class);
|
||||
} else {
|
||||
@@ -55,9 +55,9 @@ public class AtLeastOneSuccessfulStrategyWithLockingAndBanning extends AtLeastOn
|
||||
logger.info("failed password authentication for user "+username);
|
||||
final SecurityService mySecurityService = getSecurityService();
|
||||
if (mySecurityService != null) {
|
||||
final LockingAndBanning lockingAndBanning = mySecurityService.failedPasswordAuthentication(user);
|
||||
if (lockingAndBanning != null) {
|
||||
logger.info("User "+username+" locked for password authentication: "+lockingAndBanning);
|
||||
final TimedLock timedLock = mySecurityService.failedPasswordAuthentication(user);
|
||||
if (timedLock != null) {
|
||||
logger.info("User "+username+" locked for password authentication: "+timedLock);
|
||||
}
|
||||
} else {
|
||||
logger.warning("Account locking due to failed password authentication for user "+username+" not possible; security service not found");
|
||||
@@ -81,9 +81,9 @@ public class AtLeastOneSuccessfulStrategyWithLockingAndBanning extends AtLeastOn
|
||||
logger.info("failed bearer token authentication for client IP "+bearerToken.getClientIP()+" with user agent "+bearerToken.getUserAgent());
|
||||
final SecurityService mySecurityService = getSecurityService();
|
||||
if (mySecurityService != null) {
|
||||
final LockingAndBanning lockingAndBanning = mySecurityService.failedBearerTokenAuthentication(bearerToken.getClientIP());
|
||||
if (lockingAndBanning != null) {
|
||||
logger.info("Client IP "+bearerToken.getClientIP()+" locked for bearer token authentication: "+lockingAndBanning);
|
||||
final TimedLock timedLock = mySecurityService.failedBearerTokenAuthentication(bearerToken.getClientIP());
|
||||
if (timedLock != null) {
|
||||
logger.info("Client IP "+bearerToken.getClientIP()+" locked for bearer token authentication: "+timedLock);
|
||||
}
|
||||
} else {
|
||||
logger.warning("Client IP locking due to failed bearer token authentication for client IP "
|
||||
@@ -40,7 +40,7 @@ import com.sap.sse.security.interfaces.SocialSettingsKeys;
|
||||
import com.sap.sse.security.shared.SocialUserAccount;
|
||||
import com.sap.sse.security.shared.UserGroupManagementException;
|
||||
import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.impl.UserGroup;
|
||||
|
||||
@@ -189,7 +189,7 @@ public class OAuthRealm extends AbstractCompositeAuthorizingRealm {
|
||||
try {
|
||||
UserGroup tenant = getUserStore().createUserGroup(UUID.randomUUID(), socialname + SecurityService.TENANT_SUFFIX);
|
||||
getAccessControlStore().setOwnership(tenant.getIdentifier(), user, tenant, tenant.getName());
|
||||
user = getUserStore().createUser(socialname, socialUser.getProperty(Social.EMAIL.name()), new LockingAndBanningImpl(), socialUser);
|
||||
user = getUserStore().createUser(socialname, socialUser.getProperty(Social.EMAIL.name()), new TimedLockImpl(), socialUser);
|
||||
tenant.add(user);
|
||||
getUserStore().updateUserGroup(tenant);
|
||||
} catch (UserManagementException | UserGroupManagementException e) {
|
||||
|
||||
@@ -53,7 +53,7 @@ import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.impl.AccessControlList;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
|
||||
@@ -222,6 +222,8 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
|
||||
void updateSimpleUserEmail(String username, String newEmail, String validationBaseURL) throws UserManagementException;
|
||||
|
||||
void updateUserProperties(String username, String fullName, String company, Locale locale) throws UserManagementException;
|
||||
|
||||
void resetUserTimedLock(String username) throws UserManagementException;
|
||||
|
||||
void deleteUser(String username) throws UserManagementException;
|
||||
|
||||
@@ -874,7 +876,7 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
|
||||
|
||||
Pair<Boolean, Set<String>> getCORSFilterConfiguration(String serverName);
|
||||
|
||||
LockingAndBanning failedPasswordAuthentication(User user);
|
||||
TimedLock failedPasswordAuthentication(User user);
|
||||
|
||||
void successfulPasswordAuthentication(User user);
|
||||
|
||||
@@ -892,7 +894,7 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
|
||||
* structures, avoiding garbage piling up.
|
||||
* @return TODO
|
||||
*/
|
||||
LockingAndBanning failedBearerTokenAuthentication(String clientIP);
|
||||
TimedLock failedBearerTokenAuthentication(String clientIP);
|
||||
|
||||
/**
|
||||
* Call this when the combination of {@code clientIP} and {@code userAgent} was not
|
||||
|
||||
@@ -50,8 +50,8 @@ public class UsernamePasswordRealm extends AbstractCompositeAuthorizingRealm {
|
||||
logger.warning("Rejecting authentication attempt for non-existing user "+username);
|
||||
return null;
|
||||
}
|
||||
if (user.getLockingAndBanning().isAuthenticationLocked()) {
|
||||
logger.warning("Rejected attempt to authenticate user "+username+" because it is locked: "+user.getLockingAndBanning());
|
||||
if (user.getTimedLock().isLocked()) {
|
||||
logger.warning("Rejected attempt to authenticate user "+username+" because it is locked: "+user.getTimedLock());
|
||||
throw new LockedAccountException("Password authentication for user "+username+" is currently locked");
|
||||
}
|
||||
final UsernamePasswordAccount upa = (UsernamePasswordAccount) user.getAccount(AccountType.USERNAME_PASSWORD);
|
||||
|
||||
+6
-4
@@ -15,7 +15,7 @@ import com.sap.sse.security.shared.RoleDefinition;
|
||||
import com.sap.sse.security.shared.UserGroupManagementException;
|
||||
import com.sap.sse.security.shared.UserManagementException;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.User;
|
||||
import com.sap.sse.security.shared.subscription.Subscription;
|
||||
@@ -69,6 +69,8 @@ public interface ReplicableSecurityService extends SecurityService {
|
||||
|
||||
Void internalUpdateUserProperties(String username, String fullName, String company, Locale locale);
|
||||
|
||||
Void internalResetUserTimedLock(String username);
|
||||
|
||||
Boolean internalValidateEmail(String username, String validationSecret);
|
||||
|
||||
Void internalSetPreference(String username, String key, String value);
|
||||
@@ -122,13 +124,13 @@ public interface ReplicableSecurityService extends SecurityService {
|
||||
|
||||
Void internalSetCORSFilterConfigurationAllowedOrigins(String serverName, String... allowedOrigins);
|
||||
|
||||
LockingAndBanning internalFailedPasswordAuthentication(String username);
|
||||
TimedLock internalFailedPasswordAuthentication(String username);
|
||||
|
||||
Boolean internalSuccessfulPasswordAuthentication(String username);
|
||||
|
||||
Boolean internalSuccessfulBearerTokenAuthentication(String clientIP);
|
||||
|
||||
LockingAndBanning internalFailedBearerTokenAuthentication(String clientIP);
|
||||
TimedLock internalFailedBearerTokenAuthentication(String clientIP);
|
||||
|
||||
LockingAndBanning internalRecordUserCreationFromClientIP(String clientIP);
|
||||
TimedLock internalRecordUserCreationFromClientIP(String clientIP);
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ import com.sap.sse.security.operations.RemoveRoleDefinitionFromUserGroupOperatio
|
||||
import com.sap.sse.security.operations.RemoveRoleFromUserOperation;
|
||||
import com.sap.sse.security.operations.RemoveUserFromUserGroupOperation;
|
||||
import com.sap.sse.security.operations.ResetPasswordOperation;
|
||||
import com.sap.sse.security.operations.ResetUserLockOperation;
|
||||
import com.sap.sse.security.operations.SecurityOperation;
|
||||
import com.sap.sse.security.operations.SetAccessTokenOperation;
|
||||
import com.sap.sse.security.operations.SetDefaultTenantForServerForUserOperation;
|
||||
@@ -184,8 +185,8 @@ import com.sap.sse.security.shared.UsernamePasswordAccount;
|
||||
import com.sap.sse.security.shared.WildcardPermission;
|
||||
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
|
||||
import com.sap.sse.security.shared.impl.AccessControlList;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
import com.sap.sse.security.shared.impl.TimedLockImpl;
|
||||
import com.sap.sse.security.shared.impl.Ownership;
|
||||
import com.sap.sse.security.shared.impl.PermissionAndRoleAssociation;
|
||||
import com.sap.sse.security.shared.impl.Role;
|
||||
@@ -277,7 +278,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
* @see #successfulBearerTokenAuthentication(String)
|
||||
* @see #isClientIPLockedForBearerTokenAuthentication(String)
|
||||
*/
|
||||
private final ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForBearerTokenAuthentication;
|
||||
private final ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForBearerTokenAuthentication;
|
||||
private final static String CLIENT_IP_NULL_ESCAPE = UUID.randomUUID().toString();
|
||||
|
||||
/**
|
||||
@@ -289,7 +290,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
* When entering values into this map, the method entering it is responsible for also scheduling a background
|
||||
* task that a while after lock expiry the record is expunged again from the map to avoid garbage piling up.
|
||||
*/
|
||||
private final ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForUserCreation;
|
||||
private final ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForUserCreation;
|
||||
|
||||
private final Zxcvbn passwordValidator;
|
||||
|
||||
@@ -340,8 +341,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
throw new IllegalArgumentException("No HasPermissionsProvider defined");
|
||||
}
|
||||
logger.info("Initializing Security Service with user store " + userStore);
|
||||
this.clientIPBasedLockingAndBanningForBearerTokenAuthentication = new ConcurrentHashMap<>();
|
||||
this.clientIPBasedLockingAndBanningForUserCreation = new ConcurrentHashMap<>();
|
||||
this.clientIPBasedTimedLocksForBearerTokenAuthentication = new ConcurrentHashMap<>();
|
||||
this.clientIPBasedTimedLocksForUserCreation = new ConcurrentHashMap<>();
|
||||
this.permissionChangeListeners = new PermissionChangeListeners(this);
|
||||
this.sharedAcrossSubdomainsOf = sharedAcrossSubdomainsOf;
|
||||
this.subscriptionPlanProvider = subscriptionPlanProvider;
|
||||
@@ -1148,22 +1149,22 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
// synchronize to ensure that no two threads can enter values into the map concurrently;
|
||||
// still the use of a ConcurrentMap is justified because there may be concurrent write access
|
||||
// through replication
|
||||
synchronized (clientIPBasedLockingAndBanningForUserCreation) {
|
||||
final LockingAndBanning lockingAndBanning = clientIPBasedLockingAndBanningForUserCreation.get(clientIP);
|
||||
if (lockingAndBanning == null || !lockingAndBanning.isAuthenticationLocked()) {
|
||||
synchronized (clientIPBasedTimedLocksForUserCreation) {
|
||||
final TimedLock timedLock = clientIPBasedTimedLocksForUserCreation.get(clientIP);
|
||||
if (timedLock == null || !timedLock.isLocked()) {
|
||||
apply(s->s.internalRecordUserCreationFromClientIP(clientIP));
|
||||
} else {
|
||||
throw new UserManagementException(UserManagementException.CLIENT_CURRENTLY_LOCKED_FOR_USER_CREATION);
|
||||
throw new UserManagementException("Client IP "+clientIP+" locked for user creation: "+timedLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingAndBanning internalRecordUserCreationFromClientIP(String clientIP) {
|
||||
final LockingAndBanning result = new LockingAndBanningImpl(TimePoint.now().plus(DEFAULT_CLIENT_IP_BASED_USER_CREATION_LOCKING_DURATION),
|
||||
public TimedLock internalRecordUserCreationFromClientIP(String clientIP) {
|
||||
final TimedLock result = new TimedLockImpl(TimePoint.now().plus(DEFAULT_CLIENT_IP_BASED_USER_CREATION_LOCKING_DURATION),
|
||||
DEFAULT_CLIENT_IP_BASED_USER_CREATION_LOCKING_DURATION);
|
||||
clientIPBasedLockingAndBanningForUserCreation.put(clientIP, result);
|
||||
scheduleCleanUpTask(clientIP, result, clientIPBasedLockingAndBanningForUserCreation,
|
||||
clientIPBasedTimedLocksForUserCreation.put(clientIP, result);
|
||||
scheduleCleanUpTask(clientIP, result, clientIPBasedTimedLocksForUserCreation,
|
||||
"client IPs locked for user creation");
|
||||
return result;
|
||||
}
|
||||
@@ -1203,7 +1204,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
|
||||
@Override
|
||||
public User internalCreateUser(String username, String email, Account... accounts) throws UserManagementException {
|
||||
final User result = store.createUser(username, email, new LockingAndBanningImpl(), accounts);
|
||||
final User result = store.createUser(username, email, new TimedLockImpl(), accounts);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1262,14 +1263,31 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetUserTimedLock(String username) throws UserManagementException {
|
||||
final User user = store.getUserByName(username);
|
||||
if (user == null) {
|
||||
throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST);
|
||||
}
|
||||
apply(new ResetUserLockOperation(username, user.getTimedLock()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void internalResetUserTimedLock(String username) {
|
||||
final User user = store.getUserByName(username);
|
||||
user.getTimedLock().resetLock();
|
||||
store.updateUser(user);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkPassword(String username, String password) throws UserManagementException {
|
||||
final User user = store.getUserByName(username);
|
||||
if (user == null) {
|
||||
throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST);
|
||||
}
|
||||
if (user.getLockingAndBanning().isAuthenticationLocked()) {
|
||||
throw new UserManagementException(UserManagementException.PASSWORD_AUTHENTICATION_CURRENTLY_LOCKED_FOR_USER);
|
||||
if (user.getTimedLock().isLocked()) {
|
||||
throw new UserManagementException("Password authentication is locked for user "+username);
|
||||
}
|
||||
final UsernamePasswordAccount account = (UsernamePasswordAccount) user.getAccount(AccountType.USERNAME_PASSWORD);
|
||||
String hashedOldPassword = hashPassword(password, account.getSalt());
|
||||
@@ -1284,23 +1302,23 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingAndBanning failedPasswordAuthentication(User user) {
|
||||
public TimedLock failedPasswordAuthentication(User user) {
|
||||
return apply(s->s.internalFailedPasswordAuthentication(user.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingAndBanning internalFailedPasswordAuthentication(String username) {
|
||||
public TimedLock internalFailedPasswordAuthentication(String username) {
|
||||
final User user = getUserByName(username);
|
||||
final LockingAndBanning lockingAndBanning;
|
||||
final TimedLock timedLock;
|
||||
if (user != null) {
|
||||
lockingAndBanning = user.getLockingAndBanning();
|
||||
lockingAndBanning.failedPasswordAuthentication();
|
||||
timedLock = user.getTimedLock();
|
||||
timedLock.extendLockDuration();
|
||||
store.updateUser(user);
|
||||
logger.info("failed password authentication for user "+username+"; locking: "+lockingAndBanning);
|
||||
logger.info("failed password authentication for user "+username+"; locking: "+timedLock);
|
||||
} else {
|
||||
lockingAndBanning = null;
|
||||
timedLock = null;
|
||||
}
|
||||
return lockingAndBanning;
|
||||
return timedLock;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1316,7 +1334,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
final boolean changed;
|
||||
final User user = getUserByName(username);
|
||||
if (user != null) {
|
||||
changed = user.getLockingAndBanning().successfulPasswordAuthentication();
|
||||
changed = user.getTimedLock().resetLock();
|
||||
if (changed) {
|
||||
store.updateUser(user);
|
||||
}
|
||||
@@ -1327,27 +1345,27 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingAndBanning failedBearerTokenAuthentication(String clientIP) {
|
||||
public TimedLock failedBearerTokenAuthentication(String clientIP) {
|
||||
return apply(s->s.internalFailedBearerTokenAuthentication(clientIP));
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockingAndBanning internalFailedBearerTokenAuthentication(String clientIP) {
|
||||
final LockingAndBanning lockingAndBanning = clientIPBasedLockingAndBanningForBearerTokenAuthentication.computeIfAbsent(escapeNullClientIP(clientIP), key->new LockingAndBanningImpl());
|
||||
lockingAndBanning.failedPasswordAuthentication();
|
||||
logger.info("failed bearer token authentication from client IP "+clientIP+"; locking: "+lockingAndBanning);
|
||||
scheduleCleanUpTask(clientIP, lockingAndBanning, clientIPBasedLockingAndBanningForBearerTokenAuthentication,
|
||||
public TimedLock internalFailedBearerTokenAuthentication(String clientIP) {
|
||||
final TimedLock timedLock = clientIPBasedTimedLocksForBearerTokenAuthentication.computeIfAbsent(escapeNullClientIP(clientIP), key->new TimedLockImpl());
|
||||
timedLock.extendLockDuration();
|
||||
logger.info("failed bearer token authentication from client IP "+clientIP+"; locking: "+timedLock);
|
||||
scheduleCleanUpTask(clientIP, timedLock, clientIPBasedTimedLocksForBearerTokenAuthentication,
|
||||
"client IPs locked for bearer token authentication");
|
||||
return lockingAndBanning;
|
||||
return timedLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a clean-up task to avoid leaking memory for the LockingAndBanning objects; schedule it in two times the
|
||||
* locking expiry of {@code lockingAndBanning}, but at least one hour, because if no authentication failure occurs
|
||||
* for that IP/user agent combination, we will entirely remove the {@link LockingAndBanning} from the map,
|
||||
* Schedule a clean-up task to avoid leaking memory for the TimedLock objects; schedule it in two times the
|
||||
* locking expiry of {@code timedLock}, but at least one hour, because if no authentication failure occurs
|
||||
* for that IP/user agent combination, we will entirely remove the {@link TimedLock} from the map,
|
||||
* effectively resetting that IP to a short default locking duration again; this way, if during the double
|
||||
* expiration time another failed attempt is registered, we can still grow the locking duration because we have kept
|
||||
* the {@link LockingAndBanning} object available for a bit longer. Furthermore, for authentication requests, the
|
||||
* the {@link TimedLock} object available for a bit longer. Furthermore, for authentication requests, the
|
||||
* responsible {@link Realm} will let authentication requests get to here only if not locked, so if we were to
|
||||
* expunge entries immediately as they unlock, the locking duration could never grow.<p>
|
||||
*
|
||||
@@ -1355,16 +1373,16 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
* expiry duration.
|
||||
*/
|
||||
private void scheduleCleanUpTask(final String clientIPOrNull,
|
||||
final LockingAndBanning lockingAndBanning,
|
||||
final ConcurrentMap<String, LockingAndBanning> mapToRemoveFrom,
|
||||
final TimedLock timedLock,
|
||||
final ConcurrentMap<String, TimedLock> mapToRemoveFrom,
|
||||
final String nameOfMapForLog) {
|
||||
final long millisUntilLockingExpiry = Math.max(
|
||||
2*ApproximateTime.approximateNow().until(lockingAndBanning.getLockedUntil()).asMillis(),
|
||||
2*ApproximateTime.approximateNow().until(timedLock.getLockedUntil()).asMillis(),
|
||||
Duration.ONE_HOUR.asMillis());
|
||||
ThreadPoolUtil.INSTANCE.getDefaultBackgroundTaskThreadPoolExecutor().schedule(
|
||||
()->{
|
||||
final LockingAndBanning lab = mapToRemoveFrom.get(escapeNullClientIP(clientIPOrNull));
|
||||
if (lab != null && !lab.isAuthenticationLocked()) {
|
||||
final TimedLock lab = mapToRemoveFrom.get(escapeNullClientIP(clientIPOrNull));
|
||||
if (lab != null && !lab.isLocked()) {
|
||||
mapToRemoveFrom.remove(escapeNullClientIP(clientIPOrNull));
|
||||
logger.info("Removed "+clientIPOrNull+" from "+nameOfMapForLog+"; "
|
||||
+mapToRemoveFrom.size()
|
||||
@@ -1389,9 +1407,9 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
@Override
|
||||
public Boolean internalSuccessfulBearerTokenAuthentication(String clientIP) {
|
||||
final boolean changed;
|
||||
final LockingAndBanning lockingAndBanning = clientIPBasedLockingAndBanningForBearerTokenAuthentication.remove(escapeNullClientIP(clientIP));
|
||||
if (lockingAndBanning != null) {
|
||||
logger.info("Unlocked bearer token authentication from "+clientIP+"; last locking state was "+lockingAndBanning);
|
||||
final TimedLock timedLock = clientIPBasedTimedLocksForBearerTokenAuthentication.remove(escapeNullClientIP(clientIP));
|
||||
if (timedLock != null) {
|
||||
logger.info("Unlocked bearer token authentication from "+clientIP+"; last locking state was "+timedLock);
|
||||
changed = true;
|
||||
} else {
|
||||
changed = false;
|
||||
@@ -1401,8 +1419,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
|
||||
@Override
|
||||
public boolean isClientIPLockedForBearerTokenAuthentication(String clientIP) {
|
||||
final LockingAndBanning lockingAndBanning = clientIPBasedLockingAndBanningForBearerTokenAuthentication.get(escapeNullClientIP(clientIP));
|
||||
return lockingAndBanning != null && lockingAndBanning.isAuthenticationLocked();
|
||||
final TimedLock timedLock = clientIPBasedTimedLocksForBearerTokenAuthentication.get(escapeNullClientIP(clientIP));
|
||||
return timedLock != null && timedLock.isLocked();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2501,8 +2519,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
store.clear();
|
||||
accessControlStore.clear();
|
||||
corsFilterConfigurationsByReplicaSetName.clear();
|
||||
clientIPBasedLockingAndBanningForBearerTokenAuthentication.clear();
|
||||
clientIPBasedLockingAndBanningForUserCreation.clear();
|
||||
clientIPBasedTimedLocksForBearerTokenAuthentication.clear();
|
||||
clientIPBasedTimedLocksForUserCreation.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2584,13 +2602,13 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
final SecurityServiceInitialLoadExtensionsDTO initialLoadExtensions = (SecurityServiceInitialLoadExtensionsDTO) is.readObject();
|
||||
final ConcurrentMap<String, Pair<Boolean, Set<String>>> newCORSFilterConfigurations = initialLoadExtensions.getCorsFilterConfigurationsByReplicaSetName();
|
||||
corsFilterConfigurationsByReplicaSetName.putAll(newCORSFilterConfigurations);
|
||||
if (initialLoadExtensions.getClientIPBasedLockingAndBanningForBearerTokenAuthentication() != null) {
|
||||
if (initialLoadExtensions.getClientIPBasedTimedLocksForBearerTokenAuthentication() != null) {
|
||||
// checking for null for backward compatibility; an older primary/master may not have known this field yet
|
||||
clientIPBasedLockingAndBanningForBearerTokenAuthentication.putAll(initialLoadExtensions.getClientIPBasedLockingAndBanningForBearerTokenAuthentication());
|
||||
clientIPBasedTimedLocksForBearerTokenAuthentication.putAll(initialLoadExtensions.getClientIPBasedTimedLocksForBearerTokenAuthentication());
|
||||
}
|
||||
if (initialLoadExtensions.getClientIPBasedLockingAndBanningForUserCreation() != null) {
|
||||
if (initialLoadExtensions.getClientIPBasedTimedLocksForUserCreation() != null) {
|
||||
// checking for null for backward compatibility; an older primary/master may not have known this field yet
|
||||
clientIPBasedLockingAndBanningForUserCreation.putAll(initialLoadExtensions.getClientIPBasedLockingAndBanningForUserCreation());
|
||||
clientIPBasedTimedLocksForUserCreation.putAll(initialLoadExtensions.getClientIPBasedTimedLocksForUserCreation());
|
||||
}
|
||||
logger.info("Triggering SecurityInitializationCustomizers upon replication ...");
|
||||
customizers.forEach(c -> c.customizeSecurityService(this));
|
||||
@@ -2606,8 +2624,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
objectOutputStream.writeObject(baseUrlForCrossDomainStorage);
|
||||
objectOutputStream.writeObject(new SecurityServiceInitialLoadExtensionsDTO(
|
||||
corsFilterConfigurationsByReplicaSetName,
|
||||
clientIPBasedLockingAndBanningForBearerTokenAuthentication,
|
||||
clientIPBasedLockingAndBanningForUserCreation));
|
||||
clientIPBasedTimedLocksForBearerTokenAuthentication,
|
||||
clientIPBasedTimedLocksForUserCreation));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2914,8 +2932,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
|
||||
// See com.sap.sse.security.impl.Activator.clearState(), moved due to required reinitialisation sequence for
|
||||
// permission-vertical
|
||||
public void clearState() throws Exception {
|
||||
clientIPBasedLockingAndBanningForBearerTokenAuthentication.clear();
|
||||
clientIPBasedLockingAndBanningForUserCreation.clear();
|
||||
clientIPBasedTimedLocksForBearerTokenAuthentication.clear();
|
||||
clientIPBasedTimedLocksForUserCreation.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
-11
@@ -9,7 +9,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.replication.Replicable;
|
||||
import com.sap.sse.security.SecurityService;
|
||||
import com.sap.sse.security.shared.impl.LockingAndBanning;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
|
||||
/**
|
||||
* Starting with the CORS filter configurations, this and future extensions of the {@link SecurityService}'s
|
||||
@@ -30,28 +30,28 @@ public class SecurityServiceInitialLoadExtensionsDTO implements Serializable {
|
||||
|
||||
private final ConcurrentMap<String, Pair<Boolean, Set<String>>> corsFilterConfigurationsByReplicaSetName;
|
||||
|
||||
private final ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForBearerTokenAuthentication;
|
||||
private final ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForBearerTokenAuthentication;
|
||||
|
||||
private final ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForUserCreation;
|
||||
private final ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForUserCreation;
|
||||
|
||||
public SecurityServiceInitialLoadExtensionsDTO(ConcurrentMap<String, Pair<Boolean, Set<String>>> corsFilterConfigurationsByReplicaSetName,
|
||||
ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForBearerTokenAuthentication,
|
||||
ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForUserCreation) {
|
||||
ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForBearerTokenAuthentication,
|
||||
ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForUserCreation) {
|
||||
super();
|
||||
this.corsFilterConfigurationsByReplicaSetName = corsFilterConfigurationsByReplicaSetName;
|
||||
this.clientIPBasedLockingAndBanningForBearerTokenAuthentication = clientIPBasedLockingAndBanningForBearerTokenAuthentication;
|
||||
this.clientIPBasedLockingAndBanningForUserCreation = clientIPBasedLockingAndBanningForUserCreation;
|
||||
this.clientIPBasedTimedLocksForBearerTokenAuthentication = clientIPBasedTimedLocksForBearerTokenAuthentication;
|
||||
this.clientIPBasedTimedLocksForUserCreation = clientIPBasedTimedLocksForUserCreation;
|
||||
}
|
||||
|
||||
ConcurrentMap<String, Pair<Boolean, Set<String>>> getCorsFilterConfigurationsByReplicaSetName() {
|
||||
return corsFilterConfigurationsByReplicaSetName;
|
||||
}
|
||||
|
||||
ConcurrentMap<String, LockingAndBanning> getClientIPBasedLockingAndBanningForBearerTokenAuthentication() {
|
||||
return clientIPBasedLockingAndBanningForBearerTokenAuthentication;
|
||||
ConcurrentMap<String, TimedLock> getClientIPBasedTimedLocksForBearerTokenAuthentication() {
|
||||
return clientIPBasedTimedLocksForBearerTokenAuthentication;
|
||||
}
|
||||
|
||||
ConcurrentMap<String, LockingAndBanning> getClientIPBasedLockingAndBanningForUserCreation() {
|
||||
return clientIPBasedLockingAndBanningForUserCreation;
|
||||
ConcurrentMap<String, TimedLock> getClientIPBasedTimedLocksForUserCreation() {
|
||||
return clientIPBasedTimedLocksForUserCreation;
|
||||
}
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.sap.sse.security.operations;
|
||||
|
||||
import com.sap.sse.security.impl.ReplicableSecurityService;
|
||||
import com.sap.sse.security.shared.impl.TimedLock;
|
||||
|
||||
public class ResetUserLockOperation implements SecurityOperation<Void> {
|
||||
private static final long serialVersionUID = -6267523788529623080L;
|
||||
protected final TimedLock timedLock;
|
||||
protected final String username;
|
||||
|
||||
public ResetUserLockOperation(String username, TimedLock timedLock) {
|
||||
this.username = username;
|
||||
this.timedLock = timedLock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void internalApplyTo(ReplicableSecurityService toState) throws Exception {
|
||||
toState.internalResetUserTimedLock(username);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
|
||||
securityManager.sessionManager.globalSessionTimeout = 31536000000
|
||||
cacheManager = com.sap.sse.security.SessionCacheManager
|
||||
securityManager.cacheManager = $cacheManager
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
|
||||
authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
|
||||
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
|
||||
|
||||
# Support for anonymous user permissions
|
||||
|
||||
Reference in New Issue
Block a user