added more test data; factored the -tenant suffix into a constant

This commit is contained in:
Axel Uhl committed 2019-11-25 17:24:51 +01:00
1 parent fd9a15bb58
commit 53f61a2e7a
19 files changed
+119 -63

No files matched your search

@@ -47,6 +47,7 @@ import com.sap.sse.common.Color;
import com.sap.sse.common.Duration;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
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;
@@ -108,7 +109,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
DomainFactory receiverDomainFactory = new DomainFactoryImpl(DomainFactory.TEST_RACE_LOG_RESOLVER);
UserStore userStore = new UserStoreImpl("defaultTenant");
userStore.clear();
UserGroup defaultTenant = userStore.createUserGroup(UUID.randomUUID(), "admin-tenant");
UserGroup defaultTenant = userStore.createUserGroup(UUID.randomUUID(), "admin"+SecurityService.TENANT_SUFFIX);
User user = userStore.createUser("admin", "");
defaultTenant.add(user);
userStore.updateUserGroup(defaultTenant);
@@ -44,6 +44,7 @@ import com.sap.sailing.selenium.api.regatta.RegattaDeviceStatus.CompetitorDevice
import com.sap.sailing.selenium.api.regatta.RegattaRaces;
import com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage;
import com.sap.sailing.selenium.test.AbstractSeleniumTest;
import com.sap.sse.security.SecurityService;
public class RegattaApiTest extends AbstractSeleniumTest {
@@ -181,7 +182,7 @@ public class RegattaApiTest extends AbstractSeleniumTest {
Competitor competitor = regattaApi.createAndAddCompetitor(userWithCompetitorCtx, EVENT_NAME, BOAT_CLASS, null, "donald", "USA");
// ensure the reader can actually see the competitor
UserGroup group = usergroupApi.getUserGroupByName(userWithCompetitorAndSecurityCtx, "donald-tenant");
UserGroup group = usergroupApi.getUserGroupByName(userWithCompetitorAndSecurityCtx, "donald"+SecurityService.TENANT_SUFFIX);
usergroupApi.addRoleToGroup(userWithCompetitorAndSecurityCtx, group.getGroupId(),
UUID.fromString(/* sailing viewer role id */"c42948df-517b-45cb-9fa9-d1e79f18e115"), true);
@@ -219,7 +220,7 @@ public class RegattaApiTest extends AbstractSeleniumTest {
"donald", "USA");
// ensure the reader can actually see the competitor
UserGroup group = usergroupApi.getUserGroupByName(userWithCompetitorAndSecurityCtx, "donald-tenant");
UserGroup group = usergroupApi.getUserGroupByName(userWithCompetitorAndSecurityCtx, "donald"+SecurityService.TENANT_SUFFIX);
usergroupApi.addRoleToGroup(userWithCompetitorAndSecurityCtx, group.getGroupId(),
UUID.fromString(/* sailing viewer role id */"c42948df-517b-45cb-9fa9-d1e79f18e115"), true);
@@ -32,18 +32,18 @@ public abstract class AbstractSecurityReplicationTest extends AbstractServerWith
}
@Override
protected SecurityServiceImpl createNewMaster() throws MalformedURLException, IOException, InterruptedException,
protected SecurityService createNewMaster() throws MalformedURLException, IOException, InterruptedException,
UserManagementException, MailException, UserGroupManagementException {
final UserStoreImpl userStore = new UserStoreImpl("TestDefaultTenant");
userStore.ensureDefaultRolesExist();
userStore.loadAndMigrateUsers();
final AccessControlStore accessControlStore = new AccessControlStoreImpl(userStore);
SecurityServiceImpl result = new SecurityServiceImpl(userStore, accessControlStore);
SecurityService result = new SecurityServiceImpl(userStore, accessControlStore);
return result;
}
@Override
protected SecurityServiceImpl createNewReplica() throws UserGroupManagementException, UserManagementException, MalformedURLException, IOException, InterruptedException {
protected SecurityService createNewReplica() throws UserGroupManagementException, UserManagementException, MalformedURLException, IOException, InterruptedException {
final UserStoreImpl userStore = new UserStoreImpl("TestDefaultTenant");
userStore.ensureDefaultRolesExist();
userStore.loadAndMigrateUsers();
@@ -51,7 +51,7 @@ public class SecurityReplicationLeadingToEmailReplicationTest extends AbstractSe
private class SecurityServerReplicationTestSetUp extends
AbstractSecurityReplicationTest.SecurityServerReplicationTestSetUp {
@Override
protected SecurityServiceImpl createNewMaster() throws MalformedURLException, IOException, InterruptedException, UserGroupManagementException, UserManagementException {
protected SecurityService createNewMaster() throws MalformedURLException, IOException, InterruptedException, UserGroupManagementException, UserManagementException {
@SuppressWarnings("unchecked")
ServiceTracker<MailService, MailService> trackerMock = mock(ServiceTracker.class);
doReturn(masterMailService).when(trackerMock).getService();
@@ -59,19 +59,19 @@ public class SecurityReplicationLeadingToEmailReplicationTest extends AbstractSe
userStore.ensureDefaultRolesExist();
userStore.loadAndMigrateUsers();
final AccessControlStore accessControlStore = new AccessControlStoreImpl(userStore);
SecurityServiceImpl result = new SecurityServiceImpl(trackerMock, userStore, accessControlStore);
SecurityService result = new SecurityServiceImpl(trackerMock, userStore, accessControlStore);
result.initialize();
return result;
}
@Override
protected SecurityServiceImpl createNewReplica() throws UserGroupManagementException, UserManagementException, MalformedURLException, IOException, InterruptedException {
protected SecurityService createNewReplica() throws UserGroupManagementException, UserManagementException, MalformedURLException, IOException, InterruptedException {
@SuppressWarnings("unchecked")
ServiceTracker<MailService, MailService> trackerMock = mock(ServiceTracker.class);
doReturn(replicaMailService).when(trackerMock).getService();
final UserStoreImpl userStore = new UserStoreImpl("TestDefaultTenant");
final AccessControlStore accessControlStore = new AccessControlStoreImpl(userStore);
SecurityServiceImpl result = new SecurityServiceImpl(trackerMock, userStore, accessControlStore);
SecurityService result = new SecurityServiceImpl(trackerMock, userStore, accessControlStore);
userStore.ensureDefaultRolesExist();
userStore.ensureDefaultTenantExists();
result.initialize();
@@ -31,7 +31,7 @@ public class SecurityServiceInitialLoadTest extends AbstractServerWithSingleServ
public SecurityServiceInitialLoadTest() {
super(new AbstractSecurityReplicationTest.SecurityServerReplicationTestSetUp() {
@Override
protected SecurityServiceImpl createNewMaster()
protected SecurityService createNewMaster()
throws MalformedURLException, IOException, InterruptedException, UserManagementException, MailException, UserGroupManagementException {
final UserStore userStore = new UserStoreImpl(PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(),
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), "TestDefaultTenant");
@@ -39,7 +39,7 @@ public class SecurityServiceInitialLoadTest extends AbstractServerWithSingleServ
userStore.loadAndMigrateUsers();
final AccessControlStore accessControlStore = new AccessControlStoreImpl(PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(),
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), userStore);
final SecurityServiceImpl newMaster = new SecurityServiceImpl(userStore, accessControlStore);
final SecurityService newMaster = new SecurityServiceImpl(userStore, accessControlStore);
newMaster.createSimpleUser(username, email, password, fullName, company,
/* validationBaseURL */ Locale.ENGLISH, null, null);
accessToken = newMaster.createAccessToken(username);
@@ -1,15 +1,23 @@
package com.sap.sse.security.storemerging;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.UUID;
import org.bson.Document;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.mongodb.MongoClientURI;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.mongodb.MongoDBConfiguration;
import com.sap.sse.security.interfaces.AccessControlStore;
@@ -35,6 +43,11 @@ public class TestSimpleUserAndPreferenceMerge {
cfgForSource = new MongoDBConfiguration(new MongoClientURI(importSourceMongoDbUri));
fill("source1", cfgForSource.getService().getDB());
}
@After
public void tearDown() {
cfgForSource.getService().getDB().drop();
}
private void fill(final String variant, final MongoDatabase db) throws IOException {
for (final CollectionNames collectionName : new CollectionNames[] { CollectionNames.USERS,
@@ -52,11 +65,44 @@ public class TestSimpleUserAndPreferenceMerge {
filler.fill(collection, "/resources/"+collectionName.name()+"_"+variant+".json");
}
@Test
public void testGroupIdentity() {
// TODO test SecurityStoreMerger.considerGroupsIdentical...
}
@Test
public void testImportFromSource1ToTarget1() throws UserGroupManagementException, UserManagementException {
final SecurityStoreMerger merger = new SecurityStoreMerger(cfgForTarget, defaultCreationGroupNameForTarget);
final Pair<UserStore, AccessControlStore> sourceStores = merger.importStores(cfgForSource, defaultCreationGroupNameForSource);
final UserStore targetUserStore = merger.getTargetUserStore();
assertNotNull(targetUserStore.getUserByName("admin"));
assertNotNull(targetUserStore.getUserByName("<all>"));
assertNotNull(targetUserStore.getUserByName("uhl"));
assertNotNull(targetUserStore.getUserByName("uhl2"));
assertNotNull(targetUserStore.getUserByName("axel.uhl"));
assertNotNull(targetUserStore.getUserByName("axel"));
assertNotNull(targetUserStore.getUserByName("YCaT"));
assertNotNull(targetUserStore.getUserByName("YCaT-member1"));
assertNotNull(targetUserStore.getUserByName("YCaT-member2"));
assertNotNull(targetUserStore.getUserByName("uhl3"));
assertNull(targetUserStore.getUserByName("uhl4"));
assertEquals(1, Util.size(targetUserStore.getUserGroupByName("uhl-tenant").getUsers()));
assertSame(targetUserStore.getUserByName("uhl"), targetUserStore.getUserGroupByName("uhl-tenant").getUsers().iterator().next());
final AccessControlStore targetAccessControlStore = merger.getTargetAccessControlStore();
final Pair<UserStore, AccessControlStore> sourceStores = merger.importStores(cfgForSource, defaultCreationGroupNameForSource);
final UserStore sourceUserStore = sourceStores.getA();
final AccessControlStore sourceAccessControlStore = sourceStores.getB();
assertNotNull(sourceUserStore.getUserByName("admin"));
assertNotNull(sourceUserStore.getUserByName("<all>"));
assertNotNull(sourceUserStore.getUserByName("uhl"));
assertNotNull(sourceUserStore.getUserByName("uhl3"));
assertNotNull(sourceUserStore.getUserByName("axel.uhl"));
assertNotNull(sourceUserStore.getUserByName("uhl4"));
// check result in target user store:
assertNotNull(targetUserStore.getUserByName("uhl3"));
assertNotNull(targetUserStore.getUserByName("uhl4")); // in particular new user uhl4 is expected to be present now
// the uhl-tenant group is expected to have been merged: the uhl4 user is part of that group in source1
assertEquals(2, Util.size(targetUserStore.getUserGroupByName("uhl-tenant").getUsers()));
assertTrue(Util.contains(targetUserStore.getUserGroupByName("uhl-tenant").getUsers(), targetUserStore.getUserByName("uhl")));
assertTrue(Util.contains(targetUserStore.getUserGroupByName("uhl-tenant").getUsers(), targetUserStore.getUserByName("uhl4")));
}
}
@@ -1 +1,2 @@
{ "_id" : ObjectId("5da986e1bcba5dcf9b934d8f"), "KEYS_AND_VALUES" : [ ], "USERNAME" : "admin" }
{ "_id" : ObjectId("5da986e1bcba5dcf9b934d8f"), "KEYS_AND_VALUES" : [ { "KEY" : "sailing.notifications.boatclasses", "VALUE" : "{}" }], "USERNAME" : "admin" }
{ "_id" : ObjectId("5d1cd3d24da9676dd43758f2"), "KEYS_AND_VALUES" : [ { "KEY" : "sailing.notifications.boatclasses", "VALUE" : "{}" }, { "KEY" : "sailing.ui.usersettings.EventRegattaLeaderboard#Ilonas Test Training (SPT)", "VALUE" : "{\"maneuverDetailsToShow\":{\"added\":[\"AVERAGE_TACK_LOSS_IN_METERS\"]}, \"raceDetailsToShow\":{\"added\":[\"RACE_GAP_TO_LEADER_IN_SECONDS\",\"RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS\",\"RACE_DISTANCE_TRAVELED\",\"RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START\",\"RACE_TIME_TRAVELED\",\"START_TACK\"]}, \"overallDetailsToShow\":{\"added\":[\"TOTAL_DISTANCE_TRAVELED\",\"TOTAL_AVERAGE_SPEED_OVER_GROUND\",\"TOTAL_TIME_SAILED_IN_SECONDS\"]}}" } ], "USERNAME" : "uhl" }
@@ -1,10 +1,6 @@
{"_id":{"$oid":"5cc705d4de317c784dcfaa1b"},"NAME":"admin","EMAIL":"nobody@sapsailing.com","FULLNAME":null,"COMPANY":null,"LOCALE":"en","EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":"sG1bZKmcx+pnUoxZwOu/qcSRfyH5Qz3Ywynx7xMlWqQ=","ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"admin","SALTED_PW":"jI9O5lgCLijLNi1/a1axMMncnX4RMpuUshSWWBl5LL0=","SALT":{"$binary":"3ENx8+Hk7x9MCet3viw0mA==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"6EebpIpumACftfJFNiaNiQ==","$type":"03"},"QUALIFYING_TENANT_NAME":"admin-tenant","QUALIFYING_USERNAME":null},{"ID":{"$binary":"XkMF1NHjd9x6/fZFcs6Zhg==","$type":"03"},"NAME":"admin","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":null},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"admin"}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"rETsHTQ95gY+uXNud+k2qg==","$type":"03"}}]}
{"_id":{"$oid":"5cc705d4de317c784dcfaa42"},"NAME":"\u003call\u003e","EMAIL":null,"FULLNAME":null,"COMPANY":null,"LOCALE":null,"EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{},"ROLE_IDS":[],"PERMISSIONS":["USER:CREATE"],"DEFAULT_TENANT_IDS":[]}
{"_id":{"$oid":"5d13ef6fe14e8d1caca94206"},"NAME":"uhl","EMAIL":"axel.uhl@sap.com.","FULLNAME":"Axel Uhl","COMPANY":"SAP SE","LOCALE":null,"EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":"UguoFG9fVhwZBDCbAOy+mdvoZxympJm3vXG2X8MMVKg=","ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"uhl","SALTED_PW":"5rasplWxI4hah5/SHE1fTu8OJcYwbVJYueyhNaNkGAA=","SALT":{"$binary":"pZTmZ4CZIllGjwrF5PUwrw==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"uhl"}],"PERMISSIONS":["MANAGE_DEVICE_CONFIGURATION:*:*","leaderboard:update:*"],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"rETsHTQ95gY+uXNud+k2qg==","$type":"03"}}]}
{"_id":{"$oid":"5d1728d4e14e8d1caca9c9f6"},"NAME":"uhl2","EMAIL":"axel.uhl@sap.com","FULLNAME":"Axel Uhl","COMPANY":"","LOCALE":"en","EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"uhl2","SALTED_PW":"3qW7i+lIuLPso7VQRmPvGuVQ99tGDB/X/RiHnWXJXso=","SALT":{"$binary":"TEgyKBFd+cxe4vpV63N1Yg==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"uhl2"},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"4U5+98apCi7bjpVjY+Zzgw==","$type":"03"},"QUALIFYING_TENANT_NAME":"uhl2-tenant","QUALIFYING_USERNAME":null}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"4U5+98apCi7bjpVjY+Zzgw==","$type":"03"}}]}
{"_id":{"$oid":"5d1cd5144da9676dd4375a6d"},"NAME":"axel.uhl","EMAIL":"axel.uhl@gmx.de","FULLNAME":"Dr. Axel Uhl","COMPANY":"SAP SE","LOCALE":null,"EMAIL_VALIDATED":true,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"axel.uhl","SALTED_PW":"V/Np8tG9fV3PVU5tL7vLaGgAQWlWuYX1SpxElnnvT4k=","SALT":{"$binary":"J0o9yTcZd6SZBQhb4MbS5Q==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"axel.uhl"},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"N0L9xnOMv7pi1iTGc3kjng==","$type":"03"},"QUALIFYING_TENANT_NAME":"axel.uhl-tenant","QUALIFYING_USERNAME":null}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"N0L9xnOMv7pi1iTGc3kjng==","$type":"03"}}]}
{"_id":{"$oid":"5d1cd5ab4da9676dd4375acc"},"NAME":"axel","EMAIL":"axel.uhl@gmx.de","FULLNAME":"A.U.","COMPANY":"","LOCALE":null,"EMAIL_VALIDATED":true,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"axel","SALTED_PW":"v0Qwj7gJnm8y3CGEibB38ilacyQ5sZeNE2assN78WMA=","SALT":{"$binary":"v2bmImY9V59f4oBIzTBZ2A==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"axel"},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"M0h+luarPKu9cwLl7VMgow==","$type":"03"},"QUALIFYING_TENANT_NAME":"axel-tenant","QUALIFYING_USERNAME":null}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"rETsHTQ95gY+uXNud+k2qg==","$type":"03"}}]}
{"_id":{"$oid":"5d4009a208cb8682ff9323b2"},"NAME":"YCaT","EMAIL":"axel.uhl@sap.com","FULLNAME":"YCaT Admin","COMPANY":"Test","LOCALE":"en","EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"YCaT","SALTED_PW":"LdoXZ3Fh3DbGWK1ptIrcj6El/mfz8d6pPln2QhaeDbY=","SALT":{"$binary":"95aG7gMwbQBAvoNv+vvzCQ==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"YCaT"},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"3UJljSIS+HF/ErXi+384tQ==","$type":"03"},"QUALIFYING_TENANT_NAME":"YCaT-tenant","QUALIFYING_USERNAME":null}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"3UJljSIS+HF/ErXi+384tQ==","$type":"03"}}]}
{"_id":{"$oid":"5d4009d208cb8682ff9323f7"},"NAME":"YCaT-member1","EMAIL":"axel.uhl@sap.com","FULLNAME":"Member1","COMPANY":"Test","LOCALE":"en","EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":"YBKL7O7Lyy8JGGF/1FypxT1owf1w0YUi0YjKJgHmTy0=","ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"YCaT-member1","SALTED_PW":"JBasBBUAMi0ux25cDbEEgsnRzSowknl9IHiyFws8DSQ=","SALT":{"$binary":"L0cJJVJjDA55KY7sT0+S3g==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"2U356l9Qpux0vdp48SvQmg==","$type":"03"},"QUALIFYING_TENANT_NAME":"YCaT-member1-tenant","QUALIFYING_USERNAME":null},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"3UJljSIS+HF/ErXi+384tQ==","$type":"03"},"QUALIFYING_TENANT_NAME":"YCaT-tenant","QUALIFYING_USERNAME":null},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"YCaT-member1"}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"2U356l9Qpux0vdp48SvQmg==","$type":"03"}}]}
{"_id":{"$oid":"5d4009ec08cb8682ff932430"},"NAME":"YCaT-member2","EMAIL":"axel.uhl@sap.com","FULLNAME":"Member2","COMPANY":"Test","LOCALE":"en","EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":"bRSk4GLUIdDzOFyQLJmYm+/VynPgisZF7V0gPFoih3g=","ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"YCaT-member2","SALTED_PW":"DRyn1o5elCs8maUXyVvdyYK3/hmox56Po6wwq3Pm/u0=","SALT":{"$binary":"PicBhfFxcspHMo/vuP4Bnw==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"3UJljSIS+HF/ErXi+384tQ==","$type":"03"},"QUALIFYING_TENANT_NAME":"YCaT-tenant","QUALIFYING_USERNAME":null},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"YCaT-member2"},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"qUGQhinRsAx4MKAHHEr7gA==","$type":"03"},"QUALIFYING_TENANT_NAME":"YCaT-member2-tenant","QUALIFYING_USERNAME":null}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"qUGQhinRsAx4MKAHHEr7gA==","$type":"03"}}]}
{"_id":{"$oid":"5dc1af0fc0825924ce57c9ee"},"NAME":"uhl3","EMAIL":"axel.uhl@sap.com","FULLNAME":null,"COMPANY":null,"LOCALE":null,"EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"uhl3","SALTED_PW":"aCdc8Fg4bwtsa8l4HZT7qPFFqovDd1DhXpMv0OOxQ4I=","SALT":{"$binary":"xynScLlhqOODM17XhH5ucQ==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"uhl3"},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"hkaUvtuvRHho1Mo2bgQwow==","$type":"03"},"QUALIFYING_TENANT_NAME":"uhl3-tenant","QUALIFYING_USERNAME":null}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"hkaUvtuvRHho1Mo2bgQwow==","$type":"03"}}]}
{"_id":{"$oid":"5cc705d4de3123784dcfaa1b"},"NAME":"admin","EMAIL":"nobody@sapsailing.com","FULLNAME":null,"COMPANY":null,"LOCALE":"en","EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":"sG1bZKmcx+pnUoxZwOu/qcSRfyH5Qz3Ywynx7xMlWqQ=","ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"admin","SALTED_PW":"jI9O5lgCLijLNi1/a1axMMncnX4RMpuUshSWWBl5LL0=","SALT":{"$binary":"3ENx8+Hk7x9MCet3viw0mA==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"6EebpIpumACftfJFNiaNiQ==","$type":"03"},"QUALIFYING_TENANT_NAME":"admin-tenant","QUALIFYING_USERNAME":null},{"ID":{"$binary":"XkMF1NHjd9x6/fZFcs6Zhg==","$type":"03"},"NAME":"admin","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":null},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"admin"}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"rETsHTQ95gY+uXNud+k2qg==","$type":"03"}}]}
{"_id":{"$oid":"5cc705d4de3234784dcfaa42"},"NAME":"\u003call\u003e","EMAIL":null,"FULLNAME":null,"COMPANY":null,"LOCALE":null,"EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{},"ROLE_IDS":[],"PERMISSIONS":["USER:CREATE"],"DEFAULT_TENANT_IDS":[]}
{"_id":{"$oid":"5d13ef6fe1345d1caca94206"},"NAME":"uhl","EMAIL":"axel.uhl@sap.com.","FULLNAME":"Axel Uhl","COMPANY":"SAP SE","LOCALE":null,"EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":"UguoFG9fVhwZBDCbAOy+mdvoZxympJm3vXG2X8MMVKg=","ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"uhl","SALTED_PW":"5rasplWxI4hah5/SHE1fTu8OJcYwbVJYueyhNaNkGAA=","SALT":{"$binary":"pZTmZ4CZIllGjwrF5PUwrw==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"uhl"}],"PERMISSIONS":["MANAGE_DEVICE_CONFIGURATION:*:*","leaderboard:update:*"],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"rETsHTQ95gY+uXNud+k2qg==","$type":"03"}}]}
{"_id":{"$oid":"5d1728d4e1456d1caca9c9f6"},"NAME":"uhl3","EMAIL":"axel.uhl@sap.com","FULLNAME":"Axel Uhl","COMPANY":"","LOCALE":"en","EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"uhl3","SALTED_PW":"3qW7i+lIuLPso7VQRmPvGuVQ99tGDB/X/RiHnWXJXso=","SALT":{"$binary":"TEgyKBFd+cxe4vpV63N1Yg==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"uhl3"},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"4U5+98apCi7bjpVjY+Zzgw==","$type":"03"},"QUALIFYING_TENANT_NAME":"uhl3-tenant","QUALIFYING_USERNAME":null}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"4U5+98apCi7bjpVjY+Zzgw==","$type":"03"}}]}
{"_id":{"$oid":"5d1cd5144d56776dd4375a6d"},"NAME":"axel.uhl","EMAIL":"axel@example.com","FULLNAME":"Dr. Axel Uhl","COMPANY":"SAP SE","LOCALE":null,"EMAIL_VALIDATED":true,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"axel.uhl","SALTED_PW":"V/Np8tG9fV3PVU5tL7vLaGgAQWlWuYX1SpxElnnvT4k=","SALT":{"$binary":"J0o9yTcZd6SZBQhb4MbS5Q==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"axel.uhl"},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"N0L9xnOMv7pi1iTGc3kjng==","$type":"03"},"QUALIFYING_TENANT_NAME":"axel.uhl-tenant","QUALIFYING_USERNAME":null}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"N0L9xnOMv7pi1iTGc3kjng==","$type":"03"}}]}
{"_id":{"$oid":"5d1728d4e1678d1caca9c9f6"},"NAME":"uhl4","EMAIL":"uhl4@example.com","FULLNAME":"Axel Uhl","COMPANY":"","LOCALE":"en","EMAIL_VALIDATED":false,"PASSWORD_RESET_SECRET":null,"VALIDATION_SECRET":null,"ACCOUNTS":{"USERNAME_PASSWORD":{"NAME":"uhl4","SALTED_PW":"3qW7i+lIuLPso7VQRmPvGuVQ99tGDB/X/RiHnWXJXso=","SALT":{"$binary":"TEgyKBFd+cxe4vpV63N1Yg==","$type":"00"}}},"ROLE_IDS":[{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":null,"QUALIFYING_TENANT_NAME":null,"QUALIFYING_USERNAME":"uhl4"},{"ID":{"$binary":"ZEQ9sUhRHa0uTk1uOXzEkA==","$type":"03"},"NAME":"user","QUALIFYING_TENANT_ID":{"$binary":"4U5+98apCi7bjpVjY+Zzgw==","$type":"03"},"QUALIFYING_TENANT_NAME":"uhl4-tenant","QUALIFYING_USERNAME":null}],"PERMISSIONS":[],"DEFAULT_TENANT_IDS":[{"DEFAULT_TENANT_SERVER":"unknown server name","DEFAULT_TENANT_GROUP":{"$binary":"4U5+98apCi7bjpVjY+Zzgw==","$type":"03"}}]}
@@ -1,15 +1,3 @@
{ "_id" : ObjectId("5da642dbbcba5dcf9b8986f7"), "ID" : BinData(3,"2UkTqzNgD1UjE7TYQaZPvw=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da6f2d7bcba5dcf9b89aeec"), "ID" : BinData(3,"0kXofM2ReYsRD+CRNVrPlQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da986c7bcba5dcf9b934ca8"), "ID" : BinData(3,"eUGuvd970yv9eqpCzb0Znw=="), "NAME" : "unknown server name-server", "USERNAMES" : [ ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da986d6bcba5dcf9b934d0e"), "ID" : BinData(3,"rU3mZkIKAPCQHdkh9Ai0kQ=="), "NAME" : "unknown server name-server", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ { "ROLE_DEFINITION_MAP_ROLE_ID" : BinData(3,"y0V7Ud9IKcQV4Rif59Gpnw=="), "ROLE_DEFINITION_MAP_FOR_ALL" : true } ]}
{ "_id" : ObjectId("5da986d6bcba5dcf9b934d28"), "ID" : BinData(3,"KU+/j3USwWyRSybtIG+juQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da986f7bcba5dcf9b934dc1"), "ID" : BinData(3,"fEoAyL0wNLMctIVFTcjDjA=="), "NAME" : "unknown server name-server", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ { "ROLE_DEFINITION_MAP_ROLE_ID" : BinData(3,"y0V7Ud9IKcQV4Rif59Gpnw=="), "ROLE_DEFINITION_MAP_FOR_ALL" : true } ]}
{ "_id" : ObjectId("5da986f7bcba5dcf9b934dca"), "ID" : BinData(3,"cEvfLbXYDxBgv5r8ldEVgQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da9873dbcba5dcf9b934e5d"), "ID" : BinData(3,"KU3+yAcof3xfzrVBrJg4jg=="), "NAME" : "unknown server name-server", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ { "ROLE_DEFINITION_MAP_ROLE_ID" : BinData(3,"y0V7Ud9IKcQV4Rif59Gpnw=="), "ROLE_DEFINITION_MAP_FOR_ALL" : true } ]}
{ "_id" : ObjectId("5da9873dbcba5dcf9b934e66"), "ID" : BinData(3,"lEGQBz87sPN5v4IGhoW1qQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da98743bcba5dcf9b934f0e"), "ID" : BinData(3,"SEsB9kahnW2VVTitLEUHuQ=="), "NAME" : "unknown server name-server", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ { "ROLE_DEFINITION_MAP_ROLE_ID" : BinData(3,"y0V7Ud9IKcQV4Rif59Gpnw=="), "ROLE_DEFINITION_MAP_FOR_ALL" : true } ]}
{ "_id" : ObjectId("5da98743bcba5dcf9b934f17"), "ID" : BinData(3,"8EZHHRX/DX4FG6WrggGOhQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da9fb89bcba5dcf9b938693"), "ID" : BinData(3,"wk3t8bCm1eG/R26723mhtA=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5dadce46bcba5dcf9b93ee83"), "ID" : BinData(3,"h0wAowdQM9vgY14Qq073qw=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5db37397bcba5dcf9b94c226"), "ID" : BinData(3,"LUvZnBbBI48OvWErhOaUmw=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5dd40e69c0825924ce5b9544"), "ID" : BinData(3,"skegJZFkXU8DtJyTD+gUuw=="), "NAME" : "unknoan server name-server", "USERNAMES" : [ ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da642dbb8795dcf9b8986f7"), "ID" : BinData(3,"2UkTqzNgD1UjE7TYQaZPvw=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da642d888795dcf9b8986f7"), "ID" : BinData(3,"dkoh2nbqrGJvWKIHpYEqog=="), "NAME" : "uhl-tenant", "USERNAMES" : [ "uhl", "uhl4" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5d1728d4e14e8d1caca999fe"), "ID" : BinData(3,"M0h+luarPKu9cwLl7VMgow=="), "NAME" : "uhl2-tenant", "USERNAMES" : [ "uhl2" ], "ROLE_DEFINITION_MAP" : [ ] }
@@ -1,15 +1,3 @@
{ "_id" : ObjectId("5da642dbbcba5dcf9b8986f7"), "ID" : BinData(3,"2UkTqzNgD1UjE7TYQaZPvw=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da6f2d7bcba5dcf9b89aeec"), "ID" : BinData(3,"0kXofM2ReYsRD+CRNVrPlQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da986c7bcba5dcf9b934ca8"), "ID" : BinData(3,"eUGuvd970yv9eqpCzb0Znw=="), "NAME" : "unknown server name-server", "USERNAMES" : [ ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da986d6bcba5dcf9b934d0e"), "ID" : BinData(3,"rU3mZkIKAPCQHdkh9Ai0kQ=="), "NAME" : "unknown server name-server", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ { "ROLE_DEFINITION_MAP_ROLE_ID" : BinData(3,"y0V7Ud9IKcQV4Rif59Gpnw=="), "ROLE_DEFINITION_MAP_FOR_ALL" : true } ]}
{ "_id" : ObjectId("5da986d6bcba5dcf9b934d28"), "ID" : BinData(3,"KU+/j3USwWyRSybtIG+juQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da986f7bcba5dcf9b934dc1"), "ID" : BinData(3,"fEoAyL0wNLMctIVFTcjDjA=="), "NAME" : "unknown server name-server", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ { "ROLE_DEFINITION_MAP_ROLE_ID" : BinData(3,"y0V7Ud9IKcQV4Rif59Gpnw=="), "ROLE_DEFINITION_MAP_FOR_ALL" : true } ]}
{ "_id" : ObjectId("5da986f7bcba5dcf9b934dca"), "ID" : BinData(3,"cEvfLbXYDxBgv5r8ldEVgQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da9873dbcba5dcf9b934e5d"), "ID" : BinData(3,"KU3+yAcof3xfzrVBrJg4jg=="), "NAME" : "unknown server name-server", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ { "ROLE_DEFINITION_MAP_ROLE_ID" : BinData(3,"y0V7Ud9IKcQV4Rif59Gpnw=="), "ROLE_DEFINITION_MAP_FOR_ALL" : true } ]}
{ "_id" : ObjectId("5da9873dbcba5dcf9b934e66"), "ID" : BinData(3,"lEGQBz87sPN5v4IGhoW1qQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da98743bcba5dcf9b934f0e"), "ID" : BinData(3,"SEsB9kahnW2VVTitLEUHuQ=="), "NAME" : "unknown server name-server", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ { "ROLE_DEFINITION_MAP_ROLE_ID" : BinData(3,"y0V7Ud9IKcQV4Rif59Gpnw=="), "ROLE_DEFINITION_MAP_FOR_ALL" : true } ]}
{ "_id" : ObjectId("5da98743bcba5dcf9b934f17"), "ID" : BinData(3,"8EZHHRX/DX4FG6WrggGOhQ=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da9fb89bcba5dcf9b938693"), "ID" : BinData(3,"wk3t8bCm1eG/R26723mhtA=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5dadce46bcba5dcf9b93ee83"), "ID" : BinData(3,"h0wAowdQM9vgY14Qq073qw=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5db37397bcba5dcf9b94c226"), "ID" : BinData(3,"LUvZnBbBI48OvWErhOaUmw=="), "NAME" : "admin-tenant", "USERNAMES" : [ "admin" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5dd40e69c0825924ce5b9544"), "ID" : BinData(3,"skegJZFkXU8DtJyTD+gUuw=="), "NAME" : "unknoan server name-server", "USERNAMES" : [ ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5da642d777795dcf9b8986f7"), "ID" : BinData(3,"dkoh2nbqrGJvWKIHpYEqog=="), "NAME" : "uhl-tenant", "USERNAMES" : [ "uhl" ], "ROLE_DEFINITION_MAP" : [ ] }
{ "_id" : ObjectId("5d1728d4e14e8d1caca9c9fe"), "ID" : BinData(3,"4U5+98apCi7bjpVjY+Zzgw=="), "NAME" : "uhl2-tenant", "USERNAMES" : [ "uhl2" ], "ROLE_DEFINITION_MAP" : [ ] }
@@ -11,3 +11,4 @@ Require-Bundle: com.sap.sse.mongodb,
com.sap.sse.security.interface,
com.sap.sse.security.userstore.mongodb,
com.sap.sse.common
Import-Package: com.sap.sse.security
@@ -1,14 +1,18 @@
package com.sap.sse.security.storemerging;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.mongodb.MongoClientURI;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.mongodb.MongoDBConfiguration;
import com.sap.sse.security.SecurityService;
import com.sap.sse.security.interfaces.AccessControlStore;
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.UserGroup;
import com.sap.sse.security.userstore.mongodb.AccessControlStoreImpl;
import com.sap.sse.security.userstore.mongodb.PersistenceFactory;
import com.sap.sse.security.userstore.mongodb.UserStoreImpl;
@@ -26,8 +30,7 @@ public class SecurityStoreMerger {
logger.info("Loading target user store from "+cfgForTarget);
this.targetUserStore = loadUserStore(targetPf, targetDefaultCreationGroupName);
logger.info("Loading target access control store from "+cfgForTarget);
final AccessControlStore accessControlStore = loadAccessControlStore(targetPf, targetUserStore);
this.targetAccessControlStore = accessControlStore;
this.targetAccessControlStore = loadAccessControlStore(targetPf, targetUserStore);
}
private AccessControlStore loadAccessControlStore(final PersistenceFactory targetPf, UserStore userStore) {
@@ -109,6 +112,32 @@ public class SecurityStoreMerger {
// TODO Implement Main.mergeUsersAndGroups(...)
}
/**
* If the groups have equal {@link UserGroup#getId() IDs} then they are considered identical. If both groups have
* different IDs but equal names and the names match the pattern {@code <username>-tenant} and both contain a user
* named {@code <username>} then they will be considered identical, too. In all other cases they are considered
* distinct.
*/
boolean considerGroupsIdentical(final UserGroup g1, final UserGroup g2) {
final String g1TenantGroupUserName, g2TenantGroupUserName;
return g1.getId().equals(g2.getId()) ||
(g1TenantGroupUserName=getTenantGroupUserName(g1)) != null &&
(g2TenantGroupUserName=getTenantGroupUserName(g2)) != null &&
g1TenantGroupUserName.equals(g2TenantGroupUserName);
}
private static final Pattern tenantUserGroupNamePattern = Pattern.compile("(.*)*"+SecurityService.TENANT_SUFFIX);
private String getTenantGroupUserName(UserGroup g) {
final String result;
final Matcher matcher = tenantUserGroupNamePattern.matcher(g.getName());
if (matcher.matches()) {
result = matcher.group(1);
} else {
result = null;
}
return result;
}
private void mergePreferences(UserStore sourceUserStore) {
// TODO Implement Main.mergePreferences(...)
@@ -46,7 +46,7 @@ public class SecurityResourceTest {
private static final String USERNAME = "user-123";
private static final String PASSWORD = "pass-234";
private SecurityResource servlet;
private SecurityServiceImpl service;
private SecurityService service;
private Subject authenticatedAdmin;
private UserStore store;
private AccessControlStore accessControlStore;
@@ -516,7 +516,7 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
new Callable<User>() {
@Override
public User call() throws Exception {
if (userGroupExists(username + "-tenant")) {
if (userGroupExists(username + SecurityService.TENANT_SUFFIX)) {
throw new UserManagementException(
"User tenant already exists, please chose a different username!");
}
@@ -186,7 +186,7 @@ public class OAuthRealm extends AbstractCompositeAuthorizingRealm {
User user = getUserStore().getUserByName(socialname);
if (user == null) {
try {
UserGroup tenant = getUserStore().createUserGroup(UUID.randomUUID(), socialname + "-tenant");
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()), socialUser);
tenant.add(user);
@@ -61,6 +61,7 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
}
String ALL_USERNAME = "<all>";
String TENANT_SUFFIX = "-tenant";
SecurityManager getSecurityManager();
@@ -171,7 +171,7 @@ public class Activator implements BundleActivator {
final ServiceTracker<HasPermissionsProvider, HasPermissionsProvider> hasPermissionsProviderTracker = new ServiceTracker<>(
bundleContext, HasPermissionsProvider.class, /* customizer */ null);
hasPermissionsProviderTracker.open();
SecurityServiceImpl initialSecurityService = new SecurityServiceImpl(
SecurityService initialSecurityService = new SecurityServiceImpl(
ServiceTrackerFactory.createAndOpen(context, MailService.class), userStore, accessControlStore,
new OSGIHasPermissionsProvider(hasPermissionsProviderTracker), sharedAcrossSubdomainsOf, baseUrlForCrossDomainStorage);
initialSecurityService.initialize();
@@ -893,7 +893,7 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
}
private String getDefaultTenantNameForUsername(final String username) {
return username + "-tenant";
return username + TENANT_SUFFIX;
}
@Override
+7 -3
View File
@@ -256,7 +256,13 @@ Remaining to be added to the ``winddb`` content are the same collections from al
### Algorithm for Merging
Start with the ``USERS`` collection of the database to be merged. For each username check if that name already exists in the target collection into which to merge. If no, copy the record. If yes, log this and compare the e-mail addresses. If they do not match, log this because it is not clear the records belong to the same subject, and no merge attempt will be made. Otherwise, the merge process will consider the ``ROLE_IDS`` and ``PERMISSIONS`` fields, as well as the ``DEFAULT_TENANT_IDS`` field and will set the ``EMAIL_VALIDATED`` field to ``true`` if either one of the two was ``true``. For the role assignments we will make sure that no unqualified assignments are merged. Furthermore, a role referenced in the ``ROLE_IDS`` will only be merged if the role's ID exists in the target's ``ROLE_DEFINITIONS`` collection. According to the research above, only ``user``, ``admin`` and ``moderator`` assignments seem to exist and those are pre-defined roles that will exist in the target with the same IDs. During a merge we won't touch the account and password information. Users affected by a merge will therefore end up with the username/password combination they have on the ARCHIVE server. Should that be different and should they have forgotten, they can still recover the password.
We assume that no relevant additions have been made anywhere to the ``ROLES`` collection, so we don't bother copying or merging it.
We start with the ``USER_GROUPS`` collection. Groups will be copied if none with the same UUID or an equal name exists on the importing side. Should a user group with the same ID exist, their set of roles will be merged, and their set of users will be merged after the ``USERS`` collection has been merged (see below). If a user group exists on the importing side that has an equal name but a different ID, the groups will only be considered identical if their equal names have the format``"&lt;username&gt;-tenant"`` and a user named ``&lt;username&gt;`` exists in both groups. A warning will be issued if two equal-named groups are not considered identical because of differing UUIDs and not matching the ``*-tenant`` rule explained above.
Next, the ``USERS`` collection of the database will be merged. For each username check if that name already exists in the target collection into which to merge. If no, copy the record. If yes, log this and compare the e-mail addresses. If they do not match, log this because it is not clear the records belong to the same subject, and no merge attempt will be made. Otherwise, the merge process will consider the ``ROLE_IDS`` and ``PERMISSIONS`` fields, as well as the ``DEFAULT_TENANT_IDS`` field and will set the ``EMAIL_VALIDATED`` field to ``true`` if either one of the two was ``true``. For the role assignments we will make sure that no unqualified assignments are merged. Furthermore, a role referenced in the ``ROLE_IDS`` will only be merged if the role's ID exists in the target's ``ROLES`` collection (which should be the case by the assumption above that no extensions were made anywhere to the ``ROLES`` collection). According to the research above, only ``user``, ``admin`` and ``moderator`` assignments seem to exist and those are pre-defined roles that will exist in the target with the same IDs. During a merge we won't touch the account and password information. Users affected by a merge will therefore end up with the username/password combination they have on the ARCHIVE server. Should that be different and should they have forgotten, they can still recover the password.
After merging the ``USERS`` collection the ``USER_GROUPS`` users can be aligned. For all groups resulting from the group merge above the algorithm has to ensure that all users contained in a group on the imported side are also present in the respective group on the importing side.
Before merging a permission into the ``PERMISSIONS`` array of the ``USERS`` collection we have to ensure proper qualification. The ``SERVER:DATAMINING`` permission must be constrained to the server name from where the record is being merged. This can easiest be established by stepping through the permissions granted on the active servers to be merged. Only 49er, HNV, my, NOR, sailracer, SRV and VSAW have such records, and I'll qualify or remove any unqualified permissions. (Side note: currently, due to bug 5156 it is not possible to remove those erroneous permission assignments. However, a fix is underway with commit 841893528be759d11f776bb1c437e61ffc66dccf and as soon as a release becomes available we can upgrade the servers that require it.)
@@ -285,8 +291,6 @@ Cleaned up permissions as of 2019-11-15T23:50:00Z.
The ``PREFERENCES`` collection can be merged based on user name, such that in case of conflicting preference key the collection to merge into will "win."
Merging the ``USER_GROUPS`` collection should be straightforward. They will be copied if they don't exist on the importing side. Should a user group with the same ID exist, their set of users will be merged and their set of roles will be merged.
``OWNERSHIPS`` and ``ACCESS_CONTROL_LISTS`` need to be checked for conflicts in object IDs first... TODO
## Open Issues