KEYCLOAK-3930 KEYCLOAK-3931 LDAP and Mongo fixes

This commit is contained in:
mposolda 2016-11-18 20:01:10 +01:00
parent 639cf1e038
commit da52a5c9cf
6 changed files with 72 additions and 18 deletions

View file

@ -50,6 +50,7 @@ import org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoUserEntity;
import org.keycloak.models.mongo.keycloak.entities.UserConsentEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.UserModelDelegate;
import java.util.ArrayList;
import java.util.Collections;
@ -661,16 +662,18 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
}
public MongoUserEntity getMongoUserEntity(UserModel user) {
UserAdapter adapter = null;
if (user instanceof CachedUserModel) {
adapter = (UserAdapter)((CachedUserModel)user).getDelegateForUpdate();
} else if (user instanceof UserAdapter ){
adapter = (UserAdapter)user;
if (user instanceof UserAdapter) {
UserAdapter adapter = (UserAdapter)user;
return adapter.getMongoEntity();
} else if (user instanceof CachedUserModel) {
UserModel delegate = ((CachedUserModel)user).getDelegateForUpdate();
return getMongoUserEntity(delegate);
} else if (user instanceof UserModelDelegate){
UserModel delegate = ((UserModelDelegate) user).getDelegate();
return getMongoUserEntity(delegate);
} else {
return getMongoStore().loadEntity(MongoUserEntity.class, user.getId(), invocationContext);
}
return adapter.getMongoEntity();
}
@Override

View file

@ -1988,28 +1988,39 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
@Override
public void removeComponent(ComponentModel component) {
Iterator<ComponentEntity> it = realm.getComponentEntities().iterator();
ComponentEntity found = null;
while(it.hasNext()) {
if (it.next().getId().equals(component.getId())) {
session.users().preRemove(this, component);
removeComponents(component.getId());
it.remove();
ComponentEntity next = it.next();
if (next.getId().equals(component.getId())) {
found = next;
break;
}
}
updateRealm();
if (found != null) {
session.users().preRemove(this, component);
removeComponents(component.getId());
realm.getComponentEntities().remove(found);
updateRealm();
}
}
@Override
public void removeComponents(String parentId) {
Iterator<ComponentEntity> it = realm.getComponentEntities().iterator();
Set<ComponentEntity> toRemove = new HashSet<>();
while(it.hasNext()) {
ComponentEntity next = it.next();
if (next.getParentId().equals(parentId)) {
session.users().preRemove(this, entityToModel(next));
it.remove();
toRemove.add(next);
}
}
for (ComponentEntity toRem : toRemove) {
session.users().preRemove(this, entityToModel(toRem));
realm.getComponentEntities().remove(toRem);
}
updateRealm();
}

View file

@ -261,6 +261,7 @@ public class UserAdapter extends AbstractMongoAdapter<MongoUserEntity> implement
@Override
public boolean isMemberOf(GroupModel group) {
if (user.getGroupIds() == null) return false;
if (user.getGroupIds().contains(group.getId())) return true;
Set<GroupModel> groups = getGroups();
return RoleUtils.isMember(groups, group);

View file

@ -21,6 +21,7 @@ import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.NotFoundException;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.common.constants.KerberosConstants;
import org.keycloak.component.ComponentModel;
import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
import org.keycloak.mappers.FederationConfigValidationException;
@ -60,8 +61,10 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
@ -263,6 +266,33 @@ public class UserFederationProvidersResource {
return instanceResource;
}
// TODO: This endpoint exists, so that admin console can lookup userFederation provider OR userStorage provider by federationLink.
// TODO: Endpoint should be removed once UserFederation SPI is removed as fallback is not needed anymore than
@GET
@Path("instances-with-fallback/{id}")
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public Map<String, String> getUserFederationInstanceWithFallback(@PathParam("id") String id) {
this.auth.requireView();
Map<String, String> result = new HashMap<>();
UserFederationProviderModel model = KeycloakModelUtils.findUserFederationProviderById(id, realm);
if (model != null) {
result.put("federationLinkName", model.getDisplayName());
result.put("federationLink", "#/realms/" + realm.getName() + "/user-federation/providers/" + model.getProviderName() + "/" + model.getId());
return result;
} else {
ComponentModel userStorage = KeycloakModelUtils.findUserStorageProviderById(id, realm);
if (userStorage != null) {
result.put("federationLinkName", userStorage.getName());
result.put("federationLink", "#/realms/" + realm.getName() + "/user-storage/providers/" + userStorage.getProviderId() + "/" + userStorage.getId());
return result;
} else {
throw new NotFoundException("Could not find federation provider or userStorage provider");
}
}
}
private ConfigPropertyRepresentation toConfigPropertyRepresentation(ProviderConfigProperty prop) {
return ModelToRepresentation.toRepresentation(prop);

View file

@ -337,7 +337,7 @@ module.controller('UserTabCtrl', function($scope, $location, Dialog, Notificatio
module.controller('UserDetailCtrl', function($scope, realm, user, BruteForceUser, User,
Components,
UserFederationInstances, UserImpersonation, RequiredActions,
$location, Dialog, Notifications) {
$location, $http, Dialog, Notifications) {
$scope.realm = realm;
$scope.create = !user.id;
$scope.editUsername = $scope.create || $scope.realm.editUsernameAllowed;
@ -362,7 +362,16 @@ module.controller('UserDetailCtrl', function($scope, realm, user, BruteForceUser
});
};
if(user.federationLink) {
console.log("federationLink is not null");
console.log("federationLink is not null. It is " + user.federationLink);
// TODO: This is temporary and should be removed once we remove userFederation SPI. It can be replaced with Components.get below
var fedUrl = authUrl + '/admin/realms/' + realm.realm + '/user-federation/instances-with-fallback/' + user.federationLink;
$http.get(fedUrl).success(function(data, status, headers, config) {
$scope.federationLinkName = data.federationLinkName;
$scope.federationLink = data.federationLink;
});
/*
if (user.federationLink.startsWith('f:')) {
Components.get({realm: realm.realm, componentId: user.federationLink}, function (link) {
$scope.federationLinkName = link.name;
@ -373,7 +382,7 @@ module.controller('UserDetailCtrl', function($scope, realm, user, BruteForceUser
$scope.federationLinkName = link.displayName;
$scope.federationLink = "#/realms/" + realm.realm + "/user-federation/providers/" + link.providerName + "/" + link.id;
});
}
}*/
} else {
console.log("federationLink is null");

View file

@ -1,6 +1,6 @@
<div data-ng-controller="LDAPTabCtrl">
<h1 data-ng-hide="create">
{{instance.displayName|capitalize}}
{{instance.name|capitalize}}
<i class="pficon pficon-delete clickable" data-ng-show="!create && access.manageUsers" data-ng-click="removeUserFederation()"></i>
</h1>
<h1 data-ng-show="create">{{:: 'add-user-federation-provider' | translate}}</h1>