Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The approach will require a long time to implement.

Risks & Assumptions

  1. The approach will correctly manage capability sets within one application but won't handle permissions defined in another application. For a long-term solution, we need to implement a more complex approach with postponed jobs. These jobs will run periodically and attempt to create capability sets.

Conclusion

...

Option 4 involves creating a mapping table for capability sets to capabilities that do not yet exist.

If mod-role-keycloak receives a capability event but cannot create a capability set because some capabilities are missing, it will still create a capability set and add a record to the mapping table indicating that this capability set is associated with another capability, along with the capability name. When we receive another capability event, we will create it and check the table to see if there is a capability set associated with it. If there is, we will associate the capability set with it and remove that item from the mapping.

Pros

This approach would handle all possible cases where the UI modules have permission sets with permissions from other backend modules, which could be defined in other applications.

Cons

Implementation for option 4

To avoid disappointing users when they see a capability set in the system that doesn't actually work (due to missing capabilities and resources), we need to hide the dummy capability sets from them. Additionally, even if we have some partially created capabilities required for the capability set, I suggest not displaying them to the end user. This can prevent confusion and simplify the implementation.

Currently, each time we create a new CapabilitySet, we always create it from scratch and never update it. We resolve the capability ID by its name, and if we can't find it, we exclude it from the result and log a warning.

Code Block
private Optional<UUID> getCapabilityId(Map<String, UUID> existingCapabilityIdsMap, String capabilityName) {
  var value = existingCapabilityIdsMap.get(capabilityName);
  if (value == null) {
    log.warn("Capability id is not found by capability name: {}", capabilityName);
    return Optional.empty();
  }

  return Optional.of(value);
}

So, instead of ignoring this capability set, we will create it regardless of whether it partially includes some capabilities or lacks them entirely. However, all missing capabilities need to be recorded in the dummy capability ID mapping table so that we can resolve them in the future once they are created.

Folio-Page-14 (1).pngImage Added

Now we have all the necessary information to update the capability set in the future, once the missing capability is created in the system.

Next, we need to extend the logic to create new capabilities. Once a capability is created, we should update the capability ID for all entries that exist in the DummyCapabilityIdMapping.

update DummyCapabilityIdMapping set capabilityid=? where capabilityName=?;

which populates all capability IDs for the particular capability

Then, we need to run the capability set update process for the capability sets affected by the creation of a new capability event.

After that, we need to remove the record from the dummy capability ID mapping table.

Statements

  • We don't want to create a separate dummy capability set table since we will always create capability sets, regardless of whether they include all capabilities, only a partial set, or are empty.

  • If a capability does not exist, we will create a record in the dummy capability ID mapping table to resolve the relationship in the future.

  • Each time we create a new capability, we check the dummy capability ID mapping table to resolve any missing relations and run the update capability set method, which will create Keycloak resources and other necessary components.

  • The process of updating the capability set should be event-driven and need to use Kafka events instead of Spring events. This approach will help maintain data consistency in case the service crashes. (No additional Kafka event is needed for version one, but future versions will require additional design to avoid the issues we faced in the past.)

  • Delete the event and record in the dummy mapping table only when the capability set is fully updated

Conclusion

I would choose option 4, as it can be easily implemented for phase one and would cover all possible cases where capabilities may be defined in other applications.

Spike Status:

Status
colourGreen
titleComplited