Skip to content

Commit

Permalink
Merge branch 'Onlineberatung:develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
patric-dosch-vi authored Mar 15, 2024
2 parents 4ab44cb + 0c17a5c commit 2f2875e
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 20 deletions.
68 changes: 51 additions & 17 deletions src/main/java/com/vi/migrationtool/keycloak/KeycloakService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.client.util.Lists;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -35,7 +37,7 @@
public class KeycloakService {

private static final String SEARCH_PARAM = "search";
private static final String MAX_USERS_TO_MIGRATE = "500";
private static final short USER_PAGE_SIZE = 500;
private static final String PROVIDED_ROLE_DOESNT_EXISTS_IN_KEYCLOAK_MSG =
"The provided role {} doesn't exists in keycloak, please create it first";
private final KeycloakConfig keycloakConfig;
Expand Down Expand Up @@ -78,7 +80,15 @@ public void addRolesToUsersWithRoleName(
KeycloakLoginResponseDTO loginResponse = keycloakLoginService.loginAdminUser();
httpHeaders.setBearerAuth(loginResponse.getAccessToken());

List<KeycloakUser> keycloakUsers = getUsersWithRoleName(roleNameToSearchForUsers);
var pageNumber = 1;
var users = getUsersWithRoleName(roleNameToSearchForUsers, pageNumber);
List<KeycloakUser> keycloakUsers = Lists.newArrayList();
while (!users.isEmpty()) {
keycloakUsers.addAll(users);
pageNumber++;
users = getUsersWithRoleName(roleNameToSearchForUsers, pageNumber);
}

if (keycloakUsers.isEmpty()) {
log.info(
"No users found with the given role {}. Migration will not be applied",
Expand Down Expand Up @@ -172,23 +182,25 @@ private List<KeycloakUser> getUsersBy(final String searchTerm, final HttpHeaders
return List.of(response.getBody());
}

public List<KeycloakUser> getUsersWithRoleName(final String roleName) {
public List<KeycloakUser> getUsersWithRoleName(final String roleName, int pageNumberedFromOne) {
var httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
KeycloakLoginResponseDTO loginResponse = keycloakLoginService.loginAdminUser();
httpHeaders.setBearerAuth(loginResponse.getAccessToken());
return getUsersWithRoleName(roleName, httpHeaders);
return getUsersWithRoleName(roleName, getFirstElementIndex(pageNumberedFromOne), httpHeaders);
}

private List<KeycloakUser> getUsersWithRoleName(
final String roleName, final HttpHeaders httpHeaders) {
final String roleName, final int firstElementIndex, final HttpHeaders httpHeaders) {

var url =
keycloakConfig.getAuthServerUrl()
+ "/admin/realms/online-beratung/roles/"
+ roleName
+ "/users?first=0&max="
+ MAX_USERS_TO_MIGRATE;
+ "/users?first="
+ firstElementIndex
+ "&max="
+ USER_PAGE_SIZE;
var getUsersBySearchTermURL = getUrl(url);

HttpEntity requestEntity = new HttpEntity<>(httpHeaders);
Expand All @@ -202,6 +214,7 @@ private List<KeycloakUser> getUsersWithRoleName(
new Object[] {});
if (isNull(response.getBody())) {
log.warn("No user found in keycloak using search param {}", getUsersBySearchTermURL);
return Lists.newArrayList();
}
return List.of(response.getBody());
}
Expand Down Expand Up @@ -292,20 +305,41 @@ private UsersWithRole addCustomAttributeToUsersWithRole(

var restTemplate = new RestTemplate();
restTemplate.setErrorHandler(faultTolerantResponseErrorHandler());
var users = getUsersWithRoleName(roleName, httpHeaders);
var updatedUsers =
users.stream()
.map(
user ->
addCustomAttributeToUserIfDoesNotExist(
customAttribute, value, httpHeaders, restTemplate, user))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());

Collection<String> updatedUsers = Lists.newArrayList();
var pageNumber = 1;
var users = getUsersWithRoleName(roleName, getFirstElementIndex(pageNumber));
while (!users.isEmpty()) {
var migratedUsersPage =
addCustomAttributeToUsers(customAttribute, value, httpHeaders, restTemplate, users);
pageNumber++;
updatedUsers.addAll(migratedUsersPage);
users = getUsersWithRoleName(roleName, pageNumber);
}

return new UsersWithRole(roleName, updatedUsers);
}

private List<String> addCustomAttributeToUsers(
String customAttribute,
Long value,
HttpHeaders httpHeaders,
RestTemplate restTemplate,
List<KeycloakUser> users) {
return users.stream()
.map(
user ->
addCustomAttributeToUserIfDoesNotExist(
customAttribute, value, httpHeaders, restTemplate, user))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
}

private int getFirstElementIndex(int pageNumberedFromOne) {
return (pageNumberedFromOne - 1) * USER_PAGE_SIZE;
}

private Optional<String> addCustomAttributeToUserIfDoesNotExist(
String customAttribute,
Long customAttributeValue,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.vi.migrationtool.tenantservice;

import com.vi.migrationtool.common.MigrationTasks;
import com.vi.migrationtool.config.BeanAwareSpringLiquibase;
import liquibase.database.Database;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.helper.Validate;
import org.springframework.jdbc.core.JdbcTemplate;

@Slf4j
@Setter
public class EnableTenantLevelToggleMigrationTask extends MigrationTasks {

String featureToggleName;

@Override
public void execute(Database database) {
Validate.notNull(featureToggleName, "Feature toggle name must not be null");
var tenantServiceJdbcTemplate =
BeanAwareSpringLiquibase.getNamedBean("tenantServiceJdbcTemplate", JdbcTemplate.class);
log.info("Activating tenant level toggle" + featureToggleName + " for all tenants");
activateFeatureToggle(tenantServiceJdbcTemplate);
}

private void activateFeatureToggle(JdbcTemplate tenantServiceJdbcTemplate) {
int[] updatedTenants =
tenantServiceJdbcTemplate.batchUpdate(
"update tenant set settings = REPLACE( settings ,'\""
+ featureToggleName
+ "\":false','\""
+ featureToggleName
+ "\":true') where settings like '%"
+ "\""
+ featureToggleName
+ "\""
+ ":false%';");

log.info("Updated toggle value for {} tenants", updatedTenants[0]);

int[] tenantsWithAddedSettings =
tenantServiceJdbcTemplate.batchUpdate(
"update tenant set settings = REPLACE(settings, '}',',\""
+ featureToggleName
+ "\":true}')"
+ " where settings not like '%"
+ featureToggleName
+ "%';");

log.info("Added feature toggle to {} tenants", tenantsWithAddedSettings[0]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class UserServiceAddAdminTask extends MigrationTasks {
public void execute(Database database) {

KeycloakService keycloakService = BeanAwareSpringLiquibase.getBean(KeycloakService.class);
List<KeycloakUser> adminUsersWithRoleName = keycloakService.getUsersWithRoleName(roleName);
List<KeycloakUser> adminUsersWithRoleName = keycloakService.getUsersWithRoleName(roleName, 1);
log.info("Found users with role name of size: {}", adminUsersWithRoleName.size());
JdbcTemplate jdbcTemplate = BeanAwareSpringLiquibase.getBean(JdbcTemplate.class);
createTenantAdminUsersIfNotExist(adminUsersWithRoleName, jdbcTemplate);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">

<changeSet author="tkuzynow" id="enable_central_data_protection_toggle">
<customChange class="com.vi.migrationtool.tenantservice.EnableTenantLevelToggleMigrationTask">
<param name="featureToggleName" value='featureCentralDataProtectionTemplateEnabled'/>
</customChange>
</changeSet>
</databaseChangeLog>
18 changes: 16 additions & 2 deletions src/main/resources/migrations/master-diakonie.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,25 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.2.xsd">

<!-- skip (already done) 0001_setup_keycloak_roles.xml -->
<!-- skip (tbd) 0002_setup_rocketchat_delete_message_config.xml -->
<!-- skip (tbd) 0003_add_tenant_can_edit_legaltexts_applevel_setting.xml -->
<!-- skip 0004_add_topic_admin_role_to_super_admin_user.xml -->
<!-- skip (tbd) 0005_add_permission_to_technical_role_rocketchat.xml -->
<!-- skip (tbd) 0006_create_admin_user_table_entries_for_existing_admins.xml -->
<!-- skip (tbd) 0007_add_view_room_permission_to_technical_role_rocketchat.xml -->
<include file="migrations/changeset/0008_remove_lockedAgencies/0008_remove_lockedAgencies_attribute.xml"/>
<!-- skip (tbd) 0009_add_documentation_enabled_applevel_setting.xml -->
<!-- skip (tbd) 0010_add_notification_and_tenant_creation_release_toggles.xml -->
<!-- skip (tbd) 0011_add_notification_technical_keycloak_role.xml -->
<!-- skip (tbd) 0012_setup_rocketchat_read_receipts.xml -->
<!-- skip (tbd) 0013_add_videogroupchat_release_toggle.xml -->
<include file="migrations/changeset/0014_import_dioceses_from_agency_to_tenant_service/0014_import_dioceses_from_agency_to_tenant_service.xml"/>
<include file="migrations/changeset/0015_create_jitsi_technical_keycloak_role/0015_create_jitsi_technical_keycloak_role.xml"/>
<include file="migrations/changeset/0016_migrate_consulting_types_description_to_topic/0016_migrate_consulting_types_description_to_topic.xml"/>
<!-- -->
<include file="migrations/changeset/0018_migrate_tenant_admins_to_set_user_admin_and_agency_admin_roles/0018_migrate_tenant_admins_to_set_user_admin_and_agency_admin_roles.xml"/>
<include file="migrations/changeset/0021_add_custom_keycloak_attribute_to_users_with_role/0021_add_custom_keycloak_attribute_to_users_with_role.xml"/>
<include file="migrations/changeset/0024_create_weblate_project/0024_create_weblate_project.xml"/>
<include file="migrations/changeset/0023_create_jitsi_technical_user/0023_create_jitsi_technical_user.xml"/>
<!-- todo <include file="migrations/changeset/0024_create_weblate_project/0024_create_weblate_project.xml"/>-->
</databaseChangeLog>
1 change: 1 addition & 0 deletions src/main/resources/migrations/master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@
<!-- by default migration 0025_fix_rocketchat_user_id_inconsistency is not applied. This must be decided by each of the clients and activated if needed -->

<!-- by default migration 0026_deactivate_legal_content_changes_by_single_tenant_admin_allowed is not applied. This must be decided by each of the clients and activated if needed -->
<!-- by default migration 0027_enable_central_data_protection_toggle/0027_enable_central_data_protection_toggle is not applied. This must be decided by each of the clients and activated if needed -->
</databaseChangeLog>

0 comments on commit 2f2875e

Please sign in to comment.