Support for periodic users sync
This commit is contained in:
parent
ee79747cb6
commit
d699404ce7
19 changed files with 382 additions and 33 deletions
|
@ -12,6 +12,9 @@ public class UserFederationProviderRepresentation {
|
||||||
private String providerName;
|
private String providerName;
|
||||||
private Map<String, String> config;
|
private Map<String, String> config;
|
||||||
private int priority;
|
private int priority;
|
||||||
|
private int fullSyncPeriod;
|
||||||
|
private int changedSyncPeriod;
|
||||||
|
private int lastSync;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
|
@ -54,6 +57,30 @@ public class UserFederationProviderRepresentation {
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getFullSyncPeriod() {
|
||||||
|
return fullSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFullSyncPeriod(int fullSyncPeriod) {
|
||||||
|
this.fullSyncPeriod = fullSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChangedSyncPeriod() {
|
||||||
|
return changedSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChangedSyncPeriod(int changedSyncPeriod) {
|
||||||
|
this.changedSyncPeriod = changedSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastSync() {
|
||||||
|
return lastSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastSync(int lastSync) {
|
||||||
|
this.lastSync = lastSync;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|
|
@ -12,6 +12,8 @@ import java.util.Properties;
|
||||||
*/
|
*/
|
||||||
public class ClasspathPropertiesFederationFactory extends BasePropertiesFederationFactory {
|
public class ClasspathPropertiesFederationFactory extends BasePropertiesFederationFactory {
|
||||||
|
|
||||||
|
public static final String PROVIDER_NAME = "classpath-properties";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BasePropertiesFederationProvider createProvider(KeycloakSession session, UserFederationProviderModel model, Properties props) {
|
protected BasePropertiesFederationProvider createProvider(KeycloakSession session, UserFederationProviderModel model, Properties props) {
|
||||||
return new ClasspathPropertiesFederationProvider(session, model, props);
|
return new ClasspathPropertiesFederationProvider(session, model, props);
|
||||||
|
@ -30,6 +32,6 @@ public class ClasspathPropertiesFederationFactory extends BasePropertiesFederati
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "classpath-properties";
|
return PROVIDER_NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
|
|
||||||
List<UserFederationProviderModel> getUserFederationProviders();
|
List<UserFederationProviderModel> getUserFederationProviders();
|
||||||
|
|
||||||
UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName);
|
UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync);
|
||||||
void updateUserFederationProvider(UserFederationProviderModel provider);
|
void updateUserFederationProvider(UserFederationProviderModel provider);
|
||||||
void removeUserFederationProvider(UserFederationProviderModel provider);
|
void removeUserFederationProvider(UserFederationProviderModel provider);
|
||||||
void setUserFederationProviders(List<UserFederationProviderModel> providers);
|
void setUserFederationProviders(List<UserFederationProviderModel> providers);
|
||||||
|
|
|
@ -16,10 +16,13 @@ public class UserFederationProviderModel {
|
||||||
private Map<String, String> config = new HashMap<String, String>();
|
private Map<String, String> config = new HashMap<String, String>();
|
||||||
private int priority;
|
private int priority;
|
||||||
private String displayName;
|
private String displayName;
|
||||||
|
private int fullSyncPeriod = -1; // In seconds. -1 means that periodic full sync is disabled
|
||||||
|
private int changedSyncPeriod = -1; // In seconds. -1 means that periodic changed sync is disabled
|
||||||
|
private int lastSync; // Date when last sync was done for this provider
|
||||||
|
|
||||||
public UserFederationProviderModel() {};
|
public UserFederationProviderModel() {};
|
||||||
|
|
||||||
public UserFederationProviderModel(String id, String providerName, Map<String, String> config, int priority, String displayName) {
|
public UserFederationProviderModel(String id, String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.providerName = providerName;
|
this.providerName = providerName;
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
|
@ -27,6 +30,9 @@ public class UserFederationProviderModel {
|
||||||
}
|
}
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
|
this.fullSyncPeriod = fullSyncPeriod;
|
||||||
|
this.changedSyncPeriod = changedSyncPeriod;
|
||||||
|
this.lastSync = lastSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -64,4 +70,28 @@ public class UserFederationProviderModel {
|
||||||
public void setDisplayName(String displayName) {
|
public void setDisplayName(String displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getFullSyncPeriod() {
|
||||||
|
return fullSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFullSyncPeriod(int fullSyncPeriod) {
|
||||||
|
this.fullSyncPeriod = fullSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChangedSyncPeriod() {
|
||||||
|
return changedSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChangedSyncPeriod(int changedSyncPeriod) {
|
||||||
|
this.changedSyncPeriod = changedSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastSync() {
|
||||||
|
return lastSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastSync(int lastSync) {
|
||||||
|
this.lastSync = lastSync;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@ public class UserFederationProviderEntity {
|
||||||
protected Map<String, String> config;
|
protected Map<String, String> config;
|
||||||
protected int priority;
|
protected int priority;
|
||||||
protected String displayName;
|
protected String displayName;
|
||||||
|
private int fullSyncPeriod;
|
||||||
|
private int changedSyncPeriod;
|
||||||
|
private int lastSync;
|
||||||
|
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -53,4 +56,28 @@ public class UserFederationProviderEntity {
|
||||||
public void setDisplayName(String displayName) {
|
public void setDisplayName(String displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getFullSyncPeriod() {
|
||||||
|
return fullSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFullSyncPeriod(int fullSyncPeriod) {
|
||||||
|
this.fullSyncPeriod = fullSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChangedSyncPeriod() {
|
||||||
|
return changedSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChangedSyncPeriod(int changedSyncPeriod) {
|
||||||
|
this.changedSyncPeriod = changedSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastSync() {
|
||||||
|
return lastSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastSync(int lastSync) {
|
||||||
|
this.lastSync = lastSync;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,6 +262,9 @@ public class ModelToRepresentation {
|
||||||
rep.setProviderName(model.getProviderName());
|
rep.setProviderName(model.getProviderName());
|
||||||
rep.setPriority(model.getPriority());
|
rep.setPriority(model.getPriority());
|
||||||
rep.setDisplayName(model.getDisplayName());
|
rep.setDisplayName(model.getDisplayName());
|
||||||
|
rep.setFullSyncPeriod(model.getFullSyncPeriod());
|
||||||
|
rep.setChangedSyncPeriod(model.getChangedSyncPeriod());
|
||||||
|
rep.setLastSync(model.getLastSync());
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,7 +288,8 @@ public class RepresentationToModel {
|
||||||
|
|
||||||
for (UserFederationProviderRepresentation representation : providers) {
|
for (UserFederationProviderRepresentation representation : providers) {
|
||||||
UserFederationProviderModel model = new UserFederationProviderModel(representation.getId(), representation.getProviderName(),
|
UserFederationProviderModel model = new UserFederationProviderModel(representation.getId(), representation.getProviderName(),
|
||||||
representation.getConfig(), representation.getPriority(), representation.getDisplayName());
|
representation.getConfig(), representation.getPriority(), representation.getDisplayName(),
|
||||||
|
representation.getFullSyncPeriod(), representation.getChangedSyncPeriod(), representation.getLastSync());
|
||||||
result.add(model);
|
result.add(model);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -594,9 +594,9 @@ public class RealmAdapter implements RealmModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName) {
|
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
|
||||||
getDelegateForUpdate();
|
getDelegateForUpdate();
|
||||||
return updated.addUserFederationProvider(providerName, config, priority, displayName);
|
return updated.addUserFederationProvider(providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -676,14 +676,15 @@ public class RealmAdapter implements RealmModel {
|
||||||
});
|
});
|
||||||
List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>();
|
List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>();
|
||||||
for (UserFederationProviderEntity entity : copy) {
|
for (UserFederationProviderEntity entity : copy) {
|
||||||
result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName()));
|
result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
|
||||||
|
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName) {
|
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
|
||||||
String id = KeycloakModelUtils.generateId();
|
String id = KeycloakModelUtils.generateId();
|
||||||
UserFederationProviderEntity entity = new UserFederationProviderEntity();
|
UserFederationProviderEntity entity = new UserFederationProviderEntity();
|
||||||
entity.setId(id);
|
entity.setId(id);
|
||||||
|
@ -695,10 +696,13 @@ public class RealmAdapter implements RealmModel {
|
||||||
displayName = id;
|
displayName = id;
|
||||||
}
|
}
|
||||||
entity.setDisplayName(displayName);
|
entity.setDisplayName(displayName);
|
||||||
|
entity.setFullSyncPeriod(fullSyncPeriod);
|
||||||
|
entity.setChangedSyncPeriod(changedSyncPeriod);
|
||||||
|
entity.setLastSync(lastSync);
|
||||||
em.persist(entity);
|
em.persist(entity);
|
||||||
realm.getUserFederationProviders().add(entity);
|
realm.getUserFederationProviders().add(entity);
|
||||||
em.flush();
|
em.flush();
|
||||||
return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName);
|
return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -728,6 +732,9 @@ public class RealmAdapter implements RealmModel {
|
||||||
entity.setPriority(model.getPriority());
|
entity.setPriority(model.getPriority());
|
||||||
entity.setProviderName(model.getProviderName());
|
entity.setProviderName(model.getProviderName());
|
||||||
entity.setPriority(model.getPriority());
|
entity.setPriority(model.getPriority());
|
||||||
|
entity.setFullSyncPeriod(model.getFullSyncPeriod());
|
||||||
|
entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
|
||||||
|
entity.setLastSync(model.getLastSync());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -750,13 +757,17 @@ public class RealmAdapter implements RealmModel {
|
||||||
if (displayName != null) {
|
if (displayName != null) {
|
||||||
entity.setDisplayName(model.getDisplayName());
|
entity.setDisplayName(model.getDisplayName());
|
||||||
}
|
}
|
||||||
|
entity.setFullSyncPeriod(model.getFullSyncPeriod());
|
||||||
|
entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
|
||||||
|
entity.setLastSync(model.getLastSync());
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (found) continue;
|
if (found) continue;
|
||||||
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName()));
|
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
|
||||||
|
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
|
||||||
it.remove();
|
it.remove();
|
||||||
em.remove(entity);
|
em.remove(entity);
|
||||||
}
|
}
|
||||||
|
@ -786,6 +797,9 @@ public class RealmAdapter implements RealmModel {
|
||||||
displayName = entity.getId();
|
displayName = entity.getId();
|
||||||
}
|
}
|
||||||
entity.setDisplayName(displayName);
|
entity.setDisplayName(displayName);
|
||||||
|
entity.setFullSyncPeriod(model.getFullSyncPeriod());
|
||||||
|
entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
|
||||||
|
entity.setLastSync(model.getLastSync());
|
||||||
em.persist(entity);
|
em.persist(entity);
|
||||||
realm.getUserFederationProviders().add(entity);
|
realm.getUserFederationProviders().add(entity);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,13 @@ public class UserFederationProviderEntity {
|
||||||
@Column(name="DISPLAY_NAME")
|
@Column(name="DISPLAY_NAME")
|
||||||
private String displayName;
|
private String displayName;
|
||||||
|
|
||||||
|
@Column(name="FULL_SYNC_PERIOD")
|
||||||
|
private int fullSyncPeriod;
|
||||||
|
@Column(name="CHANGED_SYNC_PERIOD")
|
||||||
|
private int changedSyncPeriod;
|
||||||
|
@Column(name="LAST_SYNC")
|
||||||
|
private int lastSync;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -89,4 +96,28 @@ public class UserFederationProviderEntity {
|
||||||
public void setDisplayName(String displayName) {
|
public void setDisplayName(String displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getFullSyncPeriod() {
|
||||||
|
return fullSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFullSyncPeriod(int fullSyncPeriod) {
|
||||||
|
this.fullSyncPeriod = fullSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChangedSyncPeriod() {
|
||||||
|
return changedSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChangedSyncPeriod(int changedSyncPeriod) {
|
||||||
|
this.changedSyncPeriod = changedSyncPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastSync() {
|
||||||
|
return lastSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastSync(int lastSync) {
|
||||||
|
this.lastSync = lastSync;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -757,7 +757,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName) {
|
public UserFederationProviderModel addUserFederationProvider(String providerName, Map<String, String> config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) {
|
||||||
UserFederationProviderEntity entity = new UserFederationProviderEntity();
|
UserFederationProviderEntity entity = new UserFederationProviderEntity();
|
||||||
entity.setId(KeycloakModelUtils.generateId());
|
entity.setId(KeycloakModelUtils.generateId());
|
||||||
entity.setPriority(priority);
|
entity.setPriority(priority);
|
||||||
|
@ -767,10 +767,13 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
displayName = entity.getId();
|
displayName = entity.getId();
|
||||||
}
|
}
|
||||||
entity.setDisplayName(displayName);
|
entity.setDisplayName(displayName);
|
||||||
|
entity.setFullSyncPeriod(fullSyncPeriod);
|
||||||
|
entity.setChangedSyncPeriod(changedSyncPeriod);
|
||||||
|
entity.setLastSync(lastSync);
|
||||||
realm.getUserFederationProviders().add(entity);
|
realm.getUserFederationProviders().add(entity);
|
||||||
updateRealm();
|
updateRealm();
|
||||||
|
|
||||||
return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName);
|
return new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -779,7 +782,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
UserFederationProviderEntity entity = it.next();
|
UserFederationProviderEntity entity = it.next();
|
||||||
if (entity.getId().equals(provider.getId())) {
|
if (entity.getId().equals(provider.getId())) {
|
||||||
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName()));
|
session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
|
||||||
|
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -799,6 +803,9 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
if (displayName != null) {
|
if (displayName != null) {
|
||||||
entity.setDisplayName(model.getDisplayName());
|
entity.setDisplayName(model.getDisplayName());
|
||||||
}
|
}
|
||||||
|
entity.setFullSyncPeriod(model.getFullSyncPeriod());
|
||||||
|
entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
|
||||||
|
entity.setLastSync(model.getLastSync());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateRealm();
|
updateRealm();
|
||||||
|
@ -822,7 +829,8 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
});
|
});
|
||||||
List<UserFederationProviderModel> result = new LinkedList<UserFederationProviderModel>();
|
List<UserFederationProviderModel> result = new LinkedList<UserFederationProviderModel>();
|
||||||
for (UserFederationProviderEntity entity : copy) {
|
for (UserFederationProviderEntity entity : copy) {
|
||||||
result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName()));
|
result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(),
|
||||||
|
entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -843,6 +851,9 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
entity.setDisplayName(entity.getId());
|
entity.setDisplayName(entity.getId());
|
||||||
}
|
}
|
||||||
entity.setDisplayName(displayName);
|
entity.setDisplayName(displayName);
|
||||||
|
entity.setFullSyncPeriod(model.getFullSyncPeriod());
|
||||||
|
entity.setChangedSyncPeriod(model.getChangedSyncPeriod());
|
||||||
|
entity.setLastSync(model.getLastSync());
|
||||||
entities.add(entity);
|
entities.add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
package org.keycloak.services.managers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.models.KeycloakSessionTask;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserFederationProvider;
|
||||||
|
import org.keycloak.models.UserFederationProviderFactory;
|
||||||
|
import org.keycloak.models.UserFederationProviderModel;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import org.keycloak.timer.TimerProvider;
|
||||||
|
import org.keycloak.util.Time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class PeriodicSyncManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check federationProviderModel of all realms and possibly start periodic sync for them
|
||||||
|
*
|
||||||
|
* @param sessionFactory
|
||||||
|
* @param timer
|
||||||
|
*/
|
||||||
|
public void bootstrap(final KeycloakSessionFactory sessionFactory, final TimerProvider timer) {
|
||||||
|
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(KeycloakSession session) {
|
||||||
|
List<RealmModel> realms = session.realms().getRealms();
|
||||||
|
for (final RealmModel realm : realms) {
|
||||||
|
List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
|
||||||
|
for (final UserFederationProviderModel fedProvider : federationProviders) {
|
||||||
|
startPeriodicSyncForProvider(sessionFactory, timer, fedProvider, realm.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startPeriodicSyncForProvider(final KeycloakSessionFactory sessionFactory, TimerProvider timer, final UserFederationProviderModel fedProvider, final String realmId) {
|
||||||
|
final UserFederationProviderFactory fedProviderFactory = (UserFederationProviderFactory) sessionFactory.getProviderFactory(UserFederationProvider.class, fedProvider.getProviderName());
|
||||||
|
|
||||||
|
if (fedProvider.getFullSyncPeriod() > 0) {
|
||||||
|
// We want periodic full sync for this provider
|
||||||
|
timer.schedule(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
updateLastSyncInterval(sessionFactory, fedProvider, realmId);
|
||||||
|
fedProviderFactory.syncAllUsers(sessionFactory, realmId, fedProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, fedProvider.getFullSyncPeriod() * 1000, fedProvider.getId() + "-FULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fedProvider.getChangedSyncPeriod() > 0) {
|
||||||
|
// We want periodic sync of just changed users for this provider
|
||||||
|
timer.schedule(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// See when we did last sync.
|
||||||
|
int oldLastSync = fedProvider.getLastSync();
|
||||||
|
updateLastSyncInterval(sessionFactory, fedProvider, realmId);
|
||||||
|
fedProviderFactory.syncChangedUsers(sessionFactory, realmId, fedProvider, Time.toDate(oldLastSync));
|
||||||
|
}
|
||||||
|
|
||||||
|
}, fedProvider.getChangedSyncPeriod() * 1000, fedProvider.getId() + "-CHANGED");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePeriodicSyncForProvider(TimerProvider timer, final UserFederationProviderModel fedProvider) {
|
||||||
|
timer.cancelTask(fedProvider.getId() + "-FULL");
|
||||||
|
timer.cancelTask(fedProvider.getId() + "-CHANGED");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update interval of last sync for given UserFederationProviderModel. Do it in separate transaction
|
||||||
|
private void updateLastSyncInterval(final KeycloakSessionFactory sessionFactory, final UserFederationProviderModel fedProvider, final String realmId) {
|
||||||
|
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(KeycloakSession session) {
|
||||||
|
RealmModel persistentRealm = session.realms().getRealm(realmId);
|
||||||
|
List<UserFederationProviderModel> persistentFedProviders = persistentRealm.getUserFederationProviders();
|
||||||
|
for (UserFederationProviderModel persistentFedProvider : persistentFedProviders) {
|
||||||
|
if (fedProvider.getId().equals(persistentFedProvider.getId())) {
|
||||||
|
// Update persistent provider in DB
|
||||||
|
int lastSync = Time.currentTime();
|
||||||
|
persistentFedProvider.setLastSync(lastSync);
|
||||||
|
persistentRealm.updateUserFederationProvider(persistentFedProvider);
|
||||||
|
|
||||||
|
// Update "cached" reference
|
||||||
|
fedProvider.setLastSync(lastSync);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,12 +12,14 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RealmProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.UserFederationProviderModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionProvider;
|
import org.keycloak.models.UserSessionProvider;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
import org.keycloak.models.utils.RepresentationToModel;
|
||||||
import org.keycloak.representations.idm.RealmAuditRepresentation;
|
import org.keycloak.representations.idm.RealmAuditRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.timer.TimerProvider;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -127,6 +129,8 @@ public class RealmManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeRealm(RealmModel realm) {
|
public boolean removeRealm(RealmModel realm) {
|
||||||
|
List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
|
||||||
|
|
||||||
boolean removed = model.removeRealm(realm.getId());
|
boolean removed = model.removeRealm(realm.getId());
|
||||||
if (removed) {
|
if (removed) {
|
||||||
new ApplicationManager(this).removeApplication(getKeycloakAdminstrationRealm(), realm.getMasterAdminApp());
|
new ApplicationManager(this).removeApplication(getKeycloakAdminstrationRealm(), realm.getMasterAdminApp());
|
||||||
|
@ -135,6 +139,12 @@ public class RealmManager {
|
||||||
if (sessions != null) {
|
if (sessions != null) {
|
||||||
sessions.onRealmRemoved(realm);
|
sessions.onRealmRemoved(realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove all periodic syncs for configured federation providers
|
||||||
|
PeriodicSyncManager periodicSyncManager = new PeriodicSyncManager();
|
||||||
|
for (final UserFederationProviderModel fedProvider : federationProviders) {
|
||||||
|
periodicSyncManager.removePeriodicSyncForProvider(session.getProvider(TimerProvider.class), fedProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
@ -202,6 +212,13 @@ public class RealmManager {
|
||||||
|
|
||||||
public void importRealm(RealmRepresentation rep, RealmModel newRealm) {
|
public void importRealm(RealmRepresentation rep, RealmModel newRealm) {
|
||||||
RepresentationToModel.importRealm(session, rep, newRealm);
|
RepresentationToModel.importRealm(session, rep, newRealm);
|
||||||
|
|
||||||
|
// Refresh periodic sync tasks for configured federationProviders
|
||||||
|
List<UserFederationProviderModel> federationProviders = newRealm.getUserFederationProviders();
|
||||||
|
PeriodicSyncManager periodicSyncManager = new PeriodicSyncManager();
|
||||||
|
for (final UserFederationProviderModel fedProvider : federationProviders) {
|
||||||
|
periodicSyncManager.startPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), fedProvider, newRealm.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -84,8 +84,8 @@ public class KeycloakApplication extends Application {
|
||||||
|
|
||||||
setupDefaultRealm(context.getContextPath());
|
setupDefaultRealm(context.getContextPath());
|
||||||
|
|
||||||
setupScheduledTasks(sessionFactory);
|
|
||||||
importRealms(context);
|
importRealms(context);
|
||||||
|
setupScheduledTasks(sessionFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContextPath() {
|
public String getContextPath() {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserFederationProviderModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
import org.keycloak.models.cache.CacheRealmProvider;
|
import org.keycloak.models.cache.CacheRealmProvider;
|
||||||
import org.keycloak.models.cache.CacheUserProvider;
|
import org.keycloak.models.cache.CacheUserProvider;
|
||||||
|
@ -21,10 +22,12 @@ import org.keycloak.representations.adapters.action.SessionStats;
|
||||||
import org.keycloak.representations.idm.RealmAuditRepresentation;
|
import org.keycloak.representations.idm.RealmAuditRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.services.managers.LDAPConnectionTestManager;
|
import org.keycloak.services.managers.LDAPConnectionTestManager;
|
||||||
|
import org.keycloak.services.managers.PeriodicSyncManager;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.managers.ResourceAdminManager;
|
import org.keycloak.services.managers.ResourceAdminManager;
|
||||||
import org.keycloak.services.managers.TokenManager;
|
import org.keycloak.services.managers.TokenManager;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.resources.flows.Flows;
|
||||||
|
import org.keycloak.timer.TimerProvider;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
|
@ -160,6 +163,13 @@ public class RealmAdminResource {
|
||||||
cache.setEnabled(rep.isUserCacheEnabled());
|
cache.setEnabled(rep.isUserCacheEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Refresh periodic sync tasks for configured federationProviders
|
||||||
|
List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
|
||||||
|
PeriodicSyncManager periodicSyncManager = new PeriodicSyncManager();
|
||||||
|
for (final UserFederationProviderModel fedProvider : federationProviders) {
|
||||||
|
periodicSyncManager.startPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), fedProvider, realm.getId());
|
||||||
|
}
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
|
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
|
||||||
|
|
|
@ -12,6 +12,8 @@ import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.ProviderFactory;
|
||||||
import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation;
|
import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation;
|
||||||
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
|
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
|
||||||
|
import org.keycloak.services.managers.PeriodicSyncManager;
|
||||||
|
import org.keycloak.timer.TimerProvider;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
|
@ -116,7 +118,10 @@ public class UserFederationResource {
|
||||||
if (displayName != null && displayName.trim().equals("")) {
|
if (displayName != null && displayName.trim().equals("")) {
|
||||||
displayName = null;
|
displayName = null;
|
||||||
}
|
}
|
||||||
UserFederationProviderModel model = realm.addUserFederationProvider(rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName);
|
UserFederationProviderModel model = realm.addUserFederationProvider(rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName,
|
||||||
|
rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync());
|
||||||
|
new PeriodicSyncManager().startPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
|
||||||
|
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +141,10 @@ public class UserFederationResource {
|
||||||
if (displayName != null && displayName.trim().equals("")) {
|
if (displayName != null && displayName.trim().equals("")) {
|
||||||
displayName = null;
|
displayName = null;
|
||||||
}
|
}
|
||||||
UserFederationProviderModel model = new UserFederationProviderModel(id, rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName);
|
UserFederationProviderModel model = new UserFederationProviderModel(id, rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName,
|
||||||
|
rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync());
|
||||||
realm.updateUserFederationProvider(model);
|
realm.updateUserFederationProvider(model);
|
||||||
|
new PeriodicSyncManager().startPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,9 +177,9 @@ public class UserFederationResource {
|
||||||
public void deleteProviderInstance(@PathParam("id") String id) {
|
public void deleteProviderInstance(@PathParam("id") String id) {
|
||||||
logger.info("deleteProvider");
|
logger.info("deleteProvider");
|
||||||
auth.requireManage();
|
auth.requireManage();
|
||||||
UserFederationProviderModel model = new UserFederationProviderModel(id, null, null, -1, null);
|
UserFederationProviderModel model = new UserFederationProviderModel(id, null, null, -1, null, -1, -1, 0);
|
||||||
realm.removeUserFederationProvider(model);
|
realm.removeUserFederationProvider(model);
|
||||||
|
new PeriodicSyncManager().removePeriodicSyncForProvider(session.getProvider(TimerProvider.class), model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.testutils;
|
package org.keycloak.testutils;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
@ -9,12 +10,20 @@ import org.keycloak.models.UserFederationProviderModel;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class DummyUserFederationProviderFactory implements UserFederationProviderFactory {
|
public class DummyUserFederationProviderFactory implements UserFederationProviderFactory {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(DummyUserFederationProviderFactory.class);
|
||||||
|
public static final String PROVIDER_NAME = "dummy";
|
||||||
|
|
||||||
|
private AtomicInteger fullSyncCounter = new AtomicInteger();
|
||||||
|
private AtomicInteger changedSyncCounter = new AtomicInteger();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserFederationProvider getInstance(KeycloakSession session, UserFederationProviderModel model) {
|
public UserFederationProvider getInstance(KeycloakSession session, UserFederationProviderModel model) {
|
||||||
return new DummyUserFederationProvider();
|
return new DummyUserFederationProvider();
|
||||||
|
@ -44,14 +53,26 @@ public class DummyUserFederationProviderFactory implements UserFederationProvide
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "dummy";
|
return PROVIDER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void syncAllUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model) {
|
public void syncAllUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model) {
|
||||||
|
logger.info("syncAllUsers invoked");
|
||||||
|
fullSyncCounter.incrementAndGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void syncChangedUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model, Date lastSync) {
|
public void syncChangedUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model, Date lastSync) {
|
||||||
|
logger.info("syncChangedUsers invoked");
|
||||||
|
changedSyncCounter.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFullSyncCounter() {
|
||||||
|
return fullSyncCounter.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChangedSyncCounter() {
|
||||||
|
return changedSyncCounter.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class FederationProvidersIntegrationTest {
|
||||||
ldapConfig.put(LDAPFederationProvider.SYNC_REGISTRATIONS, "true");
|
ldapConfig.put(LDAPFederationProvider.SYNC_REGISTRATIONS, "true");
|
||||||
ldapConfig.put(LDAPFederationProvider.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
|
ldapConfig.put(LDAPFederationProvider.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
|
||||||
|
|
||||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap");
|
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap", -1, -1, 0);
|
||||||
|
|
||||||
// Delete all LDAP users and add some new for testing
|
// Delete all LDAP users and add some new for testing
|
||||||
PartitionManager partitionManager = getPartitionManager(manager.getSession(), ldapModel);
|
PartitionManager partitionManager = getPartitionManager(manager.getSession(), ldapModel);
|
||||||
|
@ -166,7 +166,7 @@ public class FederationProvidersIntegrationTest {
|
||||||
RealmManager manager = new RealmManager(session);
|
RealmManager manager = new RealmManager(session);
|
||||||
|
|
||||||
RealmModel appRealm = manager.getRealm("test");
|
RealmModel appRealm = manager.getRealm("test");
|
||||||
ldapModel = appRealm.addUserFederationProvider(ldapModel.getProviderName(), ldapModel.getConfig(), ldapModel.getPriority(), ldapModel.getDisplayName());
|
ldapModel = appRealm.addUserFederationProvider(ldapModel.getProviderName(), ldapModel.getConfig(), ldapModel.getPriority(), ldapModel.getDisplayName(), -1, -1, 0);
|
||||||
} finally {
|
} finally {
|
||||||
keycloakRule.stopSession(session, true);
|
keycloakRule.stopSession(session, true);
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,8 @@ public class FederationProvidersIntegrationTest {
|
||||||
try {
|
try {
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||||
|
|
||||||
UserFederationProviderModel model = new UserFederationProviderModel(ldapModel.getId(), ldapModel.getProviderName(), ldapModel.getConfig(), ldapModel.getPriority(), ldapModel.getDisplayName());
|
UserFederationProviderModel model = new UserFederationProviderModel(ldapModel.getId(), ldapModel.getProviderName(), ldapModel.getConfig(),
|
||||||
|
ldapModel.getPriority(), ldapModel.getDisplayName(), -1, -1, 0);
|
||||||
model.getConfig().put(LDAPFederationProvider.EDIT_MODE, UserFederationProvider.EditMode.READ_ONLY.toString());
|
model.getConfig().put(LDAPFederationProvider.EDIT_MODE, UserFederationProvider.EditMode.READ_ONLY.toString());
|
||||||
appRealm.updateUserFederationProvider(model);
|
appRealm.updateUserFederationProvider(model);
|
||||||
UserModel user = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel user = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
|
@ -284,7 +285,8 @@ public class FederationProvidersIntegrationTest {
|
||||||
try {
|
try {
|
||||||
RealmModel appRealm = session.realms().getRealmByName("test");
|
RealmModel appRealm = session.realms().getRealmByName("test");
|
||||||
|
|
||||||
UserFederationProviderModel model = new UserFederationProviderModel(ldapModel.getId(), ldapModel.getProviderName(), ldapModel.getConfig(), ldapModel.getPriority(), ldapModel.getDisplayName());
|
UserFederationProviderModel model = new UserFederationProviderModel(ldapModel.getId(), ldapModel.getProviderName(), ldapModel.getConfig(), ldapModel.getPriority(),
|
||||||
|
ldapModel.getDisplayName(), -1, -1, 0);
|
||||||
model.getConfig().put(LDAPFederationProvider.EDIT_MODE, UserFederationProvider.EditMode.UNSYNCED.toString());
|
model.getConfig().put(LDAPFederationProvider.EDIT_MODE, UserFederationProvider.EditMode.UNSYNCED.toString());
|
||||||
appRealm.updateUserFederationProvider(model);
|
appRealm.updateUserFederationProvider(model);
|
||||||
UserModel user = session.users().getUserByUsername("johnkeycloak", appRealm);
|
UserModel user = session.users().getUserByUsername("johnkeycloak", appRealm);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.keycloak.testsuite.forms;
|
package org.keycloak.testsuite.forms;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
@ -10,6 +11,7 @@ import org.junit.Test;
|
||||||
import org.junit.rules.RuleChain;
|
import org.junit.rules.RuleChain;
|
||||||
import org.junit.rules.TestRule;
|
import org.junit.rules.TestRule;
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.keycloak.examples.federation.properties.ClasspathPropertiesFederationFactory;
|
||||||
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
import org.keycloak.federation.ldap.LDAPFederationProvider;
|
||||||
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
|
||||||
import org.keycloak.federation.ldap.LDAPUtils;
|
import org.keycloak.federation.ldap.LDAPUtils;
|
||||||
|
@ -21,10 +23,14 @@ import org.keycloak.models.UserFederationProviderFactory;
|
||||||
import org.keycloak.models.UserFederationProviderModel;
|
import org.keycloak.models.UserFederationProviderModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserProvider;
|
import org.keycloak.models.UserProvider;
|
||||||
|
import org.keycloak.services.managers.PeriodicSyncManager;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||||
import org.keycloak.testsuite.rule.LDAPRule;
|
import org.keycloak.testsuite.rule.LDAPRule;
|
||||||
|
import org.keycloak.testutils.DummyUserFederationProvider;
|
||||||
|
import org.keycloak.testutils.DummyUserFederationProviderFactory;
|
||||||
import org.keycloak.testutils.LDAPEmbeddedServer;
|
import org.keycloak.testutils.LDAPEmbeddedServer;
|
||||||
|
import org.keycloak.timer.TimerProvider;
|
||||||
import org.picketlink.idm.PartitionManager;
|
import org.picketlink.idm.PartitionManager;
|
||||||
import org.picketlink.idm.model.basic.User;
|
import org.picketlink.idm.model.basic.User;
|
||||||
|
|
||||||
|
@ -37,6 +43,7 @@ public class SyncProvidersTest {
|
||||||
private static LDAPRule ldapRule = new LDAPRule();
|
private static LDAPRule ldapRule = new LDAPRule();
|
||||||
|
|
||||||
private static UserFederationProviderModel ldapModel = null;
|
private static UserFederationProviderModel ldapModel = null;
|
||||||
|
private static UserFederationProviderModel dummyModel = null;
|
||||||
|
|
||||||
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
|
||||||
|
|
||||||
|
@ -47,7 +54,8 @@ public class SyncProvidersTest {
|
||||||
ldapConfig.put(LDAPFederationProvider.SYNC_REGISTRATIONS, "false");
|
ldapConfig.put(LDAPFederationProvider.SYNC_REGISTRATIONS, "false");
|
||||||
ldapConfig.put(LDAPFederationProvider.EDIT_MODE, UserFederationProvider.EditMode.UNSYNCED.toString());
|
ldapConfig.put(LDAPFederationProvider.EDIT_MODE, UserFederationProvider.EditMode.UNSYNCED.toString());
|
||||||
|
|
||||||
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap");
|
ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap",
|
||||||
|
-1, -1, 0);
|
||||||
|
|
||||||
// Delete all LDAP users and add 5 new users for testing
|
// Delete all LDAP users and add 5 new users for testing
|
||||||
PartitionManager partitionManager = FederationProvidersIntegrationTest.getPartitionManager(manager.getSession(), ldapModel);
|
PartitionManager partitionManager = FederationProvidersIntegrationTest.getPartitionManager(manager.getSession(), ldapModel);
|
||||||
|
@ -65,9 +73,7 @@ public class SyncProvidersTest {
|
||||||
LDAPUtils.updatePassword(partitionManager, user5, "password5");
|
LDAPUtils.updatePassword(partitionManager, user5, "password5");
|
||||||
|
|
||||||
// Add properties provider
|
// Add properties provider
|
||||||
// Map<String,String> filePropertiesConfig = new HashMap<String, String>();
|
dummyModel = appRealm.addUserFederationProvider(DummyUserFederationProviderFactory.PROVIDER_NAME, new HashMap<String, String>(), 1, "test-dummy", -1, 1, 0);
|
||||||
// filePropertiesConfig.put("path", );
|
|
||||||
// appRealm.addUserFederationProvider(FilePropertiesFederationFactory.PROVIDER_NAME, filePropertiesConfig, 1, "test-fileProps");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -99,11 +105,7 @@ public class SyncProvidersTest {
|
||||||
assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org");
|
assertUserImported(userProvider, testRealm, "user5", "User5FN", "User5LN", "user5@email.org");
|
||||||
|
|
||||||
// wait a bit
|
// wait a bit
|
||||||
try {
|
sleep(1000);
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
throw new RuntimeException(ie);
|
|
||||||
}
|
|
||||||
Date beforeLDAPUpdate = new Date();
|
Date beforeLDAPUpdate = new Date();
|
||||||
|
|
||||||
// Add user to LDAP and update 'user5' in LDAP
|
// Add user to LDAP and update 'user5' in LDAP
|
||||||
|
@ -135,6 +137,45 @@ public class SyncProvidersTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPeriodicSync() {
|
||||||
|
KeycloakSession session = keycloakRule.startSession();
|
||||||
|
try {
|
||||||
|
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||||
|
DummyUserFederationProviderFactory dummyFedFactory = (DummyUserFederationProviderFactory)sessionFactory.getProviderFactory(UserFederationProvider.class, DummyUserFederationProviderFactory.PROVIDER_NAME);
|
||||||
|
int full = dummyFedFactory.getFullSyncCounter();
|
||||||
|
int changed = dummyFedFactory.getChangedSyncCounter();
|
||||||
|
|
||||||
|
// Assert that after some period was DummyUserFederationProvider triggered
|
||||||
|
PeriodicSyncManager periodicSyncManager = new PeriodicSyncManager();
|
||||||
|
periodicSyncManager.bootstrap(sessionFactory, session.getProvider(TimerProvider.class));
|
||||||
|
sleep(1800);
|
||||||
|
|
||||||
|
// Cancel timer
|
||||||
|
periodicSyncManager.removePeriodicSyncForProvider(session.getProvider(TimerProvider.class), dummyModel);
|
||||||
|
|
||||||
|
// Assert that DummyUserFederationProviderFactory.syncChangedUsers was invoked
|
||||||
|
int newChanged = dummyFedFactory.getChangedSyncCounter();
|
||||||
|
Assert.assertEquals(full, dummyFedFactory.getFullSyncCounter());
|
||||||
|
Assert.assertTrue(newChanged > changed);
|
||||||
|
|
||||||
|
// Assert that dummy provider won't be invoked anymore
|
||||||
|
sleep(1800);
|
||||||
|
Assert.assertEquals(full, dummyFedFactory.getFullSyncCounter());
|
||||||
|
Assert.assertEquals(newChanged, dummyFedFactory.getChangedSyncCounter());
|
||||||
|
} finally {
|
||||||
|
keycloakRule.stopSession(session, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sleep(int time) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(time);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
throw new RuntimeException(ie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void assertUserImported(UserProvider userProvider, RealmModel realm, String username, String expectedFirstName, String expectedLastName, String expectedEmail) {
|
private void assertUserImported(UserProvider userProvider, RealmModel realm, String username, String expectedFirstName, String expectedLastName, String expectedEmail) {
|
||||||
UserModel user = userProvider.getUserByUsername(username, realm);
|
UserModel user = userProvider.getUserByUsername(username, realm);
|
||||||
Assert.assertNotNull(user);
|
Assert.assertNotNull(user);
|
||||||
|
|
Loading…
Reference in a new issue