commit
e4b3007ce2
213 changed files with 2101 additions and 2043 deletions
8
audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java
Normal file → Executable file
8
audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java
Normal file → Executable file
|
@ -7,7 +7,7 @@ import org.keycloak.audit.EventType;
|
||||||
import org.keycloak.email.EmailException;
|
import org.keycloak.email.EmailException;
|
||||||
import org.keycloak.email.EmailProvider;
|
import org.keycloak.email.EmailProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
|
||||||
|
@ -21,13 +21,13 @@ public class EmailAuditListener implements AuditListener {
|
||||||
private static final Logger log = Logger.getLogger(EmailAuditListener.class);
|
private static final Logger log = Logger.getLogger(EmailAuditListener.class);
|
||||||
|
|
||||||
private KeycloakSession session;
|
private KeycloakSession session;
|
||||||
private ModelProvider model;
|
private RealmProvider model;
|
||||||
private EmailProvider emailProvider;
|
private EmailProvider emailProvider;
|
||||||
private Set<EventType> includedEvents;
|
private Set<EventType> includedEvents;
|
||||||
|
|
||||||
public EmailAuditListener(KeycloakSession session, EmailProvider emailProvider, Set<EventType> includedEvents) {
|
public EmailAuditListener(KeycloakSession session, EmailProvider emailProvider, Set<EventType> includedEvents) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.model = session.model();
|
this.model = session.realms();
|
||||||
this.emailProvider = emailProvider;
|
this.emailProvider = emailProvider;
|
||||||
this.includedEvents = includedEvents;
|
this.includedEvents = includedEvents;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public class EmailAuditListener implements AuditListener {
|
||||||
if (includedEvents.contains(event.getEvent())) {
|
if (includedEvents.contains(event.getEvent())) {
|
||||||
if (event.getRealmId() != null && event.getUserId() != null) {
|
if (event.getRealmId() != null && event.getUserId() != null) {
|
||||||
RealmModel realm = model.getRealm(event.getRealmId());
|
RealmModel realm = model.getRealm(event.getRealmId());
|
||||||
UserModel user = realm.getUserById(event.getUserId());
|
UserModel user = session.users().getUserById(event.getUserId(), realm);
|
||||||
if (user != null && user.getEmail() != null && user.isEmailVerified()) {
|
if (user != null && user.getEmail() != null && user.isEmailVerified()) {
|
||||||
try {
|
try {
|
||||||
emailProvider.setRealm(realm).setUser(user).sendEvent(event);
|
emailProvider.setRealm(realm).setUser(user).sendEvent(event);
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.keycloak.authentication.model;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
@ -22,17 +23,23 @@ public abstract class AbstractModelAuthenticationProvider implements Authenticat
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(AbstractModelAuthenticationProvider.class);
|
private static final Logger logger = Logger.getLogger(AbstractModelAuthenticationProvider.class);
|
||||||
|
|
||||||
|
protected KeycloakSession keycloakSession;
|
||||||
|
|
||||||
|
protected AbstractModelAuthenticationProvider(KeycloakSession keycloakSession) {
|
||||||
|
this.keycloakSession = keycloakSession;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthUser getUser(RealmModel currentRealm, Map<String, String> config, String username) throws AuthenticationProviderException {
|
public AuthUser getUser(RealmModel currentRealm, Map<String, String> config, String username) throws AuthenticationProviderException {
|
||||||
RealmModel realm = getRealm(currentRealm, config);
|
RealmModel realm = getRealm(currentRealm, config);
|
||||||
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(realm, username);
|
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(keycloakSession, realm, username);
|
||||||
return user == null ? null : createAuthenticatedUserInstance(user);
|
return user == null ? null : createAuthenticatedUserInstance(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String registerUser(RealmModel currentRealm, Map<String, String> config, UserModel user) throws AuthenticationProviderException {
|
public String registerUser(RealmModel currentRealm, Map<String, String> config, UserModel user) throws AuthenticationProviderException {
|
||||||
RealmModel realm = getRealm(currentRealm, config);
|
RealmModel realm = getRealm(currentRealm, config);
|
||||||
UserModel newUser = realm.addUser(user.getUsername());
|
UserModel newUser = keycloakSession.users().addUser(realm, user.getUsername());
|
||||||
newUser.setFirstName(user.getFirstName());
|
newUser.setFirstName(user.getFirstName());
|
||||||
newUser.setLastName(user.getLastName());
|
newUser.setLastName(user.getLastName());
|
||||||
newUser.setEmail(user.getEmail());
|
newUser.setEmail(user.getEmail());
|
||||||
|
@ -43,7 +50,7 @@ public abstract class AbstractModelAuthenticationProvider implements Authenticat
|
||||||
@Override
|
@Override
|
||||||
public AuthProviderStatus validatePassword(RealmModel currentRealm, Map<String, String> config, String username, String password) throws AuthenticationProviderException {
|
public AuthProviderStatus validatePassword(RealmModel currentRealm, Map<String, String> config, String username, String password) throws AuthenticationProviderException {
|
||||||
RealmModel realm = getRealm(currentRealm, config);
|
RealmModel realm = getRealm(currentRealm, config);
|
||||||
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(realm, username);
|
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(keycloakSession, realm, username);
|
||||||
|
|
||||||
boolean result = realm.validatePassword(user, password);
|
boolean result = realm.validatePassword(user, password);
|
||||||
return result ? AuthProviderStatus.SUCCESS : AuthProviderStatus.INVALID_CREDENTIALS;
|
return result ? AuthProviderStatus.SUCCESS : AuthProviderStatus.INVALID_CREDENTIALS;
|
||||||
|
@ -59,7 +66,7 @@ public abstract class AbstractModelAuthenticationProvider implements Authenticat
|
||||||
throw new AuthenticationProviderException(error);
|
throw new AuthenticationProviderException(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel user = realm.getUser(username);
|
UserModel user = keycloakSession.users().getUserByUsername(username, realm);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
logger.warnf("User '%s' doesn't exists. Skip password update", username);
|
logger.warnf("User '%s' doesn't exists. Skip password update", username);
|
||||||
return false;
|
return false;
|
||||||
|
|
6
authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ExternalModelAuthenticationProvider.java
Normal file → Executable file
6
authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ExternalModelAuthenticationProvider.java
Normal file → Executable file
|
@ -3,7 +3,6 @@ package org.keycloak.authentication.model;
|
||||||
import org.keycloak.authentication.AuthProviderConstants;
|
import org.keycloak.authentication.AuthProviderConstants;
|
||||||
import org.keycloak.authentication.AuthenticationProviderException;
|
import org.keycloak.authentication.AuthenticationProviderException;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelProvider;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -17,10 +16,9 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public class ExternalModelAuthenticationProvider extends AbstractModelAuthenticationProvider {
|
public class ExternalModelAuthenticationProvider extends AbstractModelAuthenticationProvider {
|
||||||
|
|
||||||
private ModelProvider model;
|
|
||||||
|
|
||||||
public ExternalModelAuthenticationProvider(KeycloakSession session) {
|
public ExternalModelAuthenticationProvider(KeycloakSession session) {
|
||||||
this.model = session.model();
|
super(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -40,7 +38,7 @@ public class ExternalModelAuthenticationProvider extends AbstractModelAuthentica
|
||||||
throw new AuthenticationProviderException("Option '" + AuthProviderConstants.EXTERNAL_REALM_ID + "' not specified in configuration");
|
throw new AuthenticationProviderException("Option '" + AuthProviderConstants.EXTERNAL_REALM_ID + "' not specified in configuration");
|
||||||
}
|
}
|
||||||
|
|
||||||
RealmModel realm = model.getRealm(realmId);
|
RealmModel realm = keycloakSession.realms().getRealm(realmId);
|
||||||
if (realm == null) {
|
if (realm == null) {
|
||||||
throw new AuthenticationProviderException("Realm with id '" + realmId + "' doesn't exists");
|
throw new AuthenticationProviderException("Realm with id '" + realmId + "' doesn't exists");
|
||||||
}
|
}
|
||||||
|
|
5
authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProvider.java
Normal file → Executable file
5
authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProvider.java
Normal file → Executable file
|
@ -4,6 +4,7 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.authentication.AuthProviderConstants;
|
import org.keycloak.authentication.AuthProviderConstants;
|
||||||
|
|
||||||
|
@ -14,6 +15,10 @@ import org.keycloak.authentication.AuthProviderConstants;
|
||||||
*/
|
*/
|
||||||
public class ModelAuthenticationProvider extends AbstractModelAuthenticationProvider {
|
public class ModelAuthenticationProvider extends AbstractModelAuthenticationProvider {
|
||||||
|
|
||||||
|
public ModelAuthenticationProvider(KeycloakSession keycloakSession) {
|
||||||
|
super(keycloakSession);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return AuthProviderConstants.PROVIDER_NAME_MODEL;
|
return AuthProviderConstants.PROVIDER_NAME_MODEL;
|
||||||
|
|
2
authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProviderFactory.java
Normal file → Executable file
2
authentication/authentication-model/src/main/java/org/keycloak/authentication/model/ModelAuthenticationProviderFactory.java
Normal file → Executable file
|
@ -13,7 +13,7 @@ public class ModelAuthenticationProviderFactory implements AuthenticationProvide
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticationProvider create(KeycloakSession session) {
|
public AuthenticationProvider create(KeycloakSession session) {
|
||||||
return new ModelAuthenticationProvider();
|
return new ModelAuthenticationProvider(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
15
export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
Normal file → Executable file
15
export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
Normal file → Executable file
|
@ -22,6 +22,7 @@ import org.keycloak.exportimport.Strategy;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.AuthenticationLinkModel;
|
import org.keycloak.models.AuthenticationLinkModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleContainerModel;
|
import org.keycloak.models.RoleContainerModel;
|
||||||
|
@ -47,7 +48,7 @@ import org.keycloak.representations.idm.UserRepresentation;
|
||||||
*/
|
*/
|
||||||
public class ExportUtils {
|
public class ExportUtils {
|
||||||
|
|
||||||
public static RealmRepresentation exportRealm(RealmModel realm, boolean includeUsers) {
|
public static RealmRepresentation exportRealm(KeycloakSession session, RealmModel realm, boolean includeUsers) {
|
||||||
RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm);
|
RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm);
|
||||||
|
|
||||||
// Audit
|
// Audit
|
||||||
|
@ -147,10 +148,10 @@ public class ExportUtils {
|
||||||
|
|
||||||
// Finally users if needed
|
// Finally users if needed
|
||||||
if (includeUsers) {
|
if (includeUsers) {
|
||||||
List<UserModel> allUsers = realm.getUsers();
|
List<UserModel> allUsers = session.users().getUsers(realm);
|
||||||
List<UserRepresentation> users = new ArrayList<UserRepresentation>();
|
List<UserRepresentation> users = new ArrayList<UserRepresentation>();
|
||||||
for (UserModel user : allUsers) {
|
for (UserModel user : allUsers) {
|
||||||
UserRepresentation userRep = exportUser(realm, user);
|
UserRepresentation userRep = exportUser(session, realm, user);
|
||||||
users.add(userRep);
|
users.add(userRep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +252,7 @@ public class ExportUtils {
|
||||||
* @param user
|
* @param user
|
||||||
* @return fully exported user representation
|
* @return fully exported user representation
|
||||||
*/
|
*/
|
||||||
public static UserRepresentation exportUser(RealmModel realm, UserModel user) {
|
public static UserRepresentation exportUser(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||||
UserRepresentation userRep = ModelToRepresentation.toRepresentation(user);
|
UserRepresentation userRep = ModelToRepresentation.toRepresentation(user);
|
||||||
|
|
||||||
// AuthenticationLink
|
// AuthenticationLink
|
||||||
|
@ -262,7 +263,7 @@ public class ExportUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Social links
|
// Social links
|
||||||
Set<SocialLinkModel> socialLinks = realm.getSocialLinks(user);
|
Set<SocialLinkModel> socialLinks = session.users().getSocialLinks(user, realm);
|
||||||
List<SocialLinkRepresentation> socialLinkReps = new ArrayList<SocialLinkRepresentation>();
|
List<SocialLinkRepresentation> socialLinkReps = new ArrayList<SocialLinkRepresentation>();
|
||||||
for (SocialLinkModel socialLink : socialLinks) {
|
for (SocialLinkModel socialLink : socialLinks) {
|
||||||
SocialLinkRepresentation socialLinkRep = exportSocialLink(socialLink);
|
SocialLinkRepresentation socialLinkRep = exportSocialLink(socialLink);
|
||||||
|
@ -338,7 +339,7 @@ public class ExportUtils {
|
||||||
|
|
||||||
// Streaming API
|
// Streaming API
|
||||||
|
|
||||||
public static void exportUsersToStream(RealmModel realm, List<UserModel> usersToExport, ObjectMapper mapper, OutputStream os) throws IOException {
|
public static void exportUsersToStream(KeycloakSession session, RealmModel realm, List<UserModel> usersToExport, ObjectMapper mapper, OutputStream os) throws IOException {
|
||||||
JsonFactory factory = mapper.getJsonFactory();
|
JsonFactory factory = mapper.getJsonFactory();
|
||||||
JsonGenerator generator = factory.createJsonGenerator(os, JsonEncoding.UTF8);
|
JsonGenerator generator = factory.createJsonGenerator(os, JsonEncoding.UTF8);
|
||||||
try {
|
try {
|
||||||
|
@ -352,7 +353,7 @@ public class ExportUtils {
|
||||||
generator.writeStartArray();
|
generator.writeStartArray();
|
||||||
|
|
||||||
for (UserModel user : usersToExport) {
|
for (UserModel user : usersToExport) {
|
||||||
UserRepresentation userRep = ExportUtils.exportUser(realm, user);
|
UserRepresentation userRep = ExportUtils.exportUser(session, realm, user);
|
||||||
generator.writeObject(userRep);
|
generator.writeObject(userRep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
Normal file → Executable file
23
export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ImportUtils.java
Normal file → Executable file
|
@ -2,17 +2,13 @@ package org.keycloak.exportimport.util;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.codehaus.jackson.JsonEncoding;
|
|
||||||
import org.codehaus.jackson.JsonFactory;
|
import org.codehaus.jackson.JsonFactory;
|
||||||
import org.codehaus.jackson.JsonGenerator;
|
|
||||||
import org.codehaus.jackson.JsonParser;
|
import org.codehaus.jackson.JsonParser;
|
||||||
import org.codehaus.jackson.JsonToken;
|
import org.codehaus.jackson.JsonToken;
|
||||||
import org.codehaus.jackson.io.SerializedString;
|
|
||||||
import org.codehaus.jackson.map.ObjectMapper;
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
|
@ -20,10 +16,9 @@ import org.keycloak.exportimport.Strategy;
|
||||||
import org.keycloak.models.AdminRoles;
|
import org.keycloak.models.AdminRoles;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
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.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
@ -46,7 +41,7 @@ public class ImportUtils {
|
||||||
*/
|
*/
|
||||||
public static RealmModel importRealm(KeycloakSession session, RealmRepresentation rep, Strategy strategy) {
|
public static RealmModel importRealm(KeycloakSession session, RealmRepresentation rep, Strategy strategy) {
|
||||||
String realmName = rep.getRealm();
|
String realmName = rep.getRealm();
|
||||||
ModelProvider model = session.model();
|
RealmProvider model = session.realms();
|
||||||
RealmModel realm = model.getRealmByName(realmName);
|
RealmModel realm = model.getRealmByName(realmName);
|
||||||
|
|
||||||
if (realm != null) {
|
if (realm != null) {
|
||||||
|
@ -64,7 +59,7 @@ public class ImportUtils {
|
||||||
|
|
||||||
realm = rep.getId() != null ? model.createRealm(rep.getId(), realmName) : model.createRealm(realmName);
|
realm = rep.getId() != null ? model.createRealm(rep.getId(), realmName) : model.createRealm(realmName);
|
||||||
|
|
||||||
RepresentationToModel.importRealm(rep, realm);
|
RepresentationToModel.importRealm(session, rep, realm);
|
||||||
|
|
||||||
refreshMasterAdminApps(model, realm);
|
refreshMasterAdminApps(model, realm);
|
||||||
|
|
||||||
|
@ -72,7 +67,7 @@ public class ImportUtils {
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void refreshMasterAdminApps(ModelProvider model, RealmModel realm) {
|
private static void refreshMasterAdminApps(RealmProvider model, RealmModel realm) {
|
||||||
String adminRealmId = Config.getAdminRealm();
|
String adminRealmId = Config.getAdminRealm();
|
||||||
if (adminRealmId.equals(realm.getId())) {
|
if (adminRealmId.equals(realm.getId())) {
|
||||||
// We just imported master realm. All 'masterAdminApps' need to be refreshed
|
// We just imported master realm. All 'masterAdminApps' need to be refreshed
|
||||||
|
@ -98,7 +93,7 @@ public class ImportUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We need method here, so we are able to refresh masterAdmin applications after import. Should be RealmManager moved to model/api instead?
|
// TODO: We need method here, so we are able to refresh masterAdmin applications after import. Should be RealmManager moved to model/api instead?
|
||||||
public static void setupMasterAdminManagement(ModelProvider model, RealmModel realm) {
|
public static void setupMasterAdminManagement(RealmProvider model, RealmModel realm) {
|
||||||
RealmModel adminRealm;
|
RealmModel adminRealm;
|
||||||
RoleModel adminRole;
|
RoleModel adminRole;
|
||||||
|
|
||||||
|
@ -160,7 +155,7 @@ public class ImportUtils {
|
||||||
|
|
||||||
// Assuming that it's invoked inside transaction
|
// Assuming that it's invoked inside transaction
|
||||||
public static void importUsersFromStream(KeycloakSession session, String realmName, ObjectMapper mapper, InputStream is) throws IOException {
|
public static void importUsersFromStream(KeycloakSession session, String realmName, ObjectMapper mapper, InputStream is) throws IOException {
|
||||||
ModelProvider model = session.model();
|
RealmProvider model = session.realms();
|
||||||
JsonFactory factory = mapper.getJsonFactory();
|
JsonFactory factory = mapper.getJsonFactory();
|
||||||
JsonParser parser = factory.createJsonParser(is);
|
JsonParser parser = factory.createJsonParser(is);
|
||||||
try {
|
try {
|
||||||
|
@ -188,7 +183,7 @@ public class ImportUtils {
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
importUsers(model, realmName, userReps);
|
importUsers(session, model, realmName, userReps);
|
||||||
|
|
||||||
if (parser.getCurrentToken() == JsonToken.END_ARRAY) {
|
if (parser.getCurrentToken() == JsonToken.END_ARRAY) {
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
|
@ -200,11 +195,11 @@ public class ImportUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void importUsers(ModelProvider model, String realmName, List<UserRepresentation> userReps) {
|
private static void importUsers(KeycloakSession session, RealmProvider model, String realmName, List<UserRepresentation> userReps) {
|
||||||
RealmModel realm = model.getRealmByName(realmName);
|
RealmModel realm = model.getRealmByName(realmName);
|
||||||
Map<String, ApplicationModel> apps = realm.getApplicationNameMap();
|
Map<String, ApplicationModel> apps = realm.getApplicationNameMap();
|
||||||
for (UserRepresentation user : userReps) {
|
for (UserRepresentation user : userReps) {
|
||||||
RepresentationToModel.createUser(realm, user, apps);
|
RepresentationToModel.createUser(session, realm, user, apps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
Normal file → Executable file
16
export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java
Normal file → Executable file
|
@ -28,7 +28,7 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(KeycloakSession session) {
|
public void run(KeycloakSession session) {
|
||||||
List<RealmModel> realms = session.model().getRealms();
|
List<RealmModel> realms = session.realms().getRealms();
|
||||||
holder.realms = realms;
|
holder.realms = realms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,15 +49,15 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(KeycloakSession session) throws IOException {
|
public void run(KeycloakSession session) throws IOException {
|
||||||
RealmModel realm = session.model().getRealmByName(realmName);
|
RealmModel realm = session.realms().getRealmByName(realmName);
|
||||||
RealmRepresentation rep = ExportUtils.exportRealm(realm, exportUsersIntoSameFile);
|
RealmRepresentation rep = ExportUtils.exportRealm(session, realm, exportUsersIntoSameFile);
|
||||||
writeRealm(realmName + "-realm.json", rep);
|
writeRealm(realmName + "-realm.json", rep);
|
||||||
logger.info("Realm '" + realmName + "' - data exported");
|
logger.info("Realm '" + realmName + "' - data exported");
|
||||||
|
|
||||||
// Count total number of users
|
// Count total number of users
|
||||||
if (!exportUsersIntoSameFile) {
|
if (!exportUsersIntoSameFile) {
|
||||||
// TODO: getUsersCount method on model
|
// TODO: getUsersCount method on model
|
||||||
usersHolder.totalCount = realm.getUsers().size();
|
usersHolder.totalCount = session.users().getUsers(realm).size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(KeycloakSession session) throws IOException {
|
public void run(KeycloakSession session) throws IOException {
|
||||||
RealmModel realm = session.model().getRealmByName(realmName);
|
RealmModel realm = session.realms().getRealmByName(realmName);
|
||||||
// TODO: pagination
|
// TODO: pagination
|
||||||
List<UserModel> users = realm.getUsers();
|
List<UserModel> users = session.users().getUsers(realm);
|
||||||
usersHolder.users = users.subList(usersHolder.currentPageStart, usersHolder.currentPageEnd);
|
usersHolder.users = users.subList(usersHolder.currentPageStart, usersHolder.currentPageEnd);
|
||||||
|
|
||||||
writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", realm, usersHolder.users);
|
writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", session, realm, usersHolder.users);
|
||||||
|
|
||||||
logger.info("Users " + usersHolder.currentPageStart + "-" + usersHolder.currentPageEnd + " exported");
|
logger.info("Users " + usersHolder.currentPageStart + "-" + usersHolder.currentPageEnd + " exported");
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
|
||||||
|
|
||||||
protected abstract void writeRealm(String fileName, RealmRepresentation rep) throws IOException;
|
protected abstract void writeRealm(String fileName, RealmRepresentation rep) throws IOException;
|
||||||
|
|
||||||
protected abstract void writeUsers(String fileName, RealmModel realm, List<UserModel> users) throws IOException;
|
protected abstract void writeUsers(String fileName, KeycloakSession session, RealmModel realm, List<UserModel> users) throws IOException;
|
||||||
|
|
||||||
public static class RealmsHolder {
|
public static class RealmsHolder {
|
||||||
List<RealmModel> realms;
|
List<RealmModel> realms;
|
||||||
|
|
5
export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java
Normal file → Executable file
5
export-import/export-import-dir/src/main/java/org/keycloak/exportimport/dir/DirExportProvider.java
Normal file → Executable file
|
@ -7,6 +7,7 @@ import java.util.List;
|
||||||
|
|
||||||
import org.keycloak.exportimport.util.ExportUtils;
|
import org.keycloak.exportimport.util.ExportUtils;
|
||||||
import org.keycloak.exportimport.util.MultipleStepsExportProvider;
|
import org.keycloak.exportimport.util.MultipleStepsExportProvider;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
@ -61,10 +62,10 @@ public class DirExportProvider extends MultipleStepsExportProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void writeUsers(String fileName, RealmModel realm, List<UserModel> users) throws IOException {
|
protected void writeUsers(String fileName, KeycloakSession session, RealmModel realm, List<UserModel> users) throws IOException {
|
||||||
File file = new File(this.rootDirectory, fileName);
|
File file = new File(this.rootDirectory, fileName);
|
||||||
FileOutputStream os = new FileOutputStream(file);
|
FileOutputStream os = new FileOutputStream(file);
|
||||||
ExportUtils.exportUsersToStream(realm, users, JsonSerialization.prettyMapper, os);
|
ExportUtils.exportUsersToStream(session, realm, users, JsonSerialization.prettyMapper, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
8
export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProvider.java
Normal file → Executable file
8
export-import/export-import-single-file/src/main/java/org/keycloak/exportimport/singlefile/SingleFileExportProvider.java
Normal file → Executable file
|
@ -42,10 +42,10 @@ public class SingleFileExportProvider implements ExportProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(KeycloakSession session) throws IOException {
|
public void run(KeycloakSession session) throws IOException {
|
||||||
List<RealmModel> realms = session.model().getRealms();
|
List<RealmModel> realms = session.realms().getRealms();
|
||||||
List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
|
List<RealmRepresentation> reps = new ArrayList<RealmRepresentation>();
|
||||||
for (RealmModel realm : realms) {
|
for (RealmModel realm : realms) {
|
||||||
reps.add(ExportUtils.exportRealm(realm, true));
|
reps.add(ExportUtils.exportRealm(session, realm, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
writeToFile(reps);
|
writeToFile(reps);
|
||||||
|
@ -62,8 +62,8 @@ public class SingleFileExportProvider implements ExportProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(KeycloakSession session) throws IOException {
|
public void run(KeycloakSession session) throws IOException {
|
||||||
RealmModel realm = session.model().getRealmByName(realmName);
|
RealmModel realm = session.realms().getRealmByName(realmName);
|
||||||
RealmRepresentation realmRep = ExportUtils.exportRealm(realm, true);
|
RealmRepresentation realmRep = ExportUtils.exportRealm(session, realm, true);
|
||||||
writeToFile(realmRep);
|
writeToFile(realmRep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipExportProvider.java
Normal file → Executable file
5
export-import/export-import-zip/src/main/java/org/keycloak/exportimport/zip/ZipExportProvider.java
Normal file → Executable file
|
@ -12,6 +12,7 @@ import de.idyl.winzipaes.impl.AESEncrypterBC;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.exportimport.util.ExportUtils;
|
import org.keycloak.exportimport.util.ExportUtils;
|
||||||
import org.keycloak.exportimport.util.MultipleStepsExportProvider;
|
import org.keycloak.exportimport.util.MultipleStepsExportProvider;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
@ -53,9 +54,9 @@ public class ZipExportProvider extends MultipleStepsExportProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void writeUsers(String fileName, RealmModel realm, List<UserModel> users) throws IOException {
|
protected void writeUsers(String fileName, KeycloakSession session, RealmModel realm, List<UserModel> users) throws IOException {
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
ExportUtils.exportUsersToStream(realm, users, JsonSerialization.mapper, stream);
|
ExportUtils.exportUsersToStream(session, realm, users, JsonSerialization.mapper, stream);
|
||||||
|
|
||||||
byte[] byteArray = stream.toByteArray();
|
byte[] byteArray = stream.toByteArray();
|
||||||
ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
|
ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
|
||||||
attributes.put("totp", new TotpBean(user, baseUri));
|
attributes.put("totp", new TotpBean(user, baseUri));
|
||||||
break;
|
break;
|
||||||
case SOCIAL:
|
case SOCIAL:
|
||||||
attributes.put("social", new AccountSocialBean(realm, user, uriInfo.getBaseUri()));
|
attributes.put("social", new AccountSocialBean(session, realm, user, uriInfo.getBaseUri()));
|
||||||
break;
|
break;
|
||||||
case LOG:
|
case LOG:
|
||||||
attributes.put("log", new LogBean(events));
|
attributes.put("log", new LogBean(events));
|
||||||
|
|
|
@ -8,6 +8,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.SocialLinkModel;
|
import org.keycloak.models.SocialLinkModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
@ -22,13 +23,15 @@ public class AccountSocialBean {
|
||||||
|
|
||||||
private final List<SocialLinkEntry> socialLinks;
|
private final List<SocialLinkEntry> socialLinks;
|
||||||
private final boolean removeLinkPossible;
|
private final boolean removeLinkPossible;
|
||||||
|
private final KeycloakSession session;
|
||||||
|
|
||||||
public AccountSocialBean(RealmModel realm, UserModel user, URI baseUri) {
|
public AccountSocialBean(KeycloakSession session, RealmModel realm, UserModel user, URI baseUri) {
|
||||||
|
this.session = session;
|
||||||
URI accountSocialUpdateUri = Urls.accountSocialUpdate(baseUri, realm.getName());
|
URI accountSocialUpdateUri = Urls.accountSocialUpdate(baseUri, realm.getName());
|
||||||
this.socialLinks = new LinkedList<SocialLinkEntry>();
|
this.socialLinks = new LinkedList<SocialLinkEntry>();
|
||||||
|
|
||||||
Map<String, String> socialConfig = realm.getSocialConfig();
|
Map<String, String> socialConfig = realm.getSocialConfig();
|
||||||
Set<SocialLinkModel> userSocialLinks = realm.getSocialLinks(user);
|
Set<SocialLinkModel> userSocialLinks = session.users().getSocialLinks(user, realm);
|
||||||
|
|
||||||
int availableLinks = 0;
|
int availableLinks = 0;
|
||||||
if (socialConfig != null && !socialConfig.isEmpty()) {
|
if (socialConfig != null && !socialConfig.isEmpty()) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,8 +2,6 @@ package org.keycloak.models;
|
||||||
|
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +27,7 @@ public interface KeycloakSession {
|
||||||
* @return
|
* @return
|
||||||
* @throws IllegalStateException if transaction is not active
|
* @throws IllegalStateException if transaction is not active
|
||||||
*/
|
*/
|
||||||
ModelProvider model();
|
RealmProvider realms();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a managed provider instance. Will start a provider transaction. This transaction is managed by the KeycloakSession
|
* Returns a managed provider instance. Will start a provider transaction. This transaction is managed by the KeycloakSession
|
||||||
|
@ -42,4 +40,5 @@ public interface KeycloakSession {
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
UserProvider users();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package org.keycloak.models;
|
|
||||||
|
|
||||||
import org.keycloak.provider.Provider;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public interface ModelProvider extends Provider {
|
|
||||||
// Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
|
|
||||||
|
|
||||||
RealmModel createRealm(String name);
|
|
||||||
RealmModel createRealm(String id, String name);
|
|
||||||
RealmModel getRealm(String id);
|
|
||||||
RealmModel getRealmByName(String name);
|
|
||||||
|
|
||||||
UserModel getUserById(String id, RealmModel realm);
|
|
||||||
UserModel getUserByUsername(String username, RealmModel realm);
|
|
||||||
UserModel getUserByEmail(String email, RealmModel realm);
|
|
||||||
UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm);
|
|
||||||
List<UserModel> getUsers(RealmModel realm);
|
|
||||||
List<UserModel> searchForUser(String search, RealmModel realm);
|
|
||||||
List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm);
|
|
||||||
|
|
||||||
Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm);
|
|
||||||
SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm);
|
|
||||||
|
|
||||||
RoleModel getRoleById(String id, RealmModel realm);
|
|
||||||
ApplicationModel getApplicationById(String id, RealmModel realm);
|
|
||||||
OAuthClientModel getOAuthClientById(String id, RealmModel realm);
|
|
||||||
List<RealmModel> getRealms();
|
|
||||||
boolean removeRealm(String id);
|
|
||||||
|
|
||||||
void close();
|
|
||||||
}
|
|
|
@ -110,18 +110,6 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
|
|
||||||
boolean validateTOTP(UserModel user, String password, String token);
|
boolean validateTOTP(UserModel user, String password, String token);
|
||||||
|
|
||||||
UserModel getUser(String name);
|
|
||||||
|
|
||||||
UserModel getUserByEmail(String email);
|
|
||||||
|
|
||||||
UserModel getUserById(String name);
|
|
||||||
|
|
||||||
UserModel addUser(String id, String username, boolean addDefaultRoles);
|
|
||||||
|
|
||||||
UserModel addUser(String username);
|
|
||||||
|
|
||||||
boolean removeUser(String name);
|
|
||||||
|
|
||||||
RoleModel getRoleById(String id);
|
RoleModel getRoleById(String id);
|
||||||
|
|
||||||
List<String> getDefaultRoles();
|
List<String> getDefaultRoles();
|
||||||
|
@ -147,16 +135,6 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
|
|
||||||
void updateRequiredCredentials(Set<String> creds);
|
void updateRequiredCredentials(Set<String> creds);
|
||||||
|
|
||||||
UserModel getUserBySocialLink(SocialLinkModel socialLink);
|
|
||||||
|
|
||||||
Set<SocialLinkModel> getSocialLinks(UserModel user);
|
|
||||||
|
|
||||||
SocialLinkModel getSocialLink(UserModel user, String socialProvider);
|
|
||||||
|
|
||||||
void addSocialLink(UserModel user, SocialLinkModel socialLink);
|
|
||||||
|
|
||||||
boolean removeSocialLink(UserModel user, String socialProvider);
|
|
||||||
|
|
||||||
boolean isSocial();
|
boolean isSocial();
|
||||||
|
|
||||||
void setSocial(boolean social);
|
void setSocial(boolean social);
|
||||||
|
@ -165,12 +143,6 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
|
|
||||||
void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin);
|
void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin);
|
||||||
|
|
||||||
List<UserModel> getUsers();
|
|
||||||
|
|
||||||
List<UserModel> searchForUser(String search);
|
|
||||||
|
|
||||||
List<UserModel> searchForUserByAttributes(Map<String, String> attributes);
|
|
||||||
|
|
||||||
OAuthClientModel addOAuthClient(String name);
|
OAuthClientModel addOAuthClient(String name);
|
||||||
|
|
||||||
OAuthClientModel addOAuthClient(String id, String name);
|
OAuthClientModel addOAuthClient(String id, String name);
|
||||||
|
|
26
model/api/src/main/java/org/keycloak/models/RealmProvider.java
Executable file
26
model/api/src/main/java/org/keycloak/models/RealmProvider.java
Executable file
|
@ -0,0 +1,26 @@
|
||||||
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import org.keycloak.provider.Provider;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public interface RealmProvider extends Provider {
|
||||||
|
// Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
|
||||||
|
|
||||||
|
RealmModel createRealm(String name);
|
||||||
|
RealmModel createRealm(String id, String name);
|
||||||
|
RealmModel getRealm(String id);
|
||||||
|
RealmModel getRealmByName(String name);
|
||||||
|
|
||||||
|
RoleModel getRoleById(String id, RealmModel realm);
|
||||||
|
ApplicationModel getApplicationById(String id, RealmModel realm);
|
||||||
|
OAuthClientModel getOAuthClientById(String id, RealmModel realm);
|
||||||
|
List<RealmModel> getRealms();
|
||||||
|
boolean removeRealm(String id);
|
||||||
|
|
||||||
|
void close();
|
||||||
|
}
|
|
@ -6,5 +6,5 @@ import org.keycloak.provider.ProviderFactory;
|
||||||
* @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 interface ModelProviderFactory extends ProviderFactory<ModelProvider> {
|
public interface RealmProviderFactory extends ProviderFactory<RealmProvider> {
|
||||||
}
|
}
|
8
model/api/src/main/java/org/keycloak/models/ModelSpi.java → model/api/src/main/java/org/keycloak/models/RealmSpi.java
Normal file → Executable file
8
model/api/src/main/java/org/keycloak/models/ModelSpi.java → model/api/src/main/java/org/keycloak/models/RealmSpi.java
Normal file → Executable file
|
@ -7,21 +7,21 @@ import org.keycloak.provider.Spi;
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public class ModelSpi implements Spi {
|
public class RealmSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "model";
|
return "realm";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends Provider> getProviderClass() {
|
public Class<? extends Provider> getProviderClass() {
|
||||||
return ModelProvider.class;
|
return RealmProvider.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||||
return ModelProviderFactory.class;
|
return RealmProviderFactory.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 $
|
||||||
|
|
|
@ -13,12 +13,13 @@ import java.util.Set;
|
||||||
public interface UserProvider extends Provider {
|
public interface UserProvider extends Provider {
|
||||||
// Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
|
// Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
|
||||||
|
|
||||||
KeycloakTransaction getTransaction();
|
|
||||||
|
|
||||||
UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles);
|
UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles);
|
||||||
UserModel addUser(RealmModel realm, String username);
|
UserModel addUser(RealmModel realm, String username);
|
||||||
boolean removeUser(RealmModel realm, String name);
|
boolean removeUser(RealmModel realm, String name);
|
||||||
|
|
||||||
|
public void addSocialLink(RealmModel realm, UserModel user, SocialLinkModel socialLink);
|
||||||
|
public boolean removeSocialLink(RealmModel realm, UserModel user, String socialProvider);
|
||||||
|
|
||||||
UserModel getUserById(String id, RealmModel realm);
|
UserModel getUserById(String id, RealmModel realm);
|
||||||
UserModel getUserByUsername(String username, RealmModel realm);
|
UserModel getUserByUsername(String username, RealmModel realm);
|
||||||
UserModel getUserByEmail(String email, RealmModel realm);
|
UserModel getUserByEmail(String email, RealmModel realm);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
|
|
@ -3,8 +3,6 @@ package org.keycloak.models;
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
|
27
model/api/src/main/java/org/keycloak/models/UserSpi.java
Executable file
27
model/api/src/main/java/org/keycloak/models/UserSpi.java
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import org.keycloak.provider.Provider;
|
||||||
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
import org.keycloak.provider.Spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
public class UserSpi implements Spi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "user";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Provider> getProviderClass() {
|
||||||
|
return UserProvider.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||||
|
return UserProviderFactory.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
4
model/api/src/main/java/org/keycloak/models/entities/UserEntity.java
Normal file → Executable file
4
model/api/src/main/java/org/keycloak/models/entities/UserEntity.java
Normal file → Executable file
|
@ -1,11 +1,11 @@
|
||||||
package org.keycloak.models.entities;
|
package org.keycloak.models.entities;
|
||||||
|
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
|
|
26
model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
Normal file → Executable file
26
model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
Normal file → Executable file
|
@ -1,5 +1,15 @@
|
||||||
package org.keycloak.models.utils;
|
package org.keycloak.models.utils;
|
||||||
|
|
||||||
|
import org.bouncycastle.openssl.PEMWriter;
|
||||||
|
import org.keycloak.models.ApplicationModel;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.UserCredentialModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.util.PemUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
|
@ -10,16 +20,6 @@ import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
|
|
||||||
import org.bouncycastle.openssl.PEMWriter;
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.RoleModel;
|
|
||||||
import org.keycloak.models.UserCredentialModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.util.PemUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of helper methods, which are useful in various model implementations.
|
* Set of helper methods, which are useful in various model implementations.
|
||||||
|
@ -122,10 +122,10 @@ public final class KeycloakModelUtils {
|
||||||
* @param username username or email of user
|
* @param username username or email of user
|
||||||
* @return found user
|
* @return found user
|
||||||
*/
|
*/
|
||||||
public static UserModel findUserByNameOrEmail(RealmModel realm, String username) {
|
public static UserModel findUserByNameOrEmail(KeycloakSession session, RealmModel realm, String username) {
|
||||||
UserModel user = realm.getUser(username);
|
UserModel user = session.users().getUserByUsername(username, realm);
|
||||||
if (user == null && username.contains("@")) {
|
if (user == null && username.contains("@")) {
|
||||||
user = realm.getUserByEmail(username);
|
user = session.users().getUserByEmail(username, realm);
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
31
model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
Normal file → Executable file
31
model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
Normal file → Executable file
|
@ -1,15 +1,5 @@
|
||||||
package org.keycloak.models.utils;
|
package org.keycloak.models.utils;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import net.iharder.Base64;
|
import net.iharder.Base64;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
|
@ -17,6 +7,7 @@ import org.keycloak.models.AuthenticationLinkModel;
|
||||||
import org.keycloak.models.AuthenticationProviderModel;
|
import org.keycloak.models.AuthenticationProviderModel;
|
||||||
import org.keycloak.models.ClaimMask;
|
import org.keycloak.models.ClaimMask;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
@ -37,11 +28,21 @@ import org.keycloak.representations.idm.ScopeMappingRepresentation;
|
||||||
import org.keycloak.representations.idm.SocialLinkRepresentation;
|
import org.keycloak.representations.idm.SocialLinkRepresentation;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class RepresentationToModel {
|
public class RepresentationToModel {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(RepresentationToModel.class);
|
private static Logger logger = Logger.getLogger(RepresentationToModel.class);
|
||||||
|
|
||||||
public static void importRealm(RealmRepresentation rep, RealmModel newRealm) {
|
public static void importRealm(KeycloakSession session, RealmRepresentation rep, RealmModel newRealm) {
|
||||||
newRealm.setName(rep.getRealm());
|
newRealm.setName(rep.getRealm());
|
||||||
if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled());
|
if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled());
|
||||||
if (rep.isSocial() != null) newRealm.setSocial(rep.isSocial());
|
if (rep.isSocial() != null) newRealm.setSocial(rep.isSocial());
|
||||||
|
@ -210,7 +211,7 @@ public class RepresentationToModel {
|
||||||
|
|
||||||
if (rep.getUsers() != null) {
|
if (rep.getUsers() != null) {
|
||||||
for (UserRepresentation userRep : rep.getUsers()) {
|
for (UserRepresentation userRep : rep.getUsers()) {
|
||||||
UserModel user = createUser(newRealm, userRep, appMap);
|
UserModel user = createUser(session, newRealm, userRep, appMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -571,8 +572,8 @@ public class RepresentationToModel {
|
||||||
|
|
||||||
// Users
|
// Users
|
||||||
|
|
||||||
public static UserModel createUser(RealmModel newRealm, UserRepresentation userRep, Map<String, ApplicationModel> appMap) {
|
public static UserModel createUser(KeycloakSession session, RealmModel newRealm, UserRepresentation userRep, Map<String, ApplicationModel> appMap) {
|
||||||
UserModel user = newRealm.addUser(userRep.getId(), userRep.getUsername(), false);
|
UserModel user = session.users().addUser(newRealm, userRep.getId(), userRep.getUsername(), false);
|
||||||
user.setEnabled(userRep.isEnabled());
|
user.setEnabled(userRep.isEnabled());
|
||||||
user.setEmail(userRep.getEmail());
|
user.setEmail(userRep.getEmail());
|
||||||
user.setFirstName(userRep.getFirstName());
|
user.setFirstName(userRep.getFirstName());
|
||||||
|
@ -600,7 +601,7 @@ public class RepresentationToModel {
|
||||||
if (userRep.getSocialLinks() != null) {
|
if (userRep.getSocialLinks() != null) {
|
||||||
for (SocialLinkRepresentation socialLink : userRep.getSocialLinks()) {
|
for (SocialLinkRepresentation socialLink : userRep.getSocialLinks()) {
|
||||||
SocialLinkModel mappingModel = new SocialLinkModel(socialLink.getSocialProvider(), socialLink.getSocialUserId(), socialLink.getSocialUsername());
|
SocialLinkModel mappingModel = new SocialLinkModel(socialLink.getSocialProvider(), socialLink.getSocialUserId(), socialLink.getSocialUsername());
|
||||||
newRealm.addSocialLink(user, mappingModel);
|
session.users().addSocialLink(newRealm, user, mappingModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (userRep.getRealmRoles() != null) {
|
if (userRep.getRealmRoles() != null) {
|
||||||
|
|
2
model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java
Normal file → Executable file
2
model/api/src/main/java/org/keycloak/models/utils/reflection/Properties.java
Normal file → Executable file
|
@ -1,7 +1,5 @@
|
||||||
package org.keycloak.models.utils.reflection;
|
package org.keycloak.models.utils.reflection;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Member;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
1
model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java
Normal file → Executable file
1
model/api/src/main/java/org/keycloak/models/utils/reflection/PropertyCriteria.java
Normal file → Executable file
|
@ -1,6 +1,5 @@
|
||||||
package org.keycloak.models.utils.reflection;
|
package org.keycloak.models.utils.reflection;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
3
model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
Normal file → Executable file
3
model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
Normal file → Executable file
|
@ -1,2 +1,3 @@
|
||||||
org.keycloak.models.ModelSpi
|
org.keycloak.models.RealmSpi
|
||||||
org.keycloak.models.UserSessionSpi
|
org.keycloak.models.UserSessionSpi
|
||||||
|
org.keycloak.models.UserSpi
|
5
model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java
Normal file → Executable file
5
model/hybrid/src/main/java/org/keycloak/models/hybrid/ApplicationAdapter.java
Normal file → Executable file
|
@ -1,15 +1,12 @@
|
||||||
package org.keycloak.models.hybrid;
|
package org.keycloak.models.hybrid;
|
||||||
|
|
||||||
import org.keycloak.models.realms.Application;
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.realms.Application;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
1
model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
Normal file → Executable file
1
model/hybrid/src/main/java/org/keycloak/models/hybrid/ClientAdapter.java
Normal file → Executable file
|
@ -3,7 +3,6 @@ package org.keycloak.models.hybrid;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.realms.Client;
|
import org.keycloak.models.realms.Client;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
3
model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
Normal file → Executable file
3
model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProvider.java
Normal file → Executable file
|
@ -1,7 +1,6 @@
|
||||||
package org.keycloak.models.hybrid;
|
package org.keycloak.models.hybrid;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakTransaction;
|
import org.keycloak.models.KeycloakTransaction;
|
||||||
import org.keycloak.models.ModelProvider;
|
import org.keycloak.models.ModelProvider;
|
||||||
|
@ -10,13 +9,11 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.SocialLinkModel;
|
import org.keycloak.models.SocialLinkModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.UsernameLoginFailureModel;
|
import org.keycloak.models.UsernameLoginFailureModel;
|
||||||
import org.keycloak.models.realms.RealmProvider;
|
import org.keycloak.models.realms.RealmProvider;
|
||||||
import org.keycloak.models.sessions.SessionProvider;
|
import org.keycloak.models.sessions.SessionProvider;
|
||||||
import org.keycloak.models.users.UserProvider;
|
import org.keycloak.models.users.UserProvider;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.util.Time;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
3
model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java
Normal file → Executable file
3
model/hybrid/src/main/java/org/keycloak/models/hybrid/HybridModelProviderFactory.java
Normal file → Executable file
|
@ -1,12 +1,9 @@
|
||||||
package org.keycloak.models.hybrid;
|
package org.keycloak.models.hybrid;
|
||||||
|
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.models.realms.RealmProvider;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelProvider;
|
import org.keycloak.models.ModelProvider;
|
||||||
import org.keycloak.models.ModelProviderFactory;
|
import org.keycloak.models.ModelProviderFactory;
|
||||||
import org.keycloak.models.sessions.SessionProvider;
|
|
||||||
import org.keycloak.models.users.UserProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
|
13
model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
Normal file → Executable file
13
model/hybrid/src/main/java/org/keycloak/models/hybrid/RealmAdapter.java
Normal file → Executable file
|
@ -1,11 +1,5 @@
|
||||||
package org.keycloak.models.hybrid;
|
package org.keycloak.models.hybrid;
|
||||||
|
|
||||||
import org.keycloak.models.UserCredentialModel;
|
|
||||||
import org.keycloak.models.UserCredentialValueModel;
|
|
||||||
import org.keycloak.models.realms.Application;
|
|
||||||
import org.keycloak.models.realms.Client;
|
|
||||||
import org.keycloak.models.realms.OAuthClient;
|
|
||||||
import org.keycloak.models.realms.Realm;
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.AuthenticationProviderModel;
|
import org.keycloak.models.AuthenticationProviderModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
|
@ -15,9 +9,14 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.SocialLinkModel;
|
import org.keycloak.models.SocialLinkModel;
|
||||||
|
import org.keycloak.models.UserCredentialModel;
|
||||||
|
import org.keycloak.models.UserCredentialValueModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.UsernameLoginFailureModel;
|
import org.keycloak.models.UsernameLoginFailureModel;
|
||||||
|
import org.keycloak.models.realms.Application;
|
||||||
|
import org.keycloak.models.realms.Client;
|
||||||
|
import org.keycloak.models.realms.OAuthClient;
|
||||||
|
import org.keycloak.models.realms.Realm;
|
||||||
import org.keycloak.models.users.Credentials;
|
import org.keycloak.models.users.Credentials;
|
||||||
import org.keycloak.models.users.Feature;
|
import org.keycloak.models.users.Feature;
|
||||||
import org.keycloak.models.users.User;
|
import org.keycloak.models.users.User;
|
||||||
|
|
4
model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java
Normal file → Executable file
4
model/hybrid/src/main/java/org/keycloak/models/hybrid/RoleAdapter.java
Normal file → Executable file
|
@ -1,10 +1,10 @@
|
||||||
package org.keycloak.models.hybrid;
|
package org.keycloak.models.hybrid;
|
||||||
|
|
||||||
|
import org.keycloak.models.RoleContainerModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.realms.Application;
|
import org.keycloak.models.realms.Application;
|
||||||
import org.keycloak.models.realms.Realm;
|
import org.keycloak.models.realms.Realm;
|
||||||
import org.keycloak.models.realms.Role;
|
import org.keycloak.models.realms.Role;
|
||||||
import org.keycloak.models.RoleContainerModel;
|
|
||||||
import org.keycloak.models.RoleModel;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
3
model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java
Normal file → Executable file
3
model/hybrid/src/main/java/org/keycloak/models/hybrid/UsernameLoginFailureAdapter.java
Normal file → Executable file
|
@ -3,9 +3,6 @@ package org.keycloak.models.hybrid;
|
||||||
import org.keycloak.models.UsernameLoginFailureModel;
|
import org.keycloak.models.UsernameLoginFailureModel;
|
||||||
import org.keycloak.models.sessions.LoginFailure;
|
import org.keycloak.models.sessions.LoginFailure;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
|
||||||
protected ApplicationModel updated;
|
protected ApplicationModel updated;
|
||||||
protected CachedApplication cached;
|
protected CachedApplication cached;
|
||||||
|
|
||||||
public ApplicationAdapter(RealmModel cachedRealm, CachedApplication cached, CacheModelProvider cacheSession, KeycloakCache cache) {
|
public ApplicationAdapter(RealmModel cachedRealm, CachedApplication cached, CacheRealmProvider cacheSession, RealmCache cache) {
|
||||||
super(cachedRealm, cached, cache, cacheSession);
|
super(cachedRealm, cached, cache, cacheSession);
|
||||||
this.cached = cached;
|
this.cached = cached;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package org.keycloak.models.cache;
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
import org.keycloak.models.ModelProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 interface CacheModelProvider extends ModelProvider {
|
public interface CacheRealmProvider extends RealmProvider {
|
||||||
ModelProvider getDelegate();
|
RealmProvider getDelegate();
|
||||||
|
|
||||||
void registerRealmInvalidation(String id);
|
void registerRealmInvalidation(String id);
|
||||||
|
|
|
@ -6,6 +6,6 @@ import org.keycloak.provider.ProviderFactory;
|
||||||
* @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 interface CacheModelProviderFactory extends ProviderFactory<CacheModelProvider> {
|
public interface CacheRealmProviderFactory extends ProviderFactory<CacheRealmProvider> {
|
||||||
|
|
||||||
}
|
}
|
|
@ -8,20 +8,20 @@ import org.keycloak.provider.Spi;
|
||||||
* @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 CacheModelProviderSpi implements Spi {
|
public class CacheRealmProviderSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "modelCache";
|
return "realmCache";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends Provider> getProviderClass() {
|
public Class<? extends Provider> getProviderClass() {
|
||||||
return CacheModelProvider.class;
|
return CacheRealmProvider.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||||
return CacheModelProviderFactory.class;
|
return CacheRealmProviderFactory.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
14
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProvider.java
vendored
Executable file
14
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProvider.java
vendored
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public interface CacheUserProvider extends UserProvider {
|
||||||
|
UserProvider getDelegate();
|
||||||
|
|
||||||
|
void registerUserInvalidation(RealmModel realm, String id);
|
||||||
|
}
|
11
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderFactory.java
vendored
Executable file
11
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderFactory.java
vendored
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public interface CacheUserProviderFactory extends ProviderFactory<CacheUserProvider> {
|
||||||
|
|
||||||
|
}
|
27
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java
vendored
Executable file
27
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheUserProviderSpi.java
vendored
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.provider.Provider;
|
||||||
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
import org.keycloak.provider.Spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class CacheUserProviderSpi implements Spi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "userCache";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Provider> getProviderClass() {
|
||||||
|
return CacheUserProvider.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||||
|
return CacheUserProviderFactory.class;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleContainerModel;
|
import org.keycloak.models.RoleContainerModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.cache.entities.CachedClient;
|
import org.keycloak.models.cache.entities.CachedClient;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -16,12 +15,12 @@ import java.util.Set;
|
||||||
*/
|
*/
|
||||||
public abstract class ClientAdapter implements ClientModel {
|
public abstract class ClientAdapter implements ClientModel {
|
||||||
protected CachedClient cachedClient;
|
protected CachedClient cachedClient;
|
||||||
protected CacheModelProvider cacheSession;
|
protected CacheRealmProvider cacheSession;
|
||||||
protected ClientModel updatedClient;
|
protected ClientModel updatedClient;
|
||||||
protected RealmModel cachedRealm;
|
protected RealmModel cachedRealm;
|
||||||
protected KeycloakCache cache;
|
protected RealmCache cache;
|
||||||
|
|
||||||
public ClientAdapter(RealmModel cachedRealm, CachedClient cached, KeycloakCache cache, CacheModelProvider cacheSession) {
|
public ClientAdapter(RealmModel cachedRealm, CachedClient cached, RealmCache cache, CacheRealmProvider cacheSession) {
|
||||||
this.cachedRealm = cachedRealm;
|
this.cachedRealm = cachedRealm;
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
this.cacheSession = cacheSession;
|
this.cacheSession = cacheSession;
|
||||||
|
|
|
@ -1,24 +1,19 @@
|
||||||
package org.keycloak.models.cache;
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakTransaction;
|
import org.keycloak.models.KeycloakTransaction;
|
||||||
import org.keycloak.models.ModelProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.SocialLinkModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.UsernameLoginFailureModel;
|
|
||||||
import org.keycloak.models.cache.entities.CachedApplication;
|
import org.keycloak.models.cache.entities.CachedApplication;
|
||||||
import org.keycloak.models.cache.entities.CachedApplicationRole;
|
import org.keycloak.models.cache.entities.CachedApplicationRole;
|
||||||
import org.keycloak.models.cache.entities.CachedOAuthClient;
|
import org.keycloak.models.cache.entities.CachedOAuthClient;
|
||||||
import org.keycloak.models.cache.entities.CachedRealm;
|
import org.keycloak.models.cache.entities.CachedRealm;
|
||||||
import org.keycloak.models.cache.entities.CachedRealmRole;
|
import org.keycloak.models.cache.entities.CachedRealmRole;
|
||||||
import org.keycloak.models.cache.entities.CachedRole;
|
import org.keycloak.models.cache.entities.CachedRole;
|
||||||
import org.keycloak.models.cache.entities.CachedUser;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -30,10 +25,10 @@ import java.util.Set;
|
||||||
* @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 DefaultCacheModelProvider implements CacheModelProvider {
|
public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
protected KeycloakCache cache;
|
protected RealmCache cache;
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
protected ModelProvider delegate;
|
protected RealmProvider delegate;
|
||||||
protected boolean transactionActive;
|
protected boolean transactionActive;
|
||||||
protected boolean setRollbackOnly;
|
protected boolean setRollbackOnly;
|
||||||
|
|
||||||
|
@ -50,7 +45,7 @@ public class DefaultCacheModelProvider implements CacheModelProvider {
|
||||||
|
|
||||||
protected boolean clearAll;
|
protected boolean clearAll;
|
||||||
|
|
||||||
public DefaultCacheModelProvider(KeycloakCache cache, KeycloakSession session) {
|
public DefaultCacheRealmProvider(RealmCache cache, KeycloakSession session) {
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
|
||||||
|
@ -58,10 +53,10 @@ public class DefaultCacheModelProvider implements CacheModelProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelProvider getDelegate() {
|
public RealmProvider getDelegate() {
|
||||||
if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
|
if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
|
||||||
if (delegate != null) return delegate;
|
if (delegate != null) return delegate;
|
||||||
delegate = session.getProvider(ModelProvider.class);
|
delegate = session.getProvider(RealmProvider.class);
|
||||||
return delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,10 +98,6 @@ public class DefaultCacheModelProvider implements CacheModelProvider {
|
||||||
for (String id : clientInvalidations) {
|
for (String id : clientInvalidations) {
|
||||||
cache.invalidateCachedOAuthClientById(id);
|
cache.invalidateCachedOAuthClientById(id);
|
||||||
}
|
}
|
||||||
for (String id : userInvalidations) {
|
|
||||||
cache.invalidateCachedUserById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeycloakTransaction getTransaction() {
|
private KeycloakTransaction getTransaction() {
|
||||||
|
@ -200,63 +191,6 @@ public class DefaultCacheModelProvider implements CacheModelProvider {
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
|
||||||
CachedUser cached = cache.getCachedUser(id);
|
|
||||||
if (cached == null) {
|
|
||||||
UserModel model = getDelegate().getUserById(id, realm);
|
|
||||||
if (model == null) return null;
|
|
||||||
if (userInvalidations.contains(id)) return model;
|
|
||||||
cached = new CachedUser(realm, model);
|
|
||||||
cache.addCachedUser(cached);
|
|
||||||
} else if (userInvalidations.contains(id)) {
|
|
||||||
return getDelegate().getUserById(id, realm);
|
|
||||||
} else if (managedUsers.containsKey(id)) {
|
|
||||||
return managedUsers.get(id);
|
|
||||||
}
|
|
||||||
UserAdapter adapter = new UserAdapter(cached, cache, this, realm);
|
|
||||||
managedUsers.put(id, adapter);
|
|
||||||
return adapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
|
||||||
CachedUser cached = cache.getCachedUserByUsername(username, realm);
|
|
||||||
if (cached == null) {
|
|
||||||
UserModel model = getDelegate().getUserByUsername(username, realm);
|
|
||||||
if (model == null) return null;
|
|
||||||
if (userInvalidations.contains(model.getId())) return model;
|
|
||||||
cached = new CachedUser(realm, model);
|
|
||||||
cache.addCachedUser(cached);
|
|
||||||
} else if (userInvalidations.contains(cached.getId())) {
|
|
||||||
return getDelegate().getUserById(cached.getId(), realm);
|
|
||||||
} else if (managedUsers.containsKey(cached.getId())) {
|
|
||||||
return managedUsers.get(cached.getId());
|
|
||||||
}
|
|
||||||
UserAdapter adapter = new UserAdapter(cached, cache, this, realm);
|
|
||||||
managedUsers.put(cached.getId(), adapter);
|
|
||||||
return adapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
|
||||||
CachedUser cached = cache.getCachedUserByEmail(email, realm);
|
|
||||||
if (cached == null) {
|
|
||||||
UserModel model = getDelegate().getUserByEmail(email, realm);
|
|
||||||
if (model == null) return null;
|
|
||||||
if (userInvalidations.contains(model.getId())) return model;
|
|
||||||
cached = new CachedUser(realm, model);
|
|
||||||
cache.addCachedUser(cached);
|
|
||||||
} else if (userInvalidations.contains(cached.getId())) {
|
|
||||||
return getDelegate().getUserByEmail(email, realm);
|
|
||||||
} else if (managedUsers.containsKey(cached.getId())) {
|
|
||||||
return managedUsers.get(cached.getId());
|
|
||||||
}
|
|
||||||
UserAdapter adapter = new UserAdapter(cached, cache, this, realm);
|
|
||||||
managedUsers.put(cached.getId(), adapter);
|
|
||||||
return adapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RealmModel> getRealms() {
|
public List<RealmModel> getRealms() {
|
||||||
// we don't cache this for now
|
// we don't cache this for now
|
||||||
|
@ -291,36 +225,6 @@ public class DefaultCacheModelProvider implements CacheModelProvider {
|
||||||
if (delegate != null) delegate.close();
|
if (delegate != null) delegate.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
|
|
||||||
return getDelegate().getUserBySocialLink(socialLink, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> getUsers(RealmModel realm) {
|
|
||||||
return getDelegate().getUsers(realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUser(String search, RealmModel realm) {
|
|
||||||
return getDelegate().searchForUser(search, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
|
|
||||||
return getDelegate().searchForUserByAttributes(attributes, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
|
|
||||||
return getDelegate().getSocialLinks(user, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm) {
|
|
||||||
return getDelegate().getSocialLink(user, socialProvider, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RoleModel getRoleById(String id, RealmModel realm) {
|
public RoleModel getRoleById(String id, RealmModel realm) {
|
||||||
CachedRole cached = cache.getRole(id);
|
CachedRole cached = cache.getRole(id);
|
244
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
vendored
Executable file
244
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheUserProvider.java
vendored
Executable file
|
@ -0,0 +1,244 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakTransaction;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.SocialLinkModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.UserProvider;
|
||||||
|
import org.keycloak.models.cache.entities.CachedUser;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class DefaultCacheUserProvider implements CacheUserProvider {
|
||||||
|
protected UserCache cache;
|
||||||
|
protected KeycloakSession session;
|
||||||
|
protected UserProvider delegate;
|
||||||
|
protected boolean transactionActive;
|
||||||
|
protected boolean setRollbackOnly;
|
||||||
|
|
||||||
|
protected Map<String, String> userInvalidations = new HashMap<String, String>();
|
||||||
|
protected Set<String> realmInvalidations = new HashSet<String>();
|
||||||
|
protected Map<String, UserModel> managedUsers = new HashMap<String, UserModel>();
|
||||||
|
|
||||||
|
protected boolean clearAll;
|
||||||
|
|
||||||
|
public DefaultCacheUserProvider(UserCache cache, KeycloakSession session) {
|
||||||
|
this.cache = cache;
|
||||||
|
this.session = session;
|
||||||
|
|
||||||
|
session.getTransaction().enlistAfterCompletion(getTransaction());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProvider getDelegate() {
|
||||||
|
if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
|
||||||
|
if (delegate != null) return delegate;
|
||||||
|
delegate = session.getProvider(UserProvider.class);
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerUserInvalidation(RealmModel realm, String id) {
|
||||||
|
userInvalidations.put(id, realm.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void runInvalidations() {
|
||||||
|
for (Map.Entry<String, String> invalidation : userInvalidations.entrySet()) {
|
||||||
|
cache.invalidateCachedUserById(invalidation.getValue(), invalidation.getKey());
|
||||||
|
}
|
||||||
|
for (String realmId : realmInvalidations) {
|
||||||
|
cache.invalidateRealmUsers(realmId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeycloakTransaction getTransaction() {
|
||||||
|
return new KeycloakTransaction() {
|
||||||
|
@Override
|
||||||
|
public void begin() {
|
||||||
|
transactionActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commit() {
|
||||||
|
if (delegate == null) return;
|
||||||
|
if (clearAll) {
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
runInvalidations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rollback() {
|
||||||
|
setRollbackOnly = true;
|
||||||
|
runInvalidations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRollbackOnly() {
|
||||||
|
setRollbackOnly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getRollbackOnly() {
|
||||||
|
return setRollbackOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive() {
|
||||||
|
return transactionActive;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel getUserById(String id, RealmModel realm) {
|
||||||
|
if (realmInvalidations.contains(realm.getId())) {
|
||||||
|
return getDelegate().getUserById(id, realm);
|
||||||
|
}
|
||||||
|
if (userInvalidations.containsKey(id)) {
|
||||||
|
return getDelegate().getUserById(id, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
CachedUser cached = cache.getCachedUser(realm.getId(), id);
|
||||||
|
if (cached == null) {
|
||||||
|
UserModel model = getDelegate().getUserById(id, realm);
|
||||||
|
if (model == null) return null;
|
||||||
|
if (userInvalidations.containsKey(id)) return model;
|
||||||
|
cached = new CachedUser(realm, model);
|
||||||
|
cache.addCachedUser(realm.getId(), cached);
|
||||||
|
} else if (managedUsers.containsKey(id)) {
|
||||||
|
return managedUsers.get(id);
|
||||||
|
}
|
||||||
|
UserAdapter adapter = new UserAdapter(cached, this, session, realm);
|
||||||
|
managedUsers.put(id, adapter);
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel getUserByUsername(String username, RealmModel realm) {
|
||||||
|
if (realmInvalidations.contains(realm.getId())) {
|
||||||
|
return getDelegate().getUserByUsername(username, realm);
|
||||||
|
}
|
||||||
|
CachedUser cached = cache.getCachedUserByUsername(realm.getId(), username);
|
||||||
|
if (cached == null) {
|
||||||
|
UserModel model = getDelegate().getUserByUsername(username, realm);
|
||||||
|
if (model == null) return null;
|
||||||
|
if (userInvalidations.containsKey(model.getId())) return model;
|
||||||
|
cached = new CachedUser(realm, model);
|
||||||
|
cache.addCachedUser(realm.getId(), cached);
|
||||||
|
} else if (userInvalidations.containsKey(cached.getId())) {
|
||||||
|
return getDelegate().getUserById(cached.getId(), realm);
|
||||||
|
} else if (managedUsers.containsKey(cached.getId())) {
|
||||||
|
return managedUsers.get(cached.getId());
|
||||||
|
}
|
||||||
|
UserAdapter adapter = new UserAdapter(cached, this, session, realm);
|
||||||
|
managedUsers.put(cached.getId(), adapter);
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel getUserByEmail(String email, RealmModel realm) {
|
||||||
|
if (realmInvalidations.contains(realm.getId())) {
|
||||||
|
return getDelegate().getUserByEmail(email, realm);
|
||||||
|
}
|
||||||
|
CachedUser cached = cache.getCachedUserByEmail(realm.getId(), email);
|
||||||
|
if (cached == null) {
|
||||||
|
UserModel model = getDelegate().getUserByEmail(email, realm);
|
||||||
|
if (model == null) return null;
|
||||||
|
if (userInvalidations.containsKey(model.getId())) return model;
|
||||||
|
cached = new CachedUser(realm, model);
|
||||||
|
cache.addCachedUser(realm.getId(), cached);
|
||||||
|
} else if (userInvalidations.containsKey(cached.getId())) {
|
||||||
|
return getDelegate().getUserByEmail(email, realm);
|
||||||
|
} else if (managedUsers.containsKey(cached.getId())) {
|
||||||
|
return managedUsers.get(cached.getId());
|
||||||
|
}
|
||||||
|
UserAdapter adapter = new UserAdapter(cached, this, session, realm);
|
||||||
|
managedUsers.put(cached.getId(), adapter);
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (delegate != null) delegate.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
|
||||||
|
return getDelegate().getUserBySocialLink(socialLink, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserModel> getUsers(RealmModel realm) {
|
||||||
|
return getDelegate().getUsers(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserModel> searchForUser(String search, RealmModel realm) {
|
||||||
|
return getDelegate().searchForUser(search, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
|
||||||
|
return getDelegate().searchForUserByAttributes(attributes, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
|
||||||
|
return getDelegate().getSocialLinks(user, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm) {
|
||||||
|
return getDelegate().getSocialLink(user, socialProvider, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles) {
|
||||||
|
return getDelegate().addUser(realm, id, username, addDefaultRoles);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel addUser(RealmModel realm, String username) {
|
||||||
|
return getDelegate().addUser(realm, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeUser(RealmModel realm, String name) {
|
||||||
|
UserModel user = getUserByUsername(name, realm);
|
||||||
|
if (user == null) return false;
|
||||||
|
registerUserInvalidation(realm, user.getId());
|
||||||
|
return getDelegate().removeUser(realm, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addSocialLink(RealmModel realm, UserModel user, SocialLinkModel socialLink) {
|
||||||
|
getDelegate().addSocialLink(realm, user, socialLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeSocialLink(RealmModel realm, UserModel user, String socialProvider) {
|
||||||
|
return getDelegate().removeSocialLink(realm, user, socialProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preRemove(RealmModel realm) {
|
||||||
|
realmInvalidations.add(realm.getId());
|
||||||
|
getDelegate().preRemove(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preRemove(RoleModel role) {
|
||||||
|
getDelegate().preRemove(role);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,12 +7,12 @@ import org.keycloak.models.KeycloakSession;
|
||||||
* @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 SimpleCacheModelProviderFactory implements CacheModelProviderFactory {
|
public class MemoryCacheRealmProviderFactory implements CacheRealmProviderFactory {
|
||||||
protected KeycloakCache cache = new SimpleCache();
|
protected RealmCache cache = new MemoryRealmCache();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CacheModelProvider create(KeycloakSession session) {
|
public CacheRealmProvider create(KeycloakSession session) {
|
||||||
return new DefaultCacheModelProvider(cache, session);
|
return new DefaultCacheRealmProvider(cache, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -28,6 +28,6 @@ public class SimpleCacheModelProviderFactory implements CacheModelProviderFactor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "simple";
|
return "mem";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class MemoryCacheUserProviderFactory implements CacheUserProviderFactory {
|
||||||
|
protected UserCache cache = new MemoryUserCache();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CacheUserProvider create(KeycloakSession session) {
|
||||||
|
return new DefaultCacheUserProvider(cache, session);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Config.Scope config) {
|
||||||
|
config.get("");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
//To change body of implemented methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "mem";
|
||||||
|
}
|
||||||
|
}
|
125
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryRealmCache.java
vendored
Executable file
125
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryRealmCache.java
vendored
Executable file
|
@ -0,0 +1,125 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.models.cache.entities.CachedApplication;
|
||||||
|
import org.keycloak.models.cache.entities.CachedOAuthClient;
|
||||||
|
import org.keycloak.models.cache.entities.CachedRealm;
|
||||||
|
import org.keycloak.models.cache.entities.CachedRole;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class MemoryRealmCache implements RealmCache {
|
||||||
|
|
||||||
|
protected ConcurrentHashMap<String, CachedRealm> realmCache = new ConcurrentHashMap<String, CachedRealm>();
|
||||||
|
protected ConcurrentHashMap<String, CachedRealm> realmCacheByName = new ConcurrentHashMap<String, CachedRealm>();
|
||||||
|
protected ConcurrentHashMap<String, CachedApplication> applicationCache = new ConcurrentHashMap<String, CachedApplication>();
|
||||||
|
protected ConcurrentHashMap<String, CachedOAuthClient> clientCache = new ConcurrentHashMap<String, CachedOAuthClient>();
|
||||||
|
protected ConcurrentHashMap<String, CachedRole> roleCache = new ConcurrentHashMap<String, CachedRole>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
realmCache.clear();
|
||||||
|
realmCacheByName.clear();
|
||||||
|
applicationCache.clear();
|
||||||
|
clientCache.clear();
|
||||||
|
roleCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedRealm getCachedRealm(String id) {
|
||||||
|
return realmCache.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateCachedRealm(CachedRealm realm) {
|
||||||
|
realmCache.remove(realm.getId());
|
||||||
|
realmCacheByName.remove(realm.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateCachedRealmById(String id) {
|
||||||
|
CachedRealm cached = realmCache.remove(id);
|
||||||
|
if (cached != null) realmCacheByName.remove(cached.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCachedRealm(CachedRealm realm) {
|
||||||
|
realmCache.put(realm.getId(), realm);
|
||||||
|
realmCacheByName.put(realm.getName(), realm);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedRealm getCachedRealmByName(String name) {
|
||||||
|
return realmCacheByName.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedApplication getApplication(String id) {
|
||||||
|
return applicationCache.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateApplication(CachedApplication app) {
|
||||||
|
applicationCache.remove(app.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCachedApplication(CachedApplication app) {
|
||||||
|
applicationCache.put(app.getId(), app);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateCachedApplicationById(String id) {
|
||||||
|
applicationCache.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedOAuthClient getOAuthClient(String id) {
|
||||||
|
return clientCache.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateOAuthClient(CachedOAuthClient client) {
|
||||||
|
clientCache.remove(client.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCachedOAuthClient(CachedOAuthClient client) {
|
||||||
|
clientCache.put(client.getId(), client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateCachedOAuthClientById(String id) {
|
||||||
|
clientCache.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedRole getRole(String id) {
|
||||||
|
return roleCache.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateRole(CachedRole role) {
|
||||||
|
roleCache.remove(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateRoleById(String id) {
|
||||||
|
roleCache.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCachedRole(CachedRole role) {
|
||||||
|
roleCache.put(role.getId(), role);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateCachedRoleById(String id) {
|
||||||
|
roleCache.remove(id);
|
||||||
|
}
|
||||||
|
}
|
143
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java
vendored
Executable file
143
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/MemoryUserCache.java
vendored
Executable file
|
@ -0,0 +1,143 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.models.cache.entities.CachedUser;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class MemoryUserCache implements UserCache {
|
||||||
|
|
||||||
|
protected int maxUserCacheSize = 10000;
|
||||||
|
|
||||||
|
|
||||||
|
protected class RealmUsers {
|
||||||
|
protected class LRUCache extends LinkedHashMap<String, CachedUser> {
|
||||||
|
public LRUCache() {
|
||||||
|
super(1000, 1.1F, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedUser put(String key, CachedUser value) {
|
||||||
|
usersByUsername.put(value.getUsername(), value);
|
||||||
|
if (value.getEmail() != null) {
|
||||||
|
usersByEmail.put(value.getEmail(), value);
|
||||||
|
}
|
||||||
|
return super.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedUser remove(Object key) {
|
||||||
|
CachedUser user = super.remove(key);
|
||||||
|
if (user == null) return null;
|
||||||
|
removeUser(user);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
super.clear();
|
||||||
|
usersByUsername.clear();
|
||||||
|
usersByEmail.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry<String, CachedUser> eldest) {
|
||||||
|
boolean evict = size() > maxUserCacheSize;
|
||||||
|
if (evict) {
|
||||||
|
removeUser(eldest.getValue());
|
||||||
|
}
|
||||||
|
return evict;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeUser(CachedUser value) {
|
||||||
|
usersByUsername.remove(value.getUsername());
|
||||||
|
if (value.getEmail() != null) usersByEmail.remove(value.getEmail());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, CachedUser> usersById = Collections.synchronizedMap(new LRUCache());
|
||||||
|
protected Map<String, CachedUser> usersByUsername = new ConcurrentHashMap<String, CachedUser>();
|
||||||
|
protected Map<String, CachedUser> usersByEmail = new ConcurrentHashMap<String, CachedUser>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ConcurrentHashMap<String, RealmUsers> realmUsers = new ConcurrentHashMap<String, RealmUsers>();
|
||||||
|
|
||||||
|
public int getMaxUserCacheSize() {
|
||||||
|
return maxUserCacheSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxUserCacheSize(int maxUserCacheSize) {
|
||||||
|
this.maxUserCacheSize = maxUserCacheSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedUser getCachedUser(String realmId, String id) {
|
||||||
|
if (realmId == null || id == null) return null;
|
||||||
|
RealmUsers users = realmUsers.get(realmId);
|
||||||
|
if (users == null) return null;
|
||||||
|
return users.usersById.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateCachedUser(String realmId, CachedUser user) {
|
||||||
|
RealmUsers users = realmUsers.get(realmId);
|
||||||
|
if (users == null) return;
|
||||||
|
users.usersById.remove(user.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateCachedUserById(String realmId, String id) {
|
||||||
|
RealmUsers users = realmUsers.get(realmId);
|
||||||
|
if (users == null) return;
|
||||||
|
users.usersById.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCachedUser(String realmId, CachedUser user) {
|
||||||
|
RealmUsers users = realmUsers.get(realmId);
|
||||||
|
if (users == null) {
|
||||||
|
users = new RealmUsers();
|
||||||
|
realmUsers.put(realmId, users);
|
||||||
|
}
|
||||||
|
users.usersById.put(user.getId(), user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedUser getCachedUserByUsername(String realmId, String name) {
|
||||||
|
if (realmId == null || name == null) return null;
|
||||||
|
RealmUsers users = realmUsers.get(realmId);
|
||||||
|
if (users == null) return null;
|
||||||
|
CachedUser user = users.usersByUsername.get(name);
|
||||||
|
if (user == null) return null;
|
||||||
|
users.usersById.get(user.getId()); // refresh cache entry age
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CachedUser getCachedUserByEmail(String realmId, String email) {
|
||||||
|
if (realmId == null || email == null) return null;
|
||||||
|
RealmUsers users = realmUsers.get(realmId);
|
||||||
|
if (users == null) return null;
|
||||||
|
CachedUser user = users.usersByEmail.get(email);
|
||||||
|
if (user == null) return null;
|
||||||
|
users.usersById.get(user.getId()); // refresh cache entry age
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateRealmUsers(String realmId) {
|
||||||
|
realmUsers.remove(realmId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
realmUsers.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,42 +1,34 @@
|
||||||
package org.keycloak.models.cache;
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakTransaction;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.ModelProvider;
|
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.SocialLinkModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.UsernameLoginFailureModel;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 NoCacheModelProvider implements CacheModelProvider {
|
public class NoCacheRealmProvider implements CacheRealmProvider {
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
protected ModelProvider delegate;
|
protected RealmProvider delegate;
|
||||||
// protected KeycloakTransaction transactionDelegate;
|
// protected KeycloakTransaction transactionDelegate;
|
||||||
// protected boolean transactionActive;
|
// protected boolean transactionActive;
|
||||||
// protected boolean setRollbackOnly;
|
// protected boolean setRollbackOnly;
|
||||||
|
|
||||||
public NoCacheModelProvider(KeycloakSession session) {
|
public NoCacheRealmProvider(KeycloakSession session) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelProvider getDelegate() {
|
public RealmProvider getDelegate() {
|
||||||
// if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
|
// if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
|
||||||
if (delegate != null) return delegate;
|
if (delegate != null) return delegate;
|
||||||
delegate = session.getProvider(ModelProvider.class);
|
delegate = session.getProvider(RealmProvider.class);
|
||||||
// transactionDelegate = delegate.getTransaction();
|
// transactionDelegate = delegate.getTransaction();
|
||||||
// if (!transactionDelegate.isActive()) {
|
// if (!transactionDelegate.isActive()) {
|
||||||
// transactionDelegate.begin();
|
// transactionDelegate.begin();
|
||||||
|
@ -83,21 +75,6 @@ public class NoCacheModelProvider implements CacheModelProvider {
|
||||||
return getDelegate().getRealmByName(name);
|
return getDelegate().getRealmByName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
|
||||||
return getDelegate().getUserById(id, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
|
||||||
return getDelegate().getUserByUsername(username, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserByEmail(String email, RealmModel realm) {
|
|
||||||
return getDelegate().getUserByEmail(email, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RealmModel> getRealms() {
|
public List<RealmModel> getRealms() {
|
||||||
// we don't cache this for now
|
// we don't cache this for now
|
||||||
|
@ -114,36 +91,6 @@ public class NoCacheModelProvider implements CacheModelProvider {
|
||||||
if (delegate != null) delegate.close();
|
if (delegate != null) delegate.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
|
|
||||||
return getDelegate().getUserBySocialLink(socialLink, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> getUsers(RealmModel realm) {
|
|
||||||
return getDelegate().getUsers(realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUser(String search, RealmModel realm) {
|
|
||||||
return getDelegate().searchForUser(search, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
|
|
||||||
return getDelegate().searchForUserByAttributes(attributes, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
|
|
||||||
return getDelegate().getSocialLinks(user, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm) {
|
|
||||||
return getDelegate().getSocialLink(user, socialProvider, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RoleModel getRoleById(String id, RealmModel realm) {
|
public RoleModel getRoleById(String id, RealmModel realm) {
|
||||||
return getDelegate().getRoleById(id, realm);
|
return getDelegate().getRoleById(id, realm);
|
|
@ -7,10 +7,10 @@ import org.keycloak.models.KeycloakSession;
|
||||||
* @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 NoCacheModelProviderFactory implements CacheModelProviderFactory {
|
public class NoCacheRealmProviderFactory implements CacheRealmProviderFactory {
|
||||||
@Override
|
@Override
|
||||||
public CacheModelProvider create(KeycloakSession session) {
|
public CacheRealmProvider create(KeycloakSession session) {
|
||||||
return new NoCacheModelProvider(session);
|
return new NoCacheRealmProvider(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
126
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
vendored
Executable file
126
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProvider.java
vendored
Executable file
|
@ -0,0 +1,126 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakTransaction;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.SocialLinkModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.UserProvider;
|
||||||
|
import org.keycloak.models.cache.entities.CachedUser;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class NoCacheUserProvider implements CacheUserProvider {
|
||||||
|
protected KeycloakSession session;
|
||||||
|
protected UserProvider delegate;
|
||||||
|
|
||||||
|
public NoCacheUserProvider(KeycloakSession session) {
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProvider getDelegate() {
|
||||||
|
if (delegate != null) return delegate;
|
||||||
|
delegate = session.getProvider(UserProvider.class);
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerUserInvalidation(RealmModel realm, String id) {
|
||||||
|
//To change body of implemented methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel getUserById(String id, RealmModel realm) {
|
||||||
|
return getDelegate().getUserById(id, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel getUserByUsername(String username, RealmModel realm) {
|
||||||
|
return getDelegate().getUserByUsername(username, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel getUserByEmail(String email, RealmModel realm) {
|
||||||
|
return getDelegate().getUserByEmail(email, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (delegate != null) delegate.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
|
||||||
|
return getDelegate().getUserBySocialLink(socialLink, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserModel> getUsers(RealmModel realm) {
|
||||||
|
return getDelegate().getUsers(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserModel> searchForUser(String search, RealmModel realm) {
|
||||||
|
return getDelegate().searchForUser(search, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
|
||||||
|
return getDelegate().searchForUserByAttributes(attributes, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
|
||||||
|
return getDelegate().getSocialLinks(user, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm) {
|
||||||
|
return getDelegate().getSocialLink(user, socialProvider, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles) {
|
||||||
|
return getDelegate().addUser(realm, id, username, addDefaultRoles);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserModel addUser(RealmModel realm, String username) {
|
||||||
|
return getDelegate().addUser(realm, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeUser(RealmModel realm, String name) {
|
||||||
|
return getDelegate().removeUser(realm, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addSocialLink(RealmModel realm, UserModel user, SocialLinkModel socialLink) {
|
||||||
|
getDelegate().addSocialLink(realm, user, socialLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeSocialLink(RealmModel realm, UserModel user, String socialProvider) {
|
||||||
|
return getDelegate().removeSocialLink(realm, user, socialProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preRemove(RealmModel realm) {
|
||||||
|
getDelegate().preRemove(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preRemove(RoleModel role) {
|
||||||
|
getDelegate().preRemove(role);
|
||||||
|
}
|
||||||
|
}
|
30
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProviderFactory.java
vendored
Executable file
30
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheUserProviderFactory.java
vendored
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class NoCacheUserProviderFactory implements CacheUserProviderFactory {
|
||||||
|
@Override
|
||||||
|
public CacheUserProvider create(KeycloakSession session) {
|
||||||
|
return new NoCacheUserProvider(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
//To change body of implemented methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Config.Scope config) {
|
||||||
|
//To change body of implemented methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ public class OAuthClientAdapter extends ClientAdapter implements OAuthClientMode
|
||||||
protected OAuthClientModel updated;
|
protected OAuthClientModel updated;
|
||||||
protected CachedOAuthClient cached;
|
protected CachedOAuthClient cached;
|
||||||
|
|
||||||
public OAuthClientAdapter(RealmModel cachedRealm, CachedOAuthClient cached, CacheModelProvider cacheSession, KeycloakCache cache) {
|
public OAuthClientAdapter(RealmModel cachedRealm, CachedOAuthClient cached, CacheRealmProvider cacheSession, RealmCache cache) {
|
||||||
super(cachedRealm, cached, cache, cacheSession);
|
super(cachedRealm, cached, cache, cacheSession);
|
||||||
this.cached = cached;
|
this.cached = cached;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,11 @@ import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.SocialLinkModel;
|
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserCredentialValueModel;
|
import org.keycloak.models.UserCredentialValueModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.UsernameLoginFailureModel;
|
|
||||||
import org.keycloak.models.cache.entities.CachedRealm;
|
import org.keycloak.models.cache.entities.CachedRealm;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
|
|
||||||
import org.keycloak.models.utils.TimeBasedOTP;
|
import org.keycloak.models.utils.TimeBasedOTP;
|
||||||
|
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
@ -35,13 +31,13 @@ import java.util.Set;
|
||||||
*/
|
*/
|
||||||
public class RealmAdapter implements RealmModel {
|
public class RealmAdapter implements RealmModel {
|
||||||
protected CachedRealm cached;
|
protected CachedRealm cached;
|
||||||
protected CacheModelProvider cacheSession;
|
protected CacheRealmProvider cacheSession;
|
||||||
protected RealmModel updated;
|
protected RealmModel updated;
|
||||||
protected KeycloakCache cache;
|
protected RealmCache cache;
|
||||||
protected volatile transient PublicKey publicKey;
|
protected volatile transient PublicKey publicKey;
|
||||||
protected volatile transient PrivateKey privateKey;
|
protected volatile transient PrivateKey privateKey;
|
||||||
|
|
||||||
public RealmAdapter(CachedRealm cached, CacheModelProvider cacheSession) {
|
public RealmAdapter(CachedRealm cached, CacheRealmProvider cacheSession) {
|
||||||
this.cached = cached;
|
this.cached = cached;
|
||||||
this.cacheSession = cacheSession;
|
this.cacheSession = cacheSession;
|
||||||
}
|
}
|
||||||
|
@ -395,39 +391,6 @@ public class RealmAdapter implements RealmModel {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUser(String name) {
|
|
||||||
return cacheSession.getUserByUsername(name, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserByEmail(String email) {
|
|
||||||
return cacheSession.getUserByEmail(email, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserById(String id) {
|
|
||||||
return cacheSession.getUserById(id, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel addUser(String id, String username, boolean addDefaultRoles) {
|
|
||||||
getDelegateForUpdate();
|
|
||||||
return updated.addUser(id, username, addDefaultRoles);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel addUser(String username) {
|
|
||||||
getDelegateForUpdate();
|
|
||||||
return updated.addUser(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeUser(String name) {
|
|
||||||
getDelegateForUpdate();
|
|
||||||
return updated.removeUser(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RoleModel getRoleById(String id) {
|
public RoleModel getRoleById(String id) {
|
||||||
if (updated != null) return updated.getRoleById(id);
|
if (updated != null) return updated.getRoleById(id);
|
||||||
|
@ -538,36 +501,6 @@ public class RealmAdapter implements RealmModel {
|
||||||
updated.updateRequiredCredentials(creds);
|
updated.updateRequiredCredentials(creds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
|
|
||||||
if (updated != null) return updated.getUserBySocialLink(socialLink);
|
|
||||||
return cacheSession.getUserBySocialLink(socialLink, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<SocialLinkModel> getSocialLinks(UserModel user) {
|
|
||||||
if (updated != null) return updated.getSocialLinks(user);
|
|
||||||
return cacheSession.getSocialLinks(user, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SocialLinkModel getSocialLink(UserModel user, String socialProvider) {
|
|
||||||
if (updated != null) return updated.getSocialLink(user, socialProvider);
|
|
||||||
return cacheSession.getSocialLink(user, socialProvider, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addSocialLink(UserModel user, SocialLinkModel socialLink) {
|
|
||||||
getDelegateForUpdate();
|
|
||||||
updated.addSocialLink(user, socialLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeSocialLink(UserModel user, String socialProvider) {
|
|
||||||
getDelegateForUpdate();
|
|
||||||
return updated.removeSocialLink(user, socialProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSocial() {
|
public boolean isSocial() {
|
||||||
if (updated != null) return updated.isSocial();
|
if (updated != null) return updated.isSocial();
|
||||||
|
@ -592,24 +525,6 @@ public class RealmAdapter implements RealmModel {
|
||||||
updated.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin);
|
updated.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> getUsers() {
|
|
||||||
if (updated != null) return updated.getUsers();
|
|
||||||
return cacheSession.getUsers(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUser(String search) {
|
|
||||||
if (updated != null) return updated.searchForUser(search);
|
|
||||||
return cacheSession.searchForUser(search, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
|
|
||||||
if (updated != null) return updated.searchForUserByAttributes(attributes);
|
|
||||||
return cacheSession.searchForUserByAttributes(attributes, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OAuthClientModel addOAuthClient(String name) {
|
public OAuthClientModel addOAuthClient(String name) {
|
||||||
getDelegateForUpdate();
|
getDelegateForUpdate();
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
package org.keycloak.models.cache;
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.cache.entities.CachedApplication;
|
import org.keycloak.models.cache.entities.CachedApplication;
|
||||||
import org.keycloak.models.cache.entities.CachedOAuthClient;
|
import org.keycloak.models.cache.entities.CachedOAuthClient;
|
||||||
import org.keycloak.models.cache.entities.CachedRealm;
|
import org.keycloak.models.cache.entities.CachedRealm;
|
||||||
import org.keycloak.models.cache.entities.CachedRole;
|
import org.keycloak.models.cache.entities.CachedRole;
|
||||||
import org.keycloak.models.cache.entities.CachedUser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 interface KeycloakCache {
|
public interface RealmCache {
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
CachedRealm getCachedRealm(String id);
|
CachedRealm getCachedRealm(String id);
|
||||||
|
@ -51,16 +49,4 @@ public interface KeycloakCache {
|
||||||
|
|
||||||
void invalidateRoleById(String id);
|
void invalidateRoleById(String id);
|
||||||
|
|
||||||
CachedUser getCachedUser(String id);
|
|
||||||
|
|
||||||
void invalidateCachedUser(CachedUser user);
|
|
||||||
|
|
||||||
void addCachedUser(CachedUser user);
|
|
||||||
|
|
||||||
CachedUser getCachedUserByUsername(String name, RealmModel realm);
|
|
||||||
CachedUser getCachedUserByEmail(String name, RealmModel realm);
|
|
||||||
|
|
||||||
void invalidedCachedUserById(String id);
|
|
||||||
|
|
||||||
void invalidateCachedUserById(String id);
|
|
||||||
}
|
}
|
|
@ -19,11 +19,11 @@ public class RoleAdapter implements RoleModel {
|
||||||
|
|
||||||
protected RoleModel updated;
|
protected RoleModel updated;
|
||||||
protected CachedRole cached;
|
protected CachedRole cached;
|
||||||
protected KeycloakCache cache;
|
protected RealmCache cache;
|
||||||
protected CacheModelProvider cacheSession;
|
protected CacheRealmProvider cacheSession;
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
|
|
||||||
public RoleAdapter(CachedRole cached, KeycloakCache cache, CacheModelProvider session, RealmModel realm) {
|
public RoleAdapter(CachedRole cached, RealmCache cache, CacheRealmProvider session, RealmModel realm) {
|
||||||
this.cached = cached;
|
this.cached = cached;
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
this.cacheSession = session;
|
this.cacheSession = session;
|
||||||
|
|
|
@ -1,246 +0,0 @@
|
||||||
package org.keycloak.models.cache;
|
|
||||||
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.cache.entities.CachedApplication;
|
|
||||||
import org.keycloak.models.cache.entities.CachedOAuthClient;
|
|
||||||
import org.keycloak.models.cache.entities.CachedRealm;
|
|
||||||
import org.keycloak.models.cache.entities.CachedRole;
|
|
||||||
import org.keycloak.models.cache.entities.CachedUser;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class SimpleCache implements KeycloakCache {
|
|
||||||
|
|
||||||
protected ConcurrentHashMap<String, CachedRealm> realmCache = new ConcurrentHashMap<String, CachedRealm>();
|
|
||||||
protected ConcurrentHashMap<String, CachedRealm> realmCacheByName = new ConcurrentHashMap<String, CachedRealm>();
|
|
||||||
protected ConcurrentHashMap<String, CachedApplication> applicationCache = new ConcurrentHashMap<String, CachedApplication>();
|
|
||||||
protected ConcurrentHashMap<String, CachedOAuthClient> clientCache = new ConcurrentHashMap<String, CachedOAuthClient>();
|
|
||||||
protected ConcurrentHashMap<String, CachedRole> roleCache = new ConcurrentHashMap<String, CachedRole>();
|
|
||||||
|
|
||||||
protected int maxUserCacheSize = 10000;
|
|
||||||
protected boolean userCacheEnabled = true;
|
|
||||||
|
|
||||||
protected Map<String, CachedUser> usersById = Collections.synchronizedMap(new LRUCache());
|
|
||||||
protected Map<String, CachedUser> usersByUsername = new ConcurrentHashMap<String, CachedUser>();
|
|
||||||
protected Map<String, CachedUser> usersByEmail = new ConcurrentHashMap<String, CachedUser>();
|
|
||||||
|
|
||||||
protected class LRUCache extends LinkedHashMap<String, CachedUser> {
|
|
||||||
public LRUCache() {
|
|
||||||
super(1000, 1.1F, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedUser put(String key, CachedUser value) {
|
|
||||||
usersByUsername.put(value.getUsernameKey(), value);
|
|
||||||
if (value.getEmail() != null) {
|
|
||||||
usersByEmail.put(value.getEmailKey(), value);
|
|
||||||
}
|
|
||||||
return super.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedUser remove(Object key) {
|
|
||||||
CachedUser user = super.remove(key);
|
|
||||||
if (user == null) return null;
|
|
||||||
removeUser(user);
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
super.clear();
|
|
||||||
usersByUsername.clear();
|
|
||||||
usersByEmail.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean removeEldestEntry(Map.Entry<String, CachedUser> eldest) {
|
|
||||||
boolean evict = size() > maxUserCacheSize;
|
|
||||||
if (evict) {
|
|
||||||
removeUser(eldest.getValue());
|
|
||||||
}
|
|
||||||
return evict;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeUser(CachedUser value) {
|
|
||||||
usersByUsername.remove(value.getUsernameKey());
|
|
||||||
if (value.getEmail() != null) usersByEmail.remove(value.getEmailKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxUserCacheSize() {
|
|
||||||
return maxUserCacheSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxUserCacheSize(int maxUserCacheSize) {
|
|
||||||
this.maxUserCacheSize = maxUserCacheSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUserCacheEnabled() {
|
|
||||||
return userCacheEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserCacheEnabled(boolean userCacheEnabled) {
|
|
||||||
this.userCacheEnabled = userCacheEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedUser getCachedUser(String id) {
|
|
||||||
if (!userCacheEnabled) return null;
|
|
||||||
return usersById.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCachedUser(CachedUser user) {
|
|
||||||
if (!userCacheEnabled) return;
|
|
||||||
usersById.remove(user.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCachedUserById(String id) {
|
|
||||||
if (!userCacheEnabled) return;
|
|
||||||
usersById.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addCachedUser(CachedUser user) {
|
|
||||||
if (!userCacheEnabled) return;
|
|
||||||
usersById.put(user.getId(), user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedUser getCachedUserByUsername(String name, RealmModel realm) {
|
|
||||||
if (!userCacheEnabled) return null;
|
|
||||||
CachedUser user = usersByUsername.get(realm.getId() + "." +name);
|
|
||||||
if (user == null) return null;
|
|
||||||
usersById.get(user.getId()); // refresh cache entry age
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedUser getCachedUserByEmail(String name, RealmModel realm) {
|
|
||||||
if (!userCacheEnabled) return null;
|
|
||||||
CachedUser user = usersByEmail.get(realm.getId() + "." +name);
|
|
||||||
if (user == null) return null;
|
|
||||||
usersById.get(user.getId()); // refresh cache entry age
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidedCachedUserById(String id) {
|
|
||||||
if (!userCacheEnabled) return;
|
|
||||||
usersById.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
realmCache.clear();
|
|
||||||
realmCacheByName.clear();
|
|
||||||
applicationCache.clear();
|
|
||||||
clientCache.clear();
|
|
||||||
roleCache.clear();
|
|
||||||
usersById.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedRealm getCachedRealm(String id) {
|
|
||||||
return realmCache.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCachedRealm(CachedRealm realm) {
|
|
||||||
realmCache.remove(realm.getId());
|
|
||||||
realmCacheByName.remove(realm.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCachedRealmById(String id) {
|
|
||||||
CachedRealm cached = realmCache.remove(id);
|
|
||||||
if (cached != null) realmCacheByName.remove(cached.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addCachedRealm(CachedRealm realm) {
|
|
||||||
realmCache.put(realm.getId(), realm);
|
|
||||||
realmCacheByName.put(realm.getName(), realm);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedRealm getCachedRealmByName(String name) {
|
|
||||||
return realmCacheByName.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedApplication getApplication(String id) {
|
|
||||||
return applicationCache.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateApplication(CachedApplication app) {
|
|
||||||
applicationCache.remove(app.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addCachedApplication(CachedApplication app) {
|
|
||||||
applicationCache.put(app.getId(), app);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCachedApplicationById(String id) {
|
|
||||||
applicationCache.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedOAuthClient getOAuthClient(String id) {
|
|
||||||
return clientCache.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateOAuthClient(CachedOAuthClient client) {
|
|
||||||
clientCache.remove(client.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addCachedOAuthClient(CachedOAuthClient client) {
|
|
||||||
clientCache.put(client.getId(), client);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCachedOAuthClientById(String id) {
|
|
||||||
clientCache.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CachedRole getRole(String id) {
|
|
||||||
return roleCache.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateRole(CachedRole role) {
|
|
||||||
roleCache.remove(role.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateRoleById(String id) {
|
|
||||||
roleCache.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addCachedRole(CachedRole role) {
|
|
||||||
roleCache.put(role.getId(), role);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCachedRoleById(String id) {
|
|
||||||
roleCache.remove(id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@ package org.keycloak.models.cache;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.AuthenticationLinkModel;
|
import org.keycloak.models.AuthenticationLinkModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleContainerModel;
|
import org.keycloak.models.RoleContainerModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
|
@ -22,21 +23,21 @@ import java.util.Set;
|
||||||
public class UserAdapter implements UserModel {
|
public class UserAdapter implements UserModel {
|
||||||
protected UserModel updated;
|
protected UserModel updated;
|
||||||
protected CachedUser cached;
|
protected CachedUser cached;
|
||||||
protected KeycloakCache cache;
|
protected CacheUserProvider userProviderCache;
|
||||||
protected CacheModelProvider cacheSession;
|
protected KeycloakSession keycloakSession;
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
|
|
||||||
public UserAdapter(CachedUser cached, KeycloakCache cache, CacheModelProvider session, RealmModel realm) {
|
public UserAdapter(CachedUser cached, CacheUserProvider userProvider, KeycloakSession keycloakSession, RealmModel realm) {
|
||||||
this.cached = cached;
|
this.cached = cached;
|
||||||
this.cache = cache;
|
this.userProviderCache = userProvider;
|
||||||
this.cacheSession = session;
|
this.keycloakSession = keycloakSession;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void getDelegateForUpdate() {
|
protected void getDelegateForUpdate() {
|
||||||
if (updated == null) {
|
if (updated == null) {
|
||||||
cacheSession.registerUserInvalidation(getId());
|
userProviderCache.registerUserInvalidation(realm, getId());
|
||||||
updated = cacheSession.getDelegate().getUserById(getId(), realm);
|
updated = userProviderCache.getDelegate().getUserById(getId(), realm);
|
||||||
if (updated == null) throw new IllegalStateException("Not found in database");
|
if (updated == null) throw new IllegalStateException("Not found in database");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,7 +258,13 @@ public class UserAdapter implements UserModel {
|
||||||
if (updated != null) return updated.getRoleMappings();
|
if (updated != null) return updated.getRoleMappings();
|
||||||
Set<RoleModel> roles = new HashSet<RoleModel>();
|
Set<RoleModel> roles = new HashSet<RoleModel>();
|
||||||
for (String id : cached.getRoleMappings()) {
|
for (String id : cached.getRoleMappings()) {
|
||||||
roles.add(cacheSession.getRoleById(id, realm));
|
RoleModel roleById = keycloakSession.realms().getRoleById(id, realm);
|
||||||
|
if (roleById == null) {
|
||||||
|
// chance that role was removed, so just delete to persistence and get user invalidated
|
||||||
|
getDelegateForUpdate();
|
||||||
|
return updated.getRoleMappings();
|
||||||
|
}
|
||||||
|
roles.add(roleById);
|
||||||
|
|
||||||
}
|
}
|
||||||
return roles;
|
return roles;
|
||||||
|
|
25
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserCache.java
vendored
Executable file
25
model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/UserCache.java
vendored
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
package org.keycloak.models.cache;
|
||||||
|
|
||||||
|
import org.keycloak.models.cache.entities.CachedUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public interface UserCache {
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
CachedUser getCachedUser(String realmId, String id);
|
||||||
|
|
||||||
|
void invalidateCachedUser(String realmId, CachedUser user);
|
||||||
|
|
||||||
|
void addCachedUser(String realmId, CachedUser user);
|
||||||
|
|
||||||
|
CachedUser getCachedUserByUsername(String realmId, String name);
|
||||||
|
|
||||||
|
CachedUser getCachedUserByEmail(String realmId, String name);
|
||||||
|
|
||||||
|
void invalidateCachedUserById(String realmId, String id);
|
||||||
|
|
||||||
|
void invalidateRealmUsers(String realmId);
|
||||||
|
}
|
|
@ -1,21 +1,15 @@
|
||||||
package org.keycloak.models.cache.entities;
|
package org.keycloak.models.cache.entities;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.ModelProvider;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.cache.RealmCache;
|
||||||
import org.keycloak.models.UserSessionModel;
|
|
||||||
import org.keycloak.models.cache.KeycloakCache;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -29,7 +23,7 @@ public class CachedApplication extends CachedClient {
|
||||||
private boolean bearerOnly;
|
private boolean bearerOnly;
|
||||||
private Map<String, String> roles = new HashMap<String, String>();
|
private Map<String, String> roles = new HashMap<String, String>();
|
||||||
|
|
||||||
public CachedApplication(KeycloakCache cache, ModelProvider delegate, RealmModel realm, ApplicationModel model) {
|
public CachedApplication(RealmCache cache, RealmProvider delegate, RealmModel realm, ApplicationModel model) {
|
||||||
super(cache, delegate, realm, model);
|
super(cache, delegate, realm, model);
|
||||||
surrogateAuthRequired = model.isSurrogateAuthRequired();
|
surrogateAuthRequired = model.isSurrogateAuthRequired();
|
||||||
managementUrl = model.getManagementUrl();
|
managementUrl = model.getManagementUrl();
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package org.keycloak.models.cache.entities;
|
package org.keycloak.models.cache.entities;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.ModelProvider;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.cache.KeycloakCache;
|
import org.keycloak.models.cache.RealmCache;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -28,7 +26,7 @@ public class CachedClient {
|
||||||
protected Set<String> scope = new HashSet<String>();
|
protected Set<String> scope = new HashSet<String>();
|
||||||
protected Set<String> webOrigins = new HashSet<String>();
|
protected Set<String> webOrigins = new HashSet<String>();
|
||||||
|
|
||||||
public CachedClient(KeycloakCache cache, ModelProvider delegate, RealmModel realm, ClientModel model) {
|
public CachedClient(RealmCache cache, RealmProvider delegate, RealmModel realm, ClientModel model) {
|
||||||
id = model.getId();
|
id = model.getId();
|
||||||
secret = model.getSecret();
|
secret = model.getSecret();
|
||||||
name = model.getClientId();
|
name = model.getClientId();
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
package org.keycloak.models.cache.entities;
|
package org.keycloak.models.cache.entities;
|
||||||
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.ModelProvider;
|
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.cache.KeycloakCache;
|
import org.keycloak.models.cache.RealmCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 CachedOAuthClient extends CachedClient {
|
public class CachedOAuthClient extends CachedClient {
|
||||||
public CachedOAuthClient(KeycloakCache cache, ModelProvider delegate, RealmModel realm, OAuthClientModel model) {
|
public CachedOAuthClient(RealmCache cache, RealmProvider delegate, RealmModel realm, OAuthClientModel model) {
|
||||||
super(cache, delegate, realm, model);
|
super(cache, delegate, realm, model);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,13 @@ package org.keycloak.models.cache.entities;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.AuthenticationProviderModel;
|
import org.keycloak.models.AuthenticationProviderModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.ModelProvider;
|
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.cache.KeycloakCache;
|
import org.keycloak.models.cache.RealmCache;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -81,7 +80,7 @@ public class CachedRealm {
|
||||||
public CachedRealm() {
|
public CachedRealm() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachedRealm(KeycloakCache cache, ModelProvider delegate, RealmModel model) {
|
public CachedRealm(RealmCache cache, RealmProvider delegate, RealmModel model) {
|
||||||
id = model.getId();
|
id = model.getId();
|
||||||
name = model.getName();
|
name = model.getName();
|
||||||
enabled = model.isEnabled();
|
enabled = model.isEnabled();
|
||||||
|
|
|
@ -2,9 +2,6 @@ package org.keycloak.models.cache.entities;
|
||||||
|
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 $
|
||||||
|
|
|
@ -20,11 +20,9 @@ import java.util.Set;
|
||||||
public class CachedUser {
|
public class CachedUser {
|
||||||
private String id;
|
private String id;
|
||||||
private String username;
|
private String username;
|
||||||
private String usernameKey;
|
|
||||||
private String firstName;
|
private String firstName;
|
||||||
private String lastName;
|
private String lastName;
|
||||||
private String email;
|
private String email;
|
||||||
private String emailKey;
|
|
||||||
private boolean emailVerified;
|
private boolean emailVerified;
|
||||||
private List<UserCredentialValueModel> credentials = new LinkedList<UserCredentialValueModel>();
|
private List<UserCredentialValueModel> credentials = new LinkedList<UserCredentialValueModel>();
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
@ -38,14 +36,10 @@ public class CachedUser {
|
||||||
public CachedUser(RealmModel realm, UserModel user) {
|
public CachedUser(RealmModel realm, UserModel user) {
|
||||||
this.id = user.getId();
|
this.id = user.getId();
|
||||||
this.username = user.getUsername();
|
this.username = user.getUsername();
|
||||||
this.usernameKey = realm.getId() + "." + this.username;
|
|
||||||
this.firstName = user.getFirstName();
|
this.firstName = user.getFirstName();
|
||||||
this.lastName = user.getLastName();
|
this.lastName = user.getLastName();
|
||||||
this.attributes.putAll(user.getAttributes());
|
this.attributes.putAll(user.getAttributes());
|
||||||
this.email = user.getEmail();
|
this.email = user.getEmail();
|
||||||
if (this.email != null) {
|
|
||||||
this.emailKey = realm.getId() + "." + this.email;
|
|
||||||
}
|
|
||||||
this.emailVerified = user.isEmailVerified();
|
this.emailVerified = user.isEmailVerified();
|
||||||
this.credentials.addAll(user.getCredentialsDirectly());
|
this.credentials.addAll(user.getCredentialsDirectly());
|
||||||
this.enabled = user.isEnabled();
|
this.enabled = user.isEnabled();
|
||||||
|
@ -65,14 +59,6 @@ public class CachedUser {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsernameKey() {
|
|
||||||
return usernameKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmailKey() {
|
|
||||||
return emailKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFirstName() {
|
public String getFirstName() {
|
||||||
return firstName;
|
return firstName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
org.keycloak.models.cache.SimpleCacheModelProviderFactory
|
|
||||||
org.keycloak.models.cache.NoCacheModelProviderFactory
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
org.keycloak.models.cache.MemoryCacheRealmProviderFactory
|
||||||
|
org.keycloak.models.cache.NoCacheRealmProviderFactory
|
|
@ -0,0 +1,2 @@
|
||||||
|
org.keycloak.models.cache.MemoryCacheUserProviderFactory
|
||||||
|
org.keycloak.models.cache.NoCacheUserProviderFactory
|
|
@ -1 +1,2 @@
|
||||||
org.keycloak.models.cache.CacheModelProviderSpi
|
org.keycloak.models.cache.CacheRealmProviderSpi
|
||||||
|
org.keycloak.models.cache.CacheUserProviderSpi
|
|
@ -2,12 +2,13 @@ package org.keycloak.models.jpa;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleContainerModel;
|
import org.keycloak.models.RoleContainerModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.jpa.entities.ApplicationEntity;
|
||||||
import org.keycloak.models.jpa.entities.*;
|
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.ScopeMappingEntity;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
@ -25,10 +26,12 @@ import java.util.Set;
|
||||||
public class ApplicationAdapter extends ClientAdapter implements ApplicationModel {
|
public class ApplicationAdapter extends ClientAdapter implements ApplicationModel {
|
||||||
|
|
||||||
protected EntityManager em;
|
protected EntityManager em;
|
||||||
|
protected KeycloakSession session;
|
||||||
protected ApplicationEntity applicationEntity;
|
protected ApplicationEntity applicationEntity;
|
||||||
|
|
||||||
public ApplicationAdapter(RealmModel realm, EntityManager em, ApplicationEntity applicationEntity) {
|
public ApplicationAdapter(RealmModel realm, EntityManager em, KeycloakSession session, ApplicationEntity applicationEntity) {
|
||||||
super(realm, applicationEntity, em);
|
super(realm, applicationEntity, em);
|
||||||
|
this.session = session;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.em = em;
|
this.em = em;
|
||||||
this.applicationEntity = applicationEntity;
|
this.applicationEntity = applicationEntity;
|
||||||
|
@ -135,6 +138,7 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
|
||||||
}
|
}
|
||||||
if (!roleModel.getContainer().equals(this)) return false;
|
if (!roleModel.getContainer().equals(this)) return false;
|
||||||
|
|
||||||
|
session.users().preRemove(roleModel);
|
||||||
RoleEntity role = RoleAdapter.toRoleEntity(roleModel, em);
|
RoleEntity role = RoleAdapter.toRoleEntity(roleModel, em);
|
||||||
if (!role.isApplicationRole()) return false;
|
if (!role.isApplicationRole()) return false;
|
||||||
|
|
||||||
|
@ -143,7 +147,6 @@ public class ApplicationAdapter extends ClientAdapter implements ApplicationMode
|
||||||
applicationEntity.getDefaultRoles().remove(role);
|
applicationEntity.getDefaultRoles().remove(role);
|
||||||
em.createNativeQuery("delete from CompositeRole where childRole = :role").setParameter("role", role).executeUpdate();
|
em.createNativeQuery("delete from CompositeRole where childRole = :role").setParameter("role", role).executeUpdate();
|
||||||
em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate();
|
em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate();
|
||||||
em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", role).executeUpdate();
|
|
||||||
role.setApplication(null);
|
role.setApplication(null);
|
||||||
em.flush();
|
em.flush();
|
||||||
em.remove(role);
|
em.remove(role);
|
||||||
|
|
|
@ -1,278 +0,0 @@
|
||||||
package org.keycloak.models.jpa;
|
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.KeycloakTransaction;
|
|
||||||
import org.keycloak.models.ModelProvider;
|
|
||||||
import org.keycloak.models.OAuthClientModel;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.RoleModel;
|
|
||||||
import org.keycloak.models.SocialLinkModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.jpa.entities.ApplicationEntity;
|
|
||||||
import org.keycloak.models.jpa.entities.OAuthClientEntity;
|
|
||||||
import org.keycloak.models.jpa.entities.RealmEntity;
|
|
||||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
|
||||||
import org.keycloak.models.jpa.entities.SocialLinkEntity;
|
|
||||||
import org.keycloak.models.jpa.entities.UserEntity;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.TypedQuery;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class JpaModelProvider implements ModelProvider {
|
|
||||||
private final KeycloakSession session;
|
|
||||||
protected EntityManager em;
|
|
||||||
|
|
||||||
public JpaModelProvider(KeycloakSession session, EntityManager em) {
|
|
||||||
this.session = session;
|
|
||||||
this.em = em;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RealmModel createRealm(String name) {
|
|
||||||
return createRealm(KeycloakModelUtils.generateId(), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RealmModel createRealm(String id, String name) {
|
|
||||||
RealmEntity realm = new RealmEntity();
|
|
||||||
realm.setName(name);
|
|
||||||
realm.setId(id);
|
|
||||||
em.persist(realm);
|
|
||||||
em.flush();
|
|
||||||
return new RealmAdapter(session, em, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RealmModel getRealm(String id) {
|
|
||||||
RealmEntity realm = em.find(RealmEntity.class, id);
|
|
||||||
if (realm == null) return null;
|
|
||||||
return new RealmAdapter(session, em, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<RealmModel> getRealms() {
|
|
||||||
TypedQuery<RealmEntity> query = em.createNamedQuery("getAllRealms", RealmEntity.class);
|
|
||||||
List<RealmEntity> entities = query.getResultList();
|
|
||||||
List<RealmModel> realms = new ArrayList<RealmModel>();
|
|
||||||
for (RealmEntity entity : entities) {
|
|
||||||
realms.add(new RealmAdapter(session, em, entity));
|
|
||||||
}
|
|
||||||
return realms;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RealmModel getRealmByName(String name) {
|
|
||||||
TypedQuery<RealmEntity> query = em.createNamedQuery("getRealmByName", RealmEntity.class);
|
|
||||||
query.setParameter("name", name);
|
|
||||||
List<RealmEntity> entities = query.getResultList();
|
|
||||||
if (entities.size() == 0) return null;
|
|
||||||
if (entities.size() > 1) throw new IllegalStateException("Should not be more than one realm with same name");
|
|
||||||
RealmEntity realm = query.getResultList().get(0);
|
|
||||||
if (realm == null) return null;
|
|
||||||
return new RealmAdapter(session, em, realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserById(String id, RealmModel realmModel) {
|
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserById", UserEntity.class);
|
|
||||||
query.setParameter("id", id);
|
|
||||||
RealmEntity realm = em.getReference(RealmEntity.class, realmModel.getId());
|
|
||||||
query.setParameter("realm", realm);
|
|
||||||
List<UserEntity> entities = query.getResultList();
|
|
||||||
if (entities.size() == 0) return null;
|
|
||||||
return new UserAdapter(realmModel, em, entities.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserByUsername(String username, RealmModel realmModel) {
|
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByUsername", UserEntity.class);
|
|
||||||
query.setParameter("username", username);
|
|
||||||
RealmEntity realm = em.getReference(RealmEntity.class, realmModel.getId());
|
|
||||||
query.setParameter("realm", realm);
|
|
||||||
List<UserEntity> results = query.getResultList();
|
|
||||||
if (results.size() == 0) return null;
|
|
||||||
return new UserAdapter(realmModel, em, results.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserByEmail(String email, RealmModel realmModel) {
|
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByEmail", UserEntity.class);
|
|
||||||
query.setParameter("email", email);
|
|
||||||
RealmEntity realm = em.getReference(RealmEntity.class, realmModel.getId());
|
|
||||||
query.setParameter("realm", realm);
|
|
||||||
List<UserEntity> results = query.getResultList();
|
|
||||||
return results.isEmpty() ? null : new UserAdapter(realmModel, em, results.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeRealm(String id) {
|
|
||||||
RealmEntity realm = em.find(RealmEntity.class, id);
|
|
||||||
if (realm == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RealmAdapter adapter = new RealmAdapter(session, em, realm);
|
|
||||||
for (ApplicationEntity a : new LinkedList<ApplicationEntity>(realm.getApplications())) {
|
|
||||||
adapter.removeApplication(a.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (OAuthClientModel oauth : adapter.getOAuthClients()) {
|
|
||||||
adapter.removeOAuthClient(oauth.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (UserEntity u : em.createQuery("from UserEntity u where u.realm = :realm", UserEntity.class).setParameter("realm", realm).getResultList()) {
|
|
||||||
adapter.removeUser(u.getUsername());
|
|
||||||
}
|
|
||||||
|
|
||||||
em.remove(realm);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
|
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("findUserByLinkAndRealm", UserEntity.class);
|
|
||||||
RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
|
|
||||||
query.setParameter("realm", realmEntity);
|
|
||||||
query.setParameter("socialProvider", socialLink.getSocialProvider());
|
|
||||||
query.setParameter("socialUserId", socialLink.getSocialUserId());
|
|
||||||
List<UserEntity> results = query.getResultList();
|
|
||||||
if (results.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
} else if (results.size() > 1) {
|
|
||||||
throw new IllegalStateException("More results found for socialProvider=" + socialLink.getSocialProvider() +
|
|
||||||
", socialUserId=" + socialLink.getSocialUserId() + ", results=" + results);
|
|
||||||
} else {
|
|
||||||
UserEntity user = results.get(0);
|
|
||||||
return new UserAdapter(realm, em, user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> getUsers(RealmModel realm) {
|
|
||||||
TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm", UserEntity.class);
|
|
||||||
RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
|
|
||||||
query.setParameter("realm", realmEntity);
|
|
||||||
List<UserEntity> results = query.getResultList();
|
|
||||||
List<UserModel> users = new ArrayList<UserModel>();
|
|
||||||
for (UserEntity entity : results) users.add(new UserAdapter(realm, em, entity));
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUser(String search, RealmModel realm) {
|
|
||||||
TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm and ( lower(u.username) like :search or lower(concat(u.firstName, ' ', u.lastName)) like :search or u.email like :search )", UserEntity.class);
|
|
||||||
RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
|
|
||||||
query.setParameter("realm", realmEntity);
|
|
||||||
query.setParameter("search", "%" + search.toLowerCase() + "%");
|
|
||||||
List<UserEntity> results = query.getResultList();
|
|
||||||
List<UserModel> users = new ArrayList<UserModel>();
|
|
||||||
for (UserEntity entity : results) users.add(new UserAdapter(realm, em, entity));
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
|
|
||||||
StringBuilder builder = new StringBuilder("select u from UserEntity u");
|
|
||||||
boolean first = true;
|
|
||||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
|
||||||
String attribute = null;
|
|
||||||
if (entry.getKey().equals(UserModel.LOGIN_NAME)) {
|
|
||||||
attribute = "lower(username)";
|
|
||||||
} else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) {
|
|
||||||
attribute = "lower(firstName)";
|
|
||||||
} else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) {
|
|
||||||
attribute = "lower(lastName)";
|
|
||||||
} else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) {
|
|
||||||
attribute = "lower(email)";
|
|
||||||
}
|
|
||||||
if (attribute == null) continue;
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
builder.append(" where realm = :realm");
|
|
||||||
} else {
|
|
||||||
builder.append(" and ");
|
|
||||||
}
|
|
||||||
builder.append(attribute).append(" like '%").append(entry.getValue().toLowerCase()).append("%'");
|
|
||||||
}
|
|
||||||
String q = builder.toString();
|
|
||||||
TypedQuery<UserEntity> query = em.createQuery(q, UserEntity.class);
|
|
||||||
RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
|
|
||||||
query.setParameter("realm", realmEntity);
|
|
||||||
List<UserEntity> results = query.getResultList();
|
|
||||||
List<UserModel> users = new ArrayList<UserModel>();
|
|
||||||
for (UserEntity entity : results) users.add(new UserAdapter(realm, em, entity));
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SocialLinkEntity findSocialLink(UserModel user, String socialProvider) {
|
|
||||||
TypedQuery<SocialLinkEntity> query = em.createNamedQuery("findSocialLinkByUserAndProvider", SocialLinkEntity.class);
|
|
||||||
UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
|
|
||||||
query.setParameter("user", userEntity);
|
|
||||||
query.setParameter("socialProvider", socialProvider);
|
|
||||||
List<SocialLinkEntity> results = query.getResultList();
|
|
||||||
return results.size() > 0 ? results.get(0) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
|
|
||||||
TypedQuery<SocialLinkEntity> query = em.createNamedQuery("findSocialLinkByUser", SocialLinkEntity.class);
|
|
||||||
UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
|
|
||||||
query.setParameter("user", userEntity);
|
|
||||||
List<SocialLinkEntity> results = query.getResultList();
|
|
||||||
Set<SocialLinkModel> set = new HashSet<SocialLinkModel>();
|
|
||||||
for (SocialLinkEntity entity : results) {
|
|
||||||
set.add(new SocialLinkModel(entity.getSocialProvider(), entity.getSocialUserId(), entity.getSocialUsername()));
|
|
||||||
}
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm) {
|
|
||||||
SocialLinkEntity entity = findSocialLink(user, socialProvider);
|
|
||||||
return (entity != null) ? new SocialLinkModel(entity.getSocialProvider(), entity.getSocialUserId(), entity.getSocialUsername()) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RoleModel getRoleById(String id, RealmModel realm) {
|
|
||||||
RoleEntity entity = em.find(RoleEntity.class, id);
|
|
||||||
if (entity == null) return null;
|
|
||||||
if (!realm.getId().equals(entity.getRealmId())) return null;
|
|
||||||
return new RoleAdapter(realm, em, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApplicationModel getApplicationById(String id, RealmModel realm) {
|
|
||||||
ApplicationEntity app = em.find(ApplicationEntity.class, id);
|
|
||||||
|
|
||||||
// Check if application belongs to this realm
|
|
||||||
if (app == null || !realm.getId().equals(app.getRealm().getId())) return null;
|
|
||||||
return new ApplicationAdapter(realm, em, app);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
|
|
||||||
OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
|
|
||||||
|
|
||||||
// Check if client belongs to this realm
|
|
||||||
if (client == null || !realm.getId().equals(client.getRealm().getId())) return null;
|
|
||||||
return new OAuthClientAdapter(realm, client, em);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
130
model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
Executable file
130
model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
Executable file
|
@ -0,0 +1,130 @@
|
||||||
|
package org.keycloak.models.jpa;
|
||||||
|
|
||||||
|
import org.keycloak.models.ApplicationModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.RealmProvider;
|
||||||
|
import org.keycloak.models.OAuthClientModel;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.jpa.entities.ApplicationEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.OAuthClientEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.RealmEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class JpaRealmProvider implements RealmProvider {
|
||||||
|
private final KeycloakSession session;
|
||||||
|
protected EntityManager em;
|
||||||
|
|
||||||
|
public JpaRealmProvider(KeycloakSession session, EntityManager em) {
|
||||||
|
this.session = session;
|
||||||
|
this.em = em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel createRealm(String name) {
|
||||||
|
return createRealm(KeycloakModelUtils.generateId(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel createRealm(String id, String name) {
|
||||||
|
RealmEntity realm = new RealmEntity();
|
||||||
|
realm.setName(name);
|
||||||
|
realm.setId(id);
|
||||||
|
em.persist(realm);
|
||||||
|
em.flush();
|
||||||
|
return new RealmAdapter(session, em, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel getRealm(String id) {
|
||||||
|
RealmEntity realm = em.find(RealmEntity.class, id);
|
||||||
|
if (realm == null) return null;
|
||||||
|
return new RealmAdapter(session, em, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RealmModel> getRealms() {
|
||||||
|
TypedQuery<RealmEntity> query = em.createNamedQuery("getAllRealms", RealmEntity.class);
|
||||||
|
List<RealmEntity> entities = query.getResultList();
|
||||||
|
List<RealmModel> realms = new ArrayList<RealmModel>();
|
||||||
|
for (RealmEntity entity : entities) {
|
||||||
|
realms.add(new RealmAdapter(session, em, entity));
|
||||||
|
}
|
||||||
|
return realms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel getRealmByName(String name) {
|
||||||
|
TypedQuery<RealmEntity> query = em.createNamedQuery("getRealmByName", RealmEntity.class);
|
||||||
|
query.setParameter("name", name);
|
||||||
|
List<RealmEntity> entities = query.getResultList();
|
||||||
|
if (entities.size() == 0) return null;
|
||||||
|
if (entities.size() > 1) throw new IllegalStateException("Should not be more than one realm with same name");
|
||||||
|
RealmEntity realm = query.getResultList().get(0);
|
||||||
|
if (realm == null) return null;
|
||||||
|
return new RealmAdapter(session, em, realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeRealm(String id) {
|
||||||
|
RealmEntity realm = em.find(RealmEntity.class, id);
|
||||||
|
if (realm == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RealmAdapter adapter = new RealmAdapter(session, em, realm);
|
||||||
|
session.users().preRemove(adapter);
|
||||||
|
for (ApplicationEntity a : new LinkedList<ApplicationEntity>(realm.getApplications())) {
|
||||||
|
adapter.removeApplication(a.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (OAuthClientModel oauth : adapter.getOAuthClients()) {
|
||||||
|
adapter.removeOAuthClient(oauth.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
em.remove(realm);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RoleModel getRoleById(String id, RealmModel realm) {
|
||||||
|
RoleEntity entity = em.find(RoleEntity.class, id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
if (!realm.getId().equals(entity.getRealmId())) return null;
|
||||||
|
return new RoleAdapter(realm, em, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApplicationModel getApplicationById(String id, RealmModel realm) {
|
||||||
|
ApplicationEntity app = em.find(ApplicationEntity.class, id);
|
||||||
|
|
||||||
|
// Check if application belongs to this realm
|
||||||
|
if (app == null || !realm.getId().equals(app.getRealm().getId())) return null;
|
||||||
|
return new ApplicationAdapter(realm, em, session, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
|
||||||
|
OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
|
||||||
|
|
||||||
|
// Check if client belongs to this realm
|
||||||
|
if (client == null || !realm.getId().equals(client.getRealm().getId())) return null;
|
||||||
|
return new OAuthClientAdapter(realm, client, em);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,8 +3,8 @@ package org.keycloak.models.jpa;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.connections.jpa.JpaConnectionProvider;
|
import org.keycloak.connections.jpa.JpaConnectionProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
import org.keycloak.models.ModelProviderFactory;
|
import org.keycloak.models.RealmProviderFactory;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import javax.persistence.EntityManager;
|
||||||
* @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 JpaModelProviderFactory implements ModelProviderFactory {
|
public class JpaRealmProviderFactory implements RealmProviderFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void init(Config.Scope config) {
|
||||||
|
@ -24,9 +24,9 @@ public class JpaModelProviderFactory implements ModelProviderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelProvider create(KeycloakSession session) {
|
public RealmProvider create(KeycloakSession session) {
|
||||||
EntityManager em = session.getProvider(JpaConnectionProvider.class).getEntityManager();
|
EntityManager em = session.getProvider(JpaConnectionProvider.class).getEntityManager();
|
||||||
return new JpaModelProvider(session, em);
|
return new JpaRealmProvider(session, em);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -2,16 +2,11 @@ package org.keycloak.models.jpa;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakTransaction;
|
|
||||||
import org.keycloak.models.ModelProvider;
|
|
||||||
import org.keycloak.models.OAuthClientModel;
|
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.SocialLinkModel;
|
import org.keycloak.models.SocialLinkModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserProvider;
|
import org.keycloak.models.UserProvider;
|
||||||
import org.keycloak.models.jpa.entities.ApplicationEntity;
|
|
||||||
import org.keycloak.models.jpa.entities.OAuthClientEntity;
|
|
||||||
import org.keycloak.models.jpa.entities.RealmEntity;
|
import org.keycloak.models.jpa.entities.RealmEntity;
|
||||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||||
import org.keycloak.models.jpa.entities.SocialLinkEntity;
|
import org.keycloak.models.jpa.entities.SocialLinkEntity;
|
||||||
|
@ -23,7 +18,6 @@ import javax.persistence.EntityManager;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -39,7 +33,6 @@ public class JpaUserProvider implements UserProvider {
|
||||||
public JpaUserProvider(KeycloakSession session, EntityManager em) {
|
public JpaUserProvider(KeycloakSession session, EntityManager em) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.em = em;
|
this.em = em;
|
||||||
this.em = PersistenceExceptionConverter.create(em);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,12 +92,38 @@ public class JpaUserProvider implements UserProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preRemove(RealmModel realm) {
|
public void addSocialLink(RealmModel realm, UserModel user, SocialLinkModel socialLink) {
|
||||||
TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm", UserEntity.class);
|
SocialLinkEntity entity = new SocialLinkEntity();
|
||||||
RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
|
RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
|
||||||
query.setParameter("realm", realmEntity);
|
entity.setRealm(realmEntity);
|
||||||
for (UserEntity u : query.getResultList()) {
|
entity.setSocialProvider(socialLink.getSocialProvider());
|
||||||
em.remove(u);
|
entity.setSocialUserId(socialLink.getSocialUserId());
|
||||||
|
entity.setSocialUsername(socialLink.getSocialUsername());
|
||||||
|
UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
|
||||||
|
entity.setUser(userEntity);
|
||||||
|
em.persist(entity);
|
||||||
|
em.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeSocialLink(RealmModel realm, UserModel user, String socialProvider) {
|
||||||
|
SocialLinkEntity entity = findSocialLink(user, socialProvider);
|
||||||
|
if (entity != null) {
|
||||||
|
em.remove(entity);
|
||||||
|
em.flush();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preRemove(RealmModel realm) {
|
||||||
|
RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
|
||||||
|
for (UserEntity u : em.createQuery("from UserEntity u where u.realm = :realm", UserEntity.class).setParameter("realm", realmEntity).getResultList()) {
|
||||||
|
removeUser(realm, u.getUsername());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,12 +133,6 @@ public class JpaUserProvider implements UserProvider {
|
||||||
em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate();
|
em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public KeycloakTransaction getTransaction() {
|
|
||||||
return new JpaKeycloakTransaction(em);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realmModel) {
|
public UserModel getUserById(String id, RealmModel realmModel) {
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserById", UserEntity.class);
|
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserById", UserEntity.class);
|
||||||
|
@ -154,8 +167,6 @@ public class JpaUserProvider implements UserProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if (em.getTransaction().isActive()) em.getTransaction().rollback();
|
|
||||||
if (em.isOpen()) em.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
36
model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProviderFactory.java
Executable file
36
model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProviderFactory.java
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
package org.keycloak.models.jpa;
|
||||||
|
|
||||||
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.connections.jpa.JpaConnectionProvider;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.UserProvider;
|
||||||
|
import org.keycloak.models.UserProviderFactory;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class JpaUserProviderFactory implements UserProviderFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Config.Scope config) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "jpa";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProvider create(KeycloakSession session) {
|
||||||
|
EntityManager em = session.getProvider(JpaConnectionProvider.class).getEntityManager();
|
||||||
|
return new JpaUserProvider(session, em);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,14 +1,10 @@
|
||||||
package org.keycloak.models.jpa;
|
package org.keycloak.models.jpa;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.jpa.entities.OAuthClientEntity;
|
import org.keycloak.models.jpa.entities.OAuthClientEntity;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
|
3
model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
Normal file → Executable file
3
model/jpa/src/main/java/org/keycloak/models/jpa/PersistenceExceptionConverter.java
Normal file → Executable file
|
@ -1,12 +1,11 @@
|
||||||
package org.keycloak.models.jpa;
|
package org.keycloak.models.jpa;
|
||||||
|
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.keycloak.models.ModelException;
|
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
|
import org.keycloak.models.ModelException;
|
||||||
|
|
||||||
import javax.persistence.EntityExistsException;
|
import javax.persistence.EntityExistsException;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.PersistenceException;
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
|
@ -10,11 +10,9 @@ import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.SocialLinkModel;
|
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserCredentialValueModel;
|
import org.keycloak.models.UserCredentialValueModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UsernameLoginFailureModel;
|
|
||||||
import org.keycloak.models.jpa.entities.ApplicationEntity;
|
import org.keycloak.models.jpa.entities.ApplicationEntity;
|
||||||
import org.keycloak.models.jpa.entities.AuthenticationProviderEntity;
|
import org.keycloak.models.jpa.entities.AuthenticationProviderEntity;
|
||||||
import org.keycloak.models.jpa.entities.OAuthClientEntity;
|
import org.keycloak.models.jpa.entities.OAuthClientEntity;
|
||||||
|
@ -22,9 +20,6 @@ import org.keycloak.models.jpa.entities.RealmEntity;
|
||||||
import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
|
import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
|
||||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||||
import org.keycloak.models.jpa.entities.ScopeMappingEntity;
|
import org.keycloak.models.jpa.entities.ScopeMappingEntity;
|
||||||
import org.keycloak.models.jpa.entities.SocialLinkEntity;
|
|
||||||
import org.keycloak.models.jpa.entities.UserEntity;
|
|
||||||
import org.keycloak.models.jpa.entities.UserRoleMappingEntity;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.models.utils.TimeBasedOTP;
|
import org.keycloak.models.utils.TimeBasedOTP;
|
||||||
|
|
||||||
|
@ -411,75 +406,6 @@ public class RealmAdapter implements RealmModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUser(String name) {
|
|
||||||
return session.model().getUserByUsername(name, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserByEmail(String email) {
|
|
||||||
return session.model().getUserByEmail(email, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserById(String id) {
|
|
||||||
return session.model().getUserById(id, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel addUser(String username) {
|
|
||||||
return this.addUser(KeycloakModelUtils.generateId(), username, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel addUser(String id, String username, boolean addDefaultRoles) {
|
|
||||||
if (id == null) {
|
|
||||||
id = KeycloakModelUtils.generateId();
|
|
||||||
}
|
|
||||||
|
|
||||||
UserEntity entity = new UserEntity();
|
|
||||||
entity.setId(id);
|
|
||||||
entity.setUsername(username);
|
|
||||||
entity.setRealm(realm);
|
|
||||||
em.persist(entity);
|
|
||||||
em.flush();
|
|
||||||
UserModel userModel = new UserAdapter(this, em, entity);
|
|
||||||
|
|
||||||
if (addDefaultRoles) {
|
|
||||||
for (String r : getDefaultRoles()) {
|
|
||||||
userModel.grantRole(getRole(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ApplicationModel application : getApplications()) {
|
|
||||||
for (String r : application.getDefaultRoles()) {
|
|
||||||
userModel.grantRole(application.getRole(r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return userModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeUser(String name) {
|
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByUsername", UserEntity.class);
|
|
||||||
query.setParameter("username", name);
|
|
||||||
query.setParameter("realm", realm);
|
|
||||||
List<UserEntity> results = query.getResultList();
|
|
||||||
if (results.size() == 0) return false;
|
|
||||||
removeUser(results.get(0));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeUser(UserEntity user) {
|
|
||||||
em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
|
|
||||||
em.createQuery("delete from " + SocialLinkEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
|
|
||||||
if (user.getAuthenticationLink() != null) {
|
|
||||||
em.remove(user.getAuthenticationLink());
|
|
||||||
}
|
|
||||||
em.remove(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getDefaultRoles() {
|
public List<String> getDefaultRoles() {
|
||||||
Collection<RoleEntity> entities = realm.getDefaultRoles();
|
Collection<RoleEntity> entities = realm.getDefaultRoles();
|
||||||
|
@ -567,7 +493,7 @@ public class RealmAdapter implements RealmModel {
|
||||||
List<ApplicationModel> list = new ArrayList<ApplicationModel>();
|
List<ApplicationModel> list = new ArrayList<ApplicationModel>();
|
||||||
if (realm.getApplications() == null) return list;
|
if (realm.getApplications() == null) return list;
|
||||||
for (ApplicationEntity entity : realm.getApplications()) {
|
for (ApplicationEntity entity : realm.getApplications()) {
|
||||||
list.add(new ApplicationAdapter(this, em, entity));
|
list.add(new ApplicationAdapter(this, em, session, entity));
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -587,7 +513,7 @@ public class RealmAdapter implements RealmModel {
|
||||||
realm.getApplications().add(applicationData);
|
realm.getApplications().add(applicationData);
|
||||||
em.persist(applicationData);
|
em.persist(applicationData);
|
||||||
em.flush();
|
em.flush();
|
||||||
ApplicationModel resource = new ApplicationAdapter(this, em, applicationData);
|
ApplicationModel resource = new ApplicationAdapter(this, em, session, applicationData);
|
||||||
em.flush();
|
em.flush();
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
@ -628,7 +554,7 @@ public class RealmAdapter implements RealmModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApplicationModel getApplicationById(String id) {
|
public ApplicationModel getApplicationById(String id) {
|
||||||
return session.model().getApplicationById(id, this);
|
return session.realms().getApplicationById(id, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -636,57 +562,6 @@ public class RealmAdapter implements RealmModel {
|
||||||
return getApplicationNameMap().get(name);
|
return getApplicationNameMap().get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
|
|
||||||
return session.model().getUserBySocialLink(socialLink, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<SocialLinkModel> getSocialLinks(UserModel user) {
|
|
||||||
return session.model().getSocialLinks(user, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SocialLinkModel getSocialLink(UserModel user, String socialProvider) {
|
|
||||||
return session.model().getSocialLink(user, socialProvider, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addSocialLink(UserModel user, SocialLinkModel socialLink) {
|
|
||||||
SocialLinkEntity entity = new SocialLinkEntity();
|
|
||||||
entity.setRealm(realm);
|
|
||||||
entity.setSocialProvider(socialLink.getSocialProvider());
|
|
||||||
entity.setSocialUserId(socialLink.getSocialUserId());
|
|
||||||
entity.setSocialUsername(socialLink.getSocialUsername());
|
|
||||||
UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
|
|
||||||
entity.setUser(userEntity);
|
|
||||||
em.persist(entity);
|
|
||||||
em.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
private SocialLinkEntity findSocialLink(UserModel user, String socialProvider) {
|
|
||||||
TypedQuery<SocialLinkEntity> query = em.createNamedQuery("findSocialLinkByUserAndProvider", SocialLinkEntity.class);
|
|
||||||
UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
|
|
||||||
query.setParameter("user", userEntity);
|
|
||||||
query.setParameter("socialProvider", socialProvider);
|
|
||||||
List<SocialLinkEntity> results = query.getResultList();
|
|
||||||
return results.size() > 0 ? results.get(0) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeSocialLink(UserModel user, String socialProvider) {
|
|
||||||
SocialLinkEntity entity = findSocialLink(user, socialProvider);
|
|
||||||
if (entity != null) {
|
|
||||||
em.remove(entity);
|
|
||||||
em.flush();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSocial() {
|
public boolean isSocial() {
|
||||||
return realm.isSocial();
|
return realm.isSocial();
|
||||||
|
@ -709,21 +584,6 @@ public class RealmAdapter implements RealmModel {
|
||||||
em.flush();
|
em.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> getUsers() {
|
|
||||||
return session.model().getUsers(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUser(String search) {
|
|
||||||
return session.model().searchForUser(search, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
|
|
||||||
return session.model().searchForUserByAttributes(attributes, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OAuthClientModel addOAuthClient(String name) {
|
public OAuthClientModel addOAuthClient(String name) {
|
||||||
return this.addOAuthClient(KeycloakModelUtils.generateId(), name);
|
return this.addOAuthClient(KeycloakModelUtils.generateId(), name);
|
||||||
|
@ -764,7 +624,7 @@ public class RealmAdapter implements RealmModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OAuthClientModel getOAuthClientById(String id) {
|
public OAuthClientModel getOAuthClientById(String id) {
|
||||||
return session.model().getOAuthClientById(id, this);
|
return session.realms().getOAuthClientById(id, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -899,13 +759,12 @@ public class RealmAdapter implements RealmModel {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!role.getContainer().equals(this)) return false;
|
if (!role.getContainer().equals(this)) return false;
|
||||||
|
session.users().preRemove(role);
|
||||||
RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
|
RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
|
||||||
realm.getRoles().remove(role);
|
realm.getRoles().remove(role);
|
||||||
realm.getDefaultRoles().remove(role);
|
realm.getDefaultRoles().remove(role);
|
||||||
|
|
||||||
em.createNativeQuery("delete from CompositeRole where childRole = :role").setParameter("role", roleEntity).executeUpdate();
|
em.createNativeQuery("delete from CompositeRole where childRole = :role").setParameter("role", roleEntity).executeUpdate();
|
||||||
em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate();
|
|
||||||
em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate();
|
em.createQuery("delete from " + ScopeMappingEntity.class.getSimpleName() + " where role = :role").setParameter("role", roleEntity).executeUpdate();
|
||||||
|
|
||||||
em.remove(roleEntity);
|
em.remove(roleEntity);
|
||||||
|
@ -926,7 +785,7 @@ public class RealmAdapter implements RealmModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RoleModel getRoleById(String id) {
|
public RoleModel getRoleById(String id) {
|
||||||
return session.model().getRoleById(id, this);
|
return session.realms().getRoleById(id, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1060,7 +919,7 @@ public class RealmAdapter implements RealmModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApplicationModel getMasterAdminApp() {
|
public ApplicationModel getMasterAdminApp() {
|
||||||
return new ApplicationAdapter(this, em, realm.getMasterAdminApp());
|
return new ApplicationAdapter(this, em, session, realm.getMasterAdminApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.keycloak.models.jpa;
|
||||||
|
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.AuthenticationLinkModel;
|
import org.keycloak.models.AuthenticationLinkModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleContainerModel;
|
import org.keycloak.models.RoleContainerModel;
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
|
||||||
|
|
||||||
import javax.persistence.FetchType;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.MappedSuperclass;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
@MappedSuperclass
|
|
||||||
public class AbstractRoleMappingEntity {
|
|
||||||
@Id
|
|
||||||
@GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator")
|
|
||||||
@GeneratedValue(generator = "keycloak_generator")
|
|
||||||
protected String id;
|
|
||||||
@ManyToOne(fetch= FetchType.LAZY)
|
|
||||||
protected UserEntity user;
|
|
||||||
|
|
||||||
@ManyToOne(fetch= FetchType.LAZY)
|
|
||||||
@JoinColumn(name="roleId")
|
|
||||||
protected RoleEntity role;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserEntity getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUser(UserEntity user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RoleEntity getRole() {
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRole(RoleEntity role) {
|
|
||||||
this.role = role;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +1,12 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.CollectionTable;
|
|
||||||
import javax.persistence.ElementCollection;
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.JoinTable;
|
import javax.persistence.JoinTable;
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.persistence.UniqueConstraint;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
|
8
model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java
Normal file → Executable file
8
model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationLinkEntity.java
Normal file → Executable file
|
@ -1,14 +1,10 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.NamedQueries;
|
|
||||||
import javax.persistence.NamedQuery;
|
|
||||||
import javax.persistence.OneToOne;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
|
5
model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java
Normal file → Executable file
5
model/jpa/src/main/java/org/keycloak/models/jpa/entities/AuthenticationProviderEntity.java
Normal file → Executable file
|
@ -1,6 +1,6 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
import java.util.Map;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import javax.persistence.CollectionTable;
|
import javax.persistence.CollectionTable;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
|
@ -11,8 +11,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.MapKeyColumn;
|
import javax.persistence.MapKeyColumn;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import java.util.Map;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
|
|
@ -1,20 +1,15 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.CollectionTable;
|
import javax.persistence.CollectionTable;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.ElementCollection;
|
import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Inheritance;
|
import javax.persistence.Inheritance;
|
||||||
import javax.persistence.InheritanceType;
|
import javax.persistence.InheritanceType;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.UniqueConstraint;
|
import javax.persistence.UniqueConstraint;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
|
@ -8,8 +10,6 @@ import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 $
|
||||||
|
@ -33,6 +33,9 @@ public class CredentialEntity {
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
protected UserEntity user;
|
protected UserEntity user;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
protected RealmEntity realm;
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 $
|
||||||
|
|
|
@ -3,10 +3,7 @@ package org.keycloak.models.jpa.entities;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Inheritance;
|
|
||||||
import javax.persistence.InheritanceType;
|
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.JoinTable;
|
import javax.persistence.JoinTable;
|
||||||
import javax.persistence.ManyToMany;
|
import javax.persistence.ManyToMany;
|
||||||
|
@ -18,8 +15,6 @@ import javax.persistence.UniqueConstraint;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 $
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
|
@ -8,8 +10,6 @@ import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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 $
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
@ -10,7 +9,6 @@ import javax.persistence.Column;
|
||||||
import javax.persistence.ElementCollection;
|
import javax.persistence.ElementCollection;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
|
@ -21,7 +19,6 @@ import javax.persistence.OneToMany;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.UniqueConstraint;
|
import javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
package org.keycloak.models.jpa.entities;
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
|
|
||||||
|
@ -14,6 +21,40 @@ import javax.persistence.NamedQuery;
|
||||||
@NamedQuery(name="userRoleMappingIds", query="select m.role.id from UserRoleMappingEntity m where m.user = :user")
|
@NamedQuery(name="userRoleMappingIds", query="select m.role.id from UserRoleMappingEntity m where m.user = :user")
|
||||||
})
|
})
|
||||||
@Entity
|
@Entity
|
||||||
public class UserRoleMappingEntity extends AbstractRoleMappingEntity {
|
public class UserRoleMappingEntity {
|
||||||
|
@Id
|
||||||
|
@GenericGenerator(name="keycloak_generator", strategy="org.keycloak.models.jpa.utils.JpaIdGenerator")
|
||||||
|
@GeneratedValue(generator = "keycloak_generator")
|
||||||
|
protected String id;
|
||||||
|
@ManyToOne(fetch= FetchType.LAZY)
|
||||||
|
protected UserEntity user;
|
||||||
|
|
||||||
|
@ManyToOne(fetch= FetchType.LAZY)
|
||||||
|
@JoinColumn(name="roleId")
|
||||||
|
protected RoleEntity role;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserEntity getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(UserEntity user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoleEntity getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRole(RoleEntity role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
4
model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java
Normal file → Executable file
4
model/jpa/src/main/java/org/keycloak/models/jpa/utils/JpaIdGenerator.java
Normal file → Executable file
|
@ -1,12 +1,12 @@
|
||||||
package org.keycloak.models.jpa.utils;
|
package org.keycloak.models.jpa.utils;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
org.keycloak.models.jpa.JpaModelProviderFactory
|
|
|
@ -0,0 +1 @@
|
||||||
|
org.keycloak.models.jpa.JpaRealmProviderFactory
|
|
@ -0,0 +1 @@
|
||||||
|
org.keycloak.models.jpa.JpaUserProviderFactory
|
|
@ -2,12 +2,12 @@ package org.keycloak.models.mongo.keycloak.adapters;
|
||||||
|
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
import com.mongodb.QueryBuilder;
|
import com.mongodb.QueryBuilder;
|
||||||
|
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
|
||||||
import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
|
import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
|
||||||
import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
|
import org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity;
|
||||||
import org.keycloak.models.mongo.utils.MongoModelUtils;
|
import org.keycloak.models.mongo.utils.MongoModelUtils;
|
||||||
|
@ -141,6 +141,7 @@ public class ApplicationAdapter extends ClientAdapter<MongoApplicationEntity> im
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeRole(RoleModel role) {
|
public boolean removeRole(RoleModel role) {
|
||||||
|
session.users().preRemove(role);
|
||||||
return getMongoStore().removeEntity(MongoRoleEntity.class, role.getId(), invocationContext);
|
return getMongoStore().removeEntity(MongoRoleEntity.class, role.getId(), invocationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue