Add federated identity ProviderEvent(s)
Signed-off-by: Réda Housni Alaoui <reda-alaoui@hey.com>
This commit is contained in:
parent
42f0488d76
commit
98230aa372
4 changed files with 213 additions and 2 deletions
|
@ -575,6 +575,28 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
|||
} else {
|
||||
getFederatedStorage().addFederatedIdentity(realm, user.getId(), socialLink);
|
||||
}
|
||||
|
||||
session.getKeycloakSessionFactory().publish(new FederatedIdentityModel.FederatedIdentityCreatedEvent() {
|
||||
@Override
|
||||
public KeycloakSession getKeycloakSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmModel getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FederatedIdentityModel getFederatedIdentity() {
|
||||
return socialLink;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -588,11 +610,44 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
|||
|
||||
@Override
|
||||
public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
|
||||
FederatedIdentityModel federatedIdentityModel;
|
||||
if (StorageId.isLocalStorage(user)) {
|
||||
return localStorage().removeFederatedIdentity(realm, user, socialProvider);
|
||||
UserProvider localStorage = localStorage();
|
||||
federatedIdentityModel = localStorage.getFederatedIdentity(realm, user, socialProvider);
|
||||
localStorage.removeFederatedIdentity(realm, user, socialProvider);
|
||||
} else {
|
||||
return getFederatedStorage().removeFederatedIdentity(realm, user.getId(), socialProvider);
|
||||
UserFederatedStorageProvider federatedStorage = getFederatedStorage();
|
||||
federatedIdentityModel = federatedStorage.getFederatedIdentity(user.getId(), socialProvider, realm);
|
||||
federatedStorage.removeFederatedIdentity(realm, user.getId(), socialProvider);
|
||||
}
|
||||
|
||||
if (federatedIdentityModel == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
session.getKeycloakSessionFactory().publish(new FederatedIdentityModel.FederatedIdentityRemovedEvent() {
|
||||
@Override
|
||||
public KeycloakSession getKeycloakSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmModel getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FederatedIdentityModel getFederatedIdentity() {
|
||||
return federatedIdentityModel;
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.keycloak.models;
|
||||
|
||||
import org.keycloak.provider.ProviderEvent;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
@ -85,4 +87,18 @@ public class FederatedIdentityModel {
|
|||
result = 31 * result + (userName != null ? userName.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public interface FederatedIdentityCreatedEvent extends ProviderEvent {
|
||||
KeycloakSession getKeycloakSession();
|
||||
RealmModel getRealm();
|
||||
UserModel getUser();
|
||||
FederatedIdentityModel getFederatedIdentity();
|
||||
}
|
||||
|
||||
public interface FederatedIdentityRemovedEvent extends ProviderEvent {
|
||||
KeycloakSession getKeycloakSession();
|
||||
RealmModel getRealm();
|
||||
UserModel getUser();
|
||||
FederatedIdentityModel getFederatedIdentity();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright 2024 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.testsuite.model;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.broker.provider.IdentityProvider;
|
||||
import org.keycloak.broker.provider.IdentityProviderFactory;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.ProviderEventListener;
|
||||
import org.keycloak.testsuite.broker.oidc.TestKeycloakOidcIdentityProviderFactory;
|
||||
|
||||
/**
|
||||
* @author Réda Housni Alaoui
|
||||
*/
|
||||
@RequireProvider(value = IdentityProvider.class, only = TestKeycloakOidcIdentityProviderFactory.ID)
|
||||
public class FederatedIdentityModelTest extends KeycloakModelTest {
|
||||
|
||||
private static final String IDENTITY_PROVIDER_ALIAS = "idp-test";
|
||||
private static final String USERNAME = "jdoe";
|
||||
private String realmId;
|
||||
private String userId;
|
||||
|
||||
@Override
|
||||
public void createEnvironment(KeycloakSession s) {
|
||||
RealmModel realm = createRealm(s, "realm");
|
||||
realm.setDefaultRole(s.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName()));
|
||||
|
||||
this.realmId = realm.getId();
|
||||
|
||||
IdentityProviderFactory identityProviderFactory = (IdentityProviderFactory) s.getKeycloakSessionFactory()
|
||||
.getProviderFactory(IdentityProvider.class, TestKeycloakOidcIdentityProviderFactory.ID);
|
||||
|
||||
IdentityProviderModel identityProviderModel = identityProviderFactory.createConfig();
|
||||
identityProviderModel.setAlias(IDENTITY_PROVIDER_ALIAS);
|
||||
realm.addIdentityProvider(identityProviderModel);
|
||||
|
||||
userId = s.users().addUser(realm, USERNAME).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanEnvironment(KeycloakSession s) {
|
||||
s.realms().removeRealm(realmId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addFederatedIdentity() {
|
||||
|
||||
List<FederatedIdentityModel.FederatedIdentityCreatedEvent> recordedEvents = new ArrayList<>();
|
||||
ProviderEventListener providerEventListener = event -> {
|
||||
if (event instanceof FederatedIdentityModel.FederatedIdentityCreatedEvent) {
|
||||
recordedEvents.add((FederatedIdentityModel.FederatedIdentityCreatedEvent) event);
|
||||
}
|
||||
};
|
||||
getFactory().register(providerEventListener);
|
||||
try {
|
||||
withRealm(realmId, (session, realm) -> {
|
||||
FederatedIdentityModel federatedIdentity = new FederatedIdentityModel(IDENTITY_PROVIDER_ALIAS, userId, USERNAME);
|
||||
UserModel user = session.users().getUserById(realm, userId);
|
||||
session.users().addFederatedIdentity(realm, user, federatedIdentity);
|
||||
|
||||
assertThat(recordedEvents, hasSize(1));
|
||||
FederatedIdentityModel.FederatedIdentityCreatedEvent event = recordedEvents.get(0);
|
||||
assertThat(event.getKeycloakSession(), equalTo(session));
|
||||
assertThat(event.getRealm(), equalTo(realm));
|
||||
assertThat(event.getUser(), equalTo(user));
|
||||
assertThat(event.getFederatedIdentity(), equalTo(federatedIdentity));
|
||||
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
getFactory().unregister(providerEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeFederatedIdentity() {
|
||||
List<FederatedIdentityModel.FederatedIdentityRemovedEvent> recordedEvents = new ArrayList<>();
|
||||
ProviderEventListener providerEventListener = event -> {
|
||||
if (event instanceof FederatedIdentityModel.FederatedIdentityRemovedEvent) {
|
||||
recordedEvents.add((FederatedIdentityModel.FederatedIdentityRemovedEvent) event);
|
||||
}
|
||||
};
|
||||
getFactory().register(providerEventListener);
|
||||
try {
|
||||
withRealm(realmId, (session, realm) -> {
|
||||
FederatedIdentityModel federatedIdentity = new FederatedIdentityModel(IDENTITY_PROVIDER_ALIAS, userId, USERNAME);
|
||||
UserModel user = session.users().getUserById(realm, userId);
|
||||
session.users().addFederatedIdentity(realm, user, federatedIdentity);
|
||||
|
||||
session.users().removeFederatedIdentity(realm, user, IDENTITY_PROVIDER_ALIAS);
|
||||
|
||||
assertThat(recordedEvents, hasSize(1));
|
||||
FederatedIdentityModel.FederatedIdentityRemovedEvent event = recordedEvents.get(0);
|
||||
assertThat(event.getKeycloakSession(), equalTo(session));
|
||||
assertThat(event.getRealm(), equalTo(realm));
|
||||
assertThat(event.getUser(), equalTo(user));
|
||||
assertThat(event.getFederatedIdentity(), equalTo(federatedIdentity));
|
||||
|
||||
return null;
|
||||
});
|
||||
} finally {
|
||||
getFactory().unregister(providerEventListener);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,9 @@
|
|||
package org.keycloak.testsuite.model.parameters;
|
||||
|
||||
import org.keycloak.authorization.jpa.store.JPAAuthorizationStoreFactory;
|
||||
import org.keycloak.broker.provider.IdentityProvider;
|
||||
import org.keycloak.broker.provider.IdentityProviderFactory;
|
||||
import org.keycloak.broker.provider.IdentityProviderSpi;
|
||||
import org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory;
|
||||
import org.keycloak.connections.jpa.JpaConnectionSpi;
|
||||
import org.keycloak.connections.jpa.updater.JpaUpdaterProviderFactory;
|
||||
|
@ -68,6 +71,9 @@ public class LegacyJpa extends KeycloakModelParameters {
|
|||
|
||||
.add(DBLockSpi.class)
|
||||
|
||||
//required for FederatedIdentityModel
|
||||
.add(IdentityProviderSpi.class)
|
||||
|
||||
.build();
|
||||
|
||||
static final Set<Class<? extends ProviderFactory>> ALLOWED_FACTORIES = ImmutableSet.<Class<? extends ProviderFactory>>builder()
|
||||
|
@ -92,6 +98,9 @@ public class LegacyJpa extends KeycloakModelParameters {
|
|||
.add(MigrationProviderFactory.class)
|
||||
.add(LoginProtocolFactory.class)
|
||||
|
||||
//required for FederatedIdentityModel
|
||||
.add(IdentityProviderFactory.class)
|
||||
|
||||
.build();
|
||||
|
||||
public LegacyJpa() {
|
||||
|
|
Loading…
Reference in a new issue