/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.connections.mongo.updater.impl.updates;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import org.jboss.logging.Logger;
import org.keycloak.keys.KeyProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.storage.UserStorageProvider;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class Update2_4_0 extends Update {
private final Logger logger = Logger.getLogger(getClass());
@Override
public String getId() {
return "2.4.0";
}
@Override
public void update(KeycloakSession session) {
portUserFedMappersToComponent(LDAPConstants.LDAP_PROVIDER, "org.keycloak.storage.ldap.mappers.LDAPStorageMapper");
portUserFedToComponent(LDAPConstants.LDAP_PROVIDER);
}
public void portUserFedToComponent(String providerId) {
DBCollection realms = db.getCollection("realms");
DBCursor cursor = realms.find();
while (cursor.hasNext()) {
BasicDBObject realm = (BasicDBObject) cursor.next();
String realmId = realm.getString("_id");
Set<String> removedProviders = new HashSet<>();
BasicDBList componentEntities = (BasicDBList) realm.get("componentEntities");
BasicDBList federationProviders = (BasicDBList) realm.get("userFederationProviders");
for (Object obj : federationProviders) {
BasicDBObject fedProvider = (BasicDBObject)obj;
if (fedProvider.getString("providerName").equals(providerId)) {
String id = fedProvider.getString("id");
removedProviders.add(id);
int priority = fedProvider.getInt("priority");
String displayName = fedProvider.getString("displayName");
int fullSyncPeriod = fedProvider.getInt("fullSyncPeriod");
int changedSyncPeriod = fedProvider.getInt("changedSyncPeriod");
int lastSync = fedProvider.getInt("lastSync");
BasicDBObject component = new BasicDBObject();
component.put("id", id);
component.put("name", displayName);
component.put("providerType", UserStorageProvider.class.getName());
component.put("providerId", providerId);
component.put("parentId", realmId);
BasicDBObject config = new BasicDBObject();
config.put("priority", Collections.singletonList(Integer.toString(priority)));
config.put("fullSyncPeriod", Collections.singletonList(Integer.toString(fullSyncPeriod)));
config.put("changedSyncPeriod", Collections.singletonList(Integer.toString(changedSyncPeriod)));
config.put("lastSync", Collections.singletonList(Integer.toString(lastSync)));
BasicDBObject fedConfig = (BasicDBObject)fedProvider.get("config");
if (fedConfig != null) {
for (Map.Entry<String, Object> attr : new HashSet<>(fedConfig.entrySet())) {
String attrName = attr.getKey();
String attrValue = attr.getValue().toString();
config.put(attrName, Collections.singletonList(attrValue));
}
}
component.put("config", config);
componentEntities.add(component);
}
}
Iterator<Object> it = federationProviders.iterator();
while (it.hasNext()) {
BasicDBObject fedProvider = (BasicDBObject)it.next();
String id = fedProvider.getString("id");
if (removedProviders.contains(id)) {
it.remove();
}
}
realms.update(new BasicDBObject().append("_id", realmId), realm);
}
}
public void portUserFedMappersToComponent(String providerId, String mapperType) {
//logger.info("*** port mappers");
DBCollection realms = db.getCollection("realms");
DBCursor cursor = realms.find();
while (cursor.hasNext()) {
BasicDBObject realm = (BasicDBObject) cursor.next();
String realmId = realm.getString("_id");
Set<String> removedProviders = new HashSet<>();
BasicDBList componentEntities = (BasicDBList) realm.get("componentEntities");
BasicDBList federationProviders = (BasicDBList) realm.get("userFederationProviders");
BasicDBList fedMappers = (BasicDBList) realm.get("userFederationMappers");
for (Object obj : federationProviders) {
BasicDBObject fedProvider = (BasicDBObject)obj;
String providerName = fedProvider.getString("providerName");
//logger.info("looking for mappers of fed provider: " + providerName);
if (providerName.equals(providerId)) {
String id = fedProvider.getString("id");
//logger.info("found fed provider: " + id + ", looking at mappers");
for (Object obj2 : fedMappers) {
BasicDBObject fedMapper = (BasicDBObject)obj2;
String federationProviderId = fedMapper.getString("federationProviderId");
//logger.info("looking at mapper with federationProviderId: " + federationProviderId);
if (federationProviderId.equals(id)) {
String name = fedMapper.getString("name");
String mapperId = fedMapper.getString("id");
removedProviders.add(mapperId);
String mapperProviderId = fedMapper.getString("federationMapperType");
BasicDBObject component = new BasicDBObject();
component.put("id", mapperId);
component.put("name", name);
component.put("providerType", mapperType);
component.put("providerId", mapperProviderId);
component.put("parentId", id);
BasicDBObject fedConfig = (BasicDBObject)fedMapper.get("config");
BasicDBObject config = new BasicDBObject();
if (fedConfig != null) {
for (Map.Entry<String, Object> attr : new HashSet<>(fedConfig.entrySet())) {
String attrName = attr.getKey();
String attrValue = attr.getValue().toString();
config.put(attrName, Collections.singletonList(attrValue));
}
}
component.put("config", config);
componentEntities.add(component);
}
}
}
}
Iterator<Object> it = fedMappers.iterator();
while (it.hasNext()) {
BasicDBObject fedMapper = (BasicDBObject)it.next();
String id = fedMapper.getString("id");
if (removedProviders.contains(id)) {
it.remove();
}
}
realms.update(new BasicDBObject().append("_id", realmId), realm);
}
}
}