Skip to content

Commit

Permalink
:fix: full alignment of domains between expected (declared in wiring)…
Browse files Browse the repository at this point in the history
… and present in the DB

Signed-off-by: dseurotech <[email protected]>
  • Loading branch information
dseurotech committed Jan 19, 2024
1 parent f603fc8 commit 395c45a
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import org.eclipse.kapua.client.security.context.Utils;
import org.eclipse.kapua.commons.core.ServiceModuleBundle;
import org.eclipse.kapua.commons.metric.CommonsMetric;
import org.eclipse.kapua.commons.populators.DataPopulatorRunner;
import org.eclipse.kapua.commons.setting.system.SystemSetting;
import org.eclipse.kapua.commons.setting.system.SystemSettingKey;
import org.eclipse.kapua.commons.util.KapuaDateUtils;
Expand Down Expand Up @@ -125,7 +124,6 @@ public ServerPlugin() {
publishInfoMessageSizeLimit = BrokerSetting.getInstance().getInt(BrokerSettingKey.PUBLISHED_MESSAGE_SIZE_LOG_THRESHOLD, DEFAULT_PUBLISHED_MESSAGE_SIZE_LOG_THRESHOLD);
//TODO find a proper way to initialize database
DatabaseCheckUpdate databaseCheckUpdate = new DatabaseCheckUpdate();
KapuaLocator.getInstance().getService(DataPopulatorRunner.class).runPopulators();
serverContext = ServerContext.getInstance();
brokerEventHanldler = BrokerEventHandler.getInstance();
brokerEventHanldler.registerConsumer((brokerEvent) -> disconnectClient(brokerEvent));
Expand Down
12 changes: 12 additions & 0 deletions commons/src/main/java/org/eclipse/kapua/commons/CommonsModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.eclipse.kapua.commons.jpa.KapuaJpaRepositoryConfiguration;
import org.eclipse.kapua.commons.model.domains.Domains;
import org.eclipse.kapua.commons.model.query.QueryFactoryImpl;
import org.eclipse.kapua.commons.populators.DataPopulator;
import org.eclipse.kapua.commons.populators.DataPopulatorRunner;
import org.eclipse.kapua.commons.service.event.store.api.EventStoreRecordRepository;
import org.eclipse.kapua.commons.service.event.store.api.EventStoreService;
Expand All @@ -44,6 +45,17 @@ protected void configureModule() {
bind(DataPopulatorRunner.class).in(Singleton.class);
}

@ProvidesIntoSet
//Guice does not like to inject empty sets, so in order to always have a valid DataPopulatorRunner here is a placeholder, good-for-nothing populator implementation
public DataPopulator noopDataPopulator() {
return new DataPopulator() {

Check warning on line 51 in commons/src/main/java/org/eclipse/kapua/commons/CommonsModule.java

View check run for this annotation

Codecov / codecov/patch

commons/src/main/java/org/eclipse/kapua/commons/CommonsModule.java#L51

Added line #L51 was not covered by tests
@Override
public void populate() {
//Noop
}

Check warning on line 55 in commons/src/main/java/org/eclipse/kapua/commons/CommonsModule.java

View check run for this annotation

Codecov / codecov/patch

commons/src/main/java/org/eclipse/kapua/commons/CommonsModule.java#L55

Added line #L55 was not covered by tests
};
}

@ProvidesIntoSet
public Domain eventStoreDomain() {
return new DomainEntry(Domains.EVENT_STORE, EventStoreService.class.getName(), false, Actions.read, Actions.delete, Actions.write);

Check warning on line 61 in commons/src/main/java/org/eclipse/kapua/commons/CommonsModule.java

View check run for this annotation

Codecov / codecov/patch

commons/src/main/java/org/eclipse/kapua/commons/CommonsModule.java#L61

Added line #L61 was not covered by tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public class KapuaEntityJpaRepository<E extends KapuaEntity, C extends E, L exte
protected final Class<C> concreteClass;
protected final String entityName;
protected final Supplier<? extends L> listSupplier;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
private static final String SQL_ERROR_CODE_CONSTRAINT_VIOLATION = "23505";
private final KapuaJpaRepositoryConfiguration configuration;
private static final String ATTRIBUTE_SEPARATOR = ".";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
package org.eclipse.kapua.service.authorization.access;

import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.model.domain.Actions;
import org.eclipse.kapua.model.id.KapuaId;
import org.eclipse.kapua.storage.KapuaEntityRepository;
import org.eclipse.kapua.storage.TxContext;

public interface AccessPermissionRepository extends KapuaEntityRepository<AccessPermission, AccessPermissionListResult> {

AccessPermissionListResult findByAccessInfoId(TxContext txContext, KapuaId scopeId, KapuaId accessInfoId) throws KapuaException;

AccessPermissionListResult deleteAllByDomainAndAction(TxContext tx, String domainEntryName, Actions actionToDelete) throws KapuaException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
package org.eclipse.kapua.service.authorization.role;

import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.model.domain.Actions;
import org.eclipse.kapua.model.id.KapuaId;
import org.eclipse.kapua.storage.KapuaEntityRepository;
import org.eclipse.kapua.storage.TxContext;

public interface RolePermissionRepository extends KapuaEntityRepository<RolePermission, RolePermissionListResult> {
RolePermissionListResult findByRoleId(TxContext tx, KapuaId scopeId, KapuaId roleId) throws KapuaException;

RolePermissionListResult deleteAllByDomainAndAction(TxContext tx, String domainName, Actions actionToDelete) throws KapuaException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.commons.jpa.KapuaEntityJpaRepository;
import org.eclipse.kapua.commons.jpa.KapuaJpaRepositoryConfiguration;
import org.eclipse.kapua.model.domain.Actions;
import org.eclipse.kapua.model.id.KapuaId;
import org.eclipse.kapua.service.authorization.access.AccessPermission;
import org.eclipse.kapua.service.authorization.access.AccessPermissionAttributes;
Expand All @@ -26,6 +27,7 @@
public class AccessPermissionImplJpaRepository
extends KapuaEntityJpaRepository<AccessPermission, AccessPermissionImpl, AccessPermissionListResult>
implements AccessPermissionRepository {

public AccessPermissionImplJpaRepository(KapuaJpaRepositoryConfiguration configuration) {
super(AccessPermissionImpl.class, AccessPermission.TYPE, () -> new AccessPermissionListResultImpl(), configuration);
}
Expand All @@ -36,4 +38,32 @@ public AccessPermissionListResult findByAccessInfoId(TxContext tx, KapuaId scope
query.setPredicate(query.attributePredicate(AccessPermissionAttributes.ACCESS_INFO_ID, accessInfoId));
return this.query(tx, query);
}

@Override
public AccessPermissionListResult deleteAllByDomainAndAction(TxContext tx, String domainName, Actions actionToDelete) throws KapuaException {
return new AccessPermissionListResultImpl();

Check warning on line 44 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/access/shiro/AccessPermissionImplJpaRepository.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/access/shiro/AccessPermissionImplJpaRepository.java#L44

Added line #L44 was not covered by tests
// final EntityManager em = JpaAwareTxContext.extractEntityManager(tx);
// final CriteriaBuilder cb = em.getCriteriaBuilder();
//
// final CriteriaQuery<AccessPermissionImpl> listQuery = cb.createQuery(AccessPermissionImpl.class);
// final Root<AccessPermissionImpl> listRoot = listQuery.from(AccessPermissionImpl.class);
// listQuery.where(
// // Find all the triggers that are associated with this job
// cb.and(
// cb.equal(listRoot.get(AccessPermissionImpl_.permission).get(PermissionImpl_.domain), domainName),
// cb.equal(listRoot.get(AccessPermissionImpl_.permission).get(PermissionImpl_.action), actionToDelete)
// )
// );
// final List<AccessPermissionImpl> resultList = em.createQuery(listQuery).getResultList();
//
// if (!resultList.isEmpty()) {
// final CriteriaDelete<AccessPermissionImpl> deleteQuery = cb.createCriteriaDelete(AccessPermissionImpl.class);
// final Root<AccessPermissionImpl> deleteRoot = deleteQuery.from(AccessPermissionImpl.class);
// deleteQuery.where(deleteRoot.get(AccessPermissionImpl_.id).in(resultList.stream().map(r -> r.getId()).map(KapuaEid::parseKapuaId).collect(Collectors.toList())));
// em.createQuery(deleteQuery).executeUpdate();
// }
// final AccessPermissionListResultImpl res = new AccessPermissionListResultImpl();
// res.addItems(resultList);
// return res;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.commons.service.internal.cache.EntityCache;
import org.eclipse.kapua.commons.storage.KapuaEntityRepositoryCachingWrapper;
import org.eclipse.kapua.model.domain.Actions;
import org.eclipse.kapua.model.id.KapuaId;
import org.eclipse.kapua.service.authorization.access.AccessPermission;
import org.eclipse.kapua.service.authorization.access.AccessPermissionAttributes;
Expand Down Expand Up @@ -63,4 +64,14 @@ public AccessPermissionListResult findByAccessInfoId(TxContext tx, KapuaId scope
}
return listResult;
}

@Override
public AccessPermissionListResult deleteAllByDomainAndAction(TxContext tx, String domainEntryName, Actions actionToDelete) throws KapuaException {
return new AccessPermissionListResultImpl();

Check warning on line 70 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/access/shiro/CachingAccessPermissionRepository.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/access/shiro/CachingAccessPermissionRepository.java#L70

Added line #L70 was not covered by tests
// final AccessPermissionListResult removed = wrapped.deleteAllByDomainAndAction(tx, domainEntryName, actionToDelete);
// if (!removed.isEmpty()) {
// removed.getItems().forEach(item -> entityCache.removeList(item.getScopeId(), item.getAccessInfoId()));
// }
// return removed;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*******************************************************************************
* Copyright (c) 2016, 2022 Eurotech and/or its affiliates and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Eurotech - initial API and implementation
*******************************************************************************/
package org.eclipse.kapua.service.authorization.domain.shiro;

import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.commons.populators.DataPopulator;
import org.eclipse.kapua.model.domain.Actions;
import org.eclipse.kapua.model.domain.Domain;
import org.eclipse.kapua.service.authorization.access.AccessPermissionRepository;
import org.eclipse.kapua.service.authorization.domain.DomainRepository;
import org.eclipse.kapua.service.authorization.role.RolePermissionRepository;
import org.eclipse.kapua.storage.TxContext;
import org.eclipse.kapua.storage.TxManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DomainsAligner implements DataPopulator {
private final TxManager txManager;
private final DomainRepository domainRepository;
private final AccessPermissionRepository accessPermissionRepository;
private final RolePermissionRepository rolePermissionRepository;
private final Set<Domain> knownDomains;
private final Logger logger = LoggerFactory.getLogger(this.getClass());

Check warning on line 39 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L39

Added line #L39 was not covered by tests

@Inject
public DomainsAligner(TxManager txManager,
DomainRepository domainRepository,
AccessPermissionRepository accessPermissionRepository, RolePermissionRepository rolePermissionRepository,
Set<Domain> knownDomains) {
this.txManager = txManager;
this.domainRepository = domainRepository;
this.accessPermissionRepository = accessPermissionRepository;
this.rolePermissionRepository = rolePermissionRepository;
this.knownDomains = knownDomains;
}

Check warning on line 51 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L45-L51

Added lines #L45 - L51 were not covered by tests

@Override
public void populate() {
// logger.info("Domain alignment commencing. Found {} domain declarations in wiring", knownDomains.size());
// final Map<String, Domain> knownDomainsByName = knownDomains
// .stream()
// .collect(Collectors.toMap(d -> d.getName(), d -> d));
// final List<String> declaredDomainsNotInDb = new ArrayList<>(knownDomainsByName.keySet());
// try {
// KapuaSecurityUtils.doPrivileged(() -> {
// txManager.execute(tx -> {
// final List<org.eclipse.kapua.service.authorization.domain.Domain> dbDomainEntries = domainRepository.query(tx, new DomainQueryImpl()).getItems();
// logger.info("Found {} domain declarations in database", dbDomainEntries.size());
//
// for (final org.eclipse.kapua.service.authorization.domain.Domain dbDomainEntry : dbDomainEntries) {
// if (!knownDomainsByName.containsKey(dbDomainEntry.getName())) {
// //Leave it be. As we share the database with other components, it might have been created by such components and be hidden from us
// logger.warn("Domain '{}' is only present in the database but has no current declaration! Details: {}", dbDomainEntry.getName(), dbDomainEntry.getDomain());
// continue;
// }
// //Good news, it's both declared in wiring and present in the db!
// declaredDomainsNotInDb.remove(dbDomainEntry.getName());
// //Trigger fetch of Actions collection from db, otherwise the toString would not show the details
// dbDomainEntry.getActions();
// final Domain wiredDomain = knownDomainsByName.get(dbDomainEntry.getName());
// if (dbDomainEntry.getDomain().equals(wiredDomain)) {
// //We are happy!
// logger.debug("Domain '{}' is ok: {}", dbDomainEntry.getName(), dbDomainEntry.getDomain());
// continue;
// }
// //Align them!
// alignDomains(tx, dbDomainEntry, wiredDomain);
// }
// createMissingDomains(tx, declaredDomainsNotInDb, knownDomainsByName);
// logger.info("Domain alignment complete!");
// return null;
// });
// });
// } catch (KapuaException e) {
// throw new RuntimeException(e);
// }
}

Check warning on line 93 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L93

Added line #L93 was not covered by tests

private void createMissingDomains(TxContext tx, List<String> declaredDomainsNotInDb, Map<String, Domain> knownDomainsByName) throws KapuaException {
if (declaredDomainsNotInDb.size() > 0) {
logger.info("Found {} declared domains that have no counterpart in the database!", declaredDomainsNotInDb.size());

Check warning on line 97 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L97

Added line #L97 was not covered by tests
//Create wired domains not present in the db
for (final String declaredOnlyName : declaredDomainsNotInDb) {
final Domain expected = knownDomainsByName.get(declaredOnlyName);
createDomainInDb(tx, expected);
}

Check warning on line 102 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L100-L102

Added lines #L100 - L102 were not covered by tests
}
}

Check warning on line 104 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L104

Added line #L104 was not covered by tests

private void createDomainInDb(TxContext tx, Domain expected) throws KapuaException {
logger.info("To be added: {}", expected);
final org.eclipse.kapua.service.authorization.domain.Domain newEntity = new DomainImpl();
newEntity.setName(expected.getName());
newEntity.setActions(expected.getActions());
newEntity.setGroupable(expected.getGroupable());
newEntity.setServiceName(expected.getServiceName());
domainRepository.create(tx, newEntity);
}

Check warning on line 114 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L107-L114

Added lines #L107 - L114 were not covered by tests

private void alignDomains(TxContext tx, org.eclipse.kapua.service.authorization.domain.Domain dbDomainEntry, Domain wiredDomain) throws KapuaException {
logger.error("Domain mismatch for name '{}'! Details:" +

Check warning on line 117 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L117

Added line #L117 was not covered by tests
"\n\tDb entry: '{}', " +
"\n\texpected: '{}'",
dbDomainEntry.getName(),
dbDomainEntry.getDomain(),

Check warning on line 121 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L120-L121

Added lines #L120 - L121 were not covered by tests
wiredDomain);

final EnumSet<Actions> actionsInExcessOnTheDb = EnumSet.copyOf(dbDomainEntry.getActions());
actionsInExcessOnTheDb.removeAll(wiredDomain.getActions());
removeActionsInExcess(tx, dbDomainEntry.getName(), actionsInExcessOnTheDb);

Check warning on line 126 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L124-L126

Added lines #L124 - L126 were not covered by tests
//Remove the action from the domain. Thank you JPA for autoupdating the entity on transaction close
dbDomainEntry.getActions().removeAll(actionsInExcessOnTheDb);

Check warning on line 128 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L128

Added line #L128 was not covered by tests

final EnumSet<Actions> actionsMissingInTheDb = EnumSet.copyOf(wiredDomain.getActions());
actionsMissingInTheDb.removeAll(dbDomainEntry.getActions());

Check warning on line 131 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L130-L131

Added lines #L130 - L131 were not covered by tests
//Add the actions to the domain. Thank you JPA for autoupdating the entity on transaction close
dbDomainEntry.getActions().addAll(actionsMissingInTheDb);
}

Check warning on line 134 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L133-L134

Added lines #L133 - L134 were not covered by tests

private void removeActionsInExcess(TxContext tx, String domainName, EnumSet<Actions> actionsInExcessOnTheDb) throws KapuaException {
for (final Actions actionToDelete : actionsInExcessOnTheDb) {
logger.info("Removing action '{}' from domain '{}'", actionToDelete, domainName);
accessPermissionRepository.deleteAllByDomainAndAction(tx, domainName, actionToDelete);
rolePermissionRepository.deleteAllByDomainAndAction(tx, domainName, actionToDelete);
}
}

Check warning on line 142 in service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java

View check run for this annotation

Codecov / codecov/patch

service/security/shiro/src/main/java/org/eclipse/kapua/service/authorization/domain/shiro/DomainsAligner.java#L138-L142

Added lines #L138 - L142 were not covered by tests
}
Loading

0 comments on commit 395c45a

Please sign in to comment.