keycloak-aplcache

Changes

forms/email-freemarker/src/main/resources/META-INF/services/org.keycloak.email.EmailProviderFactory 1(+0 -1)

Details

diff --git a/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java
index 400ef04..9e1e127 100755
--- a/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java
+++ b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java
@@ -2,7 +2,7 @@ package org.keycloak.events.email;
 
 import org.jboss.logging.Logger;
 import org.keycloak.email.EmailException;
-import org.keycloak.email.EmailProvider;
+import org.keycloak.email.EmailTemplateProvider;
 import org.keycloak.events.admin.AdminEvent;
 import org.keycloak.events.Event;
 import org.keycloak.events.EventListenerProvider;
@@ -23,13 +23,13 @@ public class EmailEventListenerProvider implements EventListenerProvider {
 
     private KeycloakSession session;
     private RealmProvider model;
-    private EmailProvider emailProvider;
+    private EmailTemplateProvider emailTemplateProvider;
     private Set<EventType> includedEvents;
 
-    public EmailEventListenerProvider(KeycloakSession session, EmailProvider emailProvider, Set<EventType> includedEvents) {
+    public EmailEventListenerProvider(KeycloakSession session, EmailTemplateProvider emailTemplateProvider, Set<EventType> includedEvents) {
         this.session = session;
         this.model = session.realms();
-        this.emailProvider = emailProvider;
+        this.emailTemplateProvider = emailTemplateProvider;
         this.includedEvents = includedEvents;
     }
 
@@ -41,7 +41,7 @@ public class EmailEventListenerProvider implements EventListenerProvider {
                 UserModel user = session.users().getUserById(event.getUserId(), realm);
                 if (user != null && user.getEmail() != null && user.isEmailVerified()) {
                     try {
-                        emailProvider.setRealm(realm).setUser(user).sendEvent(event);
+                        emailTemplateProvider.setRealm(realm).setUser(user).sendEvent(event);
                     } catch (EmailException e) {
                         log.error("Failed to send type mail", e);
                     }
diff --git a/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProviderFactory.java b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProviderFactory.java
index 9f662dc..ae2c4d0 100755
--- a/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProviderFactory.java
+++ b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProviderFactory.java
@@ -1,7 +1,7 @@
 package org.keycloak.events.email;
 
 import org.keycloak.Config;
-import org.keycloak.email.EmailProvider;
+import org.keycloak.email.EmailTemplateProvider;
 import org.keycloak.events.EventListenerProvider;
 import org.keycloak.events.EventListenerProviderFactory;
 import org.keycloak.events.EventType;
@@ -26,8 +26,8 @@ public class EmailEventListenerProviderFactory implements EventListenerProviderF
 
     @Override
     public EventListenerProvider create(KeycloakSession session) {
-        EmailProvider emailProvider = session.getProvider(EmailProvider.class);
-        return new EmailEventListenerProvider(session, emailProvider, includedEvents);
+        EmailTemplateProvider emailTemplateProvider = session.getProvider(EmailTemplateProvider.class);
+        return new EmailEventListenerProvider(session, emailTemplateProvider, includedEvents);
     }
 
     @Override
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
index a6945f3..b2c7848 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
@@ -1195,7 +1195,7 @@ module.controller('RealmSMTPSettingsCtrl', function($scope, Current, Realm, real
             }
         }
 
-        obj['port'] = obj['port'].toString();
+        obj['port'] = obj['port'] && obj['port'].toString();
 
         return obj;
     }
diff --git a/forms/email-api/src/main/java/org/keycloak/email/EmailSenderProvider.java b/forms/email-api/src/main/java/org/keycloak/email/EmailSenderProvider.java
new file mode 100755
index 0000000..95ccabe
--- /dev/null
+++ b/forms/email-api/src/main/java/org/keycloak/email/EmailSenderProvider.java
@@ -0,0 +1,14 @@
+package org.keycloak.email;
+
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.provider.Provider;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public interface EmailSenderProvider extends Provider {
+
+    void send(RealmModel realm, UserModel user, String subject, String textBody, String htmlBody) throws EmailException;
+
+}
diff --git a/forms/email-api/src/main/java/org/keycloak/email/EmailTemplateProviderFactory.java b/forms/email-api/src/main/java/org/keycloak/email/EmailTemplateProviderFactory.java
new file mode 100644
index 0000000..bc934cb
--- /dev/null
+++ b/forms/email-api/src/main/java/org/keycloak/email/EmailTemplateProviderFactory.java
@@ -0,0 +1,9 @@
+package org.keycloak.email;
+
+import org.keycloak.provider.ProviderFactory;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public interface EmailTemplateProviderFactory extends ProviderFactory<EmailTemplateProvider> {
+}
diff --git a/forms/email-api/src/main/java/org/keycloak/email/EmailTemplateSpi.java b/forms/email-api/src/main/java/org/keycloak/email/EmailTemplateSpi.java
new file mode 100644
index 0000000..c84c87c
--- /dev/null
+++ b/forms/email-api/src/main/java/org/keycloak/email/EmailTemplateSpi.java
@@ -0,0 +1,31 @@
+package org.keycloak.email;
+
+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 EmailTemplateSpi implements Spi {
+
+    @Override
+    public boolean isInternal() {
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return "emailTemplate";
+    }
+
+    @Override
+    public Class<? extends Provider> getProviderClass() {
+        return EmailTemplateProvider.class;
+    }
+
+    @Override
+    public Class<? extends ProviderFactory> getProviderFactoryClass() {
+        return org.keycloak.email.EmailTemplateProviderFactory.class;
+    }
+}
diff --git a/forms/email-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/forms/email-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index 4110dba..80967a2 100644
--- a/forms/email-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/forms/email-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -1 +1,2 @@
-org.keycloak.email.EmailSpi
\ No newline at end of file
+org.keycloak.email.EmailSenderSpi
+org.keycloak.email.EmailTemplateSpi
\ No newline at end of file
diff --git a/forms/email-freemarker/src/main/resources/META-INF/services/org.keycloak.email.EmailTemplateProviderFactory b/forms/email-freemarker/src/main/resources/META-INF/services/org.keycloak.email.EmailTemplateProviderFactory
new file mode 100644
index 0000000..aa87e53
--- /dev/null
+++ b/forms/email-freemarker/src/main/resources/META-INF/services/org.keycloak.email.EmailTemplateProviderFactory
@@ -0,0 +1 @@
+org.keycloak.email.freemarker.FreeMarkerEmailTemplateProviderFactory
\ No newline at end of file
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
index d1b4df9..1cbd328 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
@@ -24,7 +24,7 @@ import org.keycloak.authentication.requiredactions.util.UserUpdateProfileContext
 import org.keycloak.broker.provider.BrokeredIdentityContext;
 import org.keycloak.common.util.ObjectUtil;
 import org.keycloak.email.EmailException;
-import org.keycloak.email.EmailProvider;
+import org.keycloak.email.EmailTemplateProvider;
 import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
 import org.keycloak.freemarker.FreeMarkerException;
 import org.keycloak.freemarker.FreeMarkerUtil;
@@ -153,7 +153,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
                     String link = builder.build(realm.getName()).toString();
                     long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction());
 
-                    session.getProvider(EmailProvider.class).setRealm(realm).setUser(user).sendVerifyEmail(link, expiration);
+                    session.getProvider(EmailTemplateProvider.class).setRealm(realm).setUser(user).sendVerifyEmail(link, expiration);
                 } catch (EmailException e) {
                     logger.error("Failed to send verification email", e);
                     return setError(Messages.EMAIL_SENT_ERROR).createErrorPage();
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/broker/IdpEmailVerificationAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/broker/IdpEmailVerificationAuthenticator.java
index ae28d3e..9780d6a 100644
--- a/services/src/main/java/org/keycloak/authentication/authenticators/broker/IdpEmailVerificationAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/broker/IdpEmailVerificationAuthenticator.java
@@ -13,7 +13,7 @@ import org.keycloak.authentication.requiredactions.VerifyEmail;
 import org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext;
 import org.keycloak.broker.provider.BrokeredIdentityContext;
 import org.keycloak.email.EmailException;
-import org.keycloak.email.EmailProvider;
+import org.keycloak.email.EmailTemplateProvider;
 import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
@@ -68,10 +68,10 @@ public class IdpEmailVerificationAuthenticator extends AbstractIdpAuthenticator 
         long expiration = TimeUnit.SECONDS.toMinutes(context.getRealm().getAccessCodeLifespanUserAction());
         try {
 
-            context.getSession().getProvider(EmailProvider.class)
+            context.getSession().getProvider(EmailTemplateProvider.class)
                     .setRealm(realm)
                     .setUser(existingUser)
-                    .setAttribute(EmailProvider.IDENTITY_PROVIDER_BROKER_CONTEXT, brokerContext)
+                    .setAttribute(EmailTemplateProvider.IDENTITY_PROVIDER_BROKER_CONTEXT, brokerContext)
                     .sendConfirmIdentityBrokerLink(link, expiration);
 
             event.success();
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialChooseUser.java b/services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialChooseUser.java
index a3538aa..e48d194 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialChooseUser.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialChooseUser.java
@@ -8,29 +8,20 @@ import org.keycloak.authentication.Authenticator;
 import org.keycloak.authentication.AuthenticatorFactory;
 import org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator;
 import org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator;
-import org.keycloak.email.EmailException;
-import org.keycloak.email.EmailProvider;
 import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
-import org.keycloak.login.LoginFormsProvider;
 import org.keycloak.models.AuthenticationExecutionModel;
-import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.provider.ProviderConfigProperty;
-import org.keycloak.services.Urls;
 import org.keycloak.services.messages.Messages;
 
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
 import java.util.List;
-import java.util.concurrent.TimeUnit;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialEmail.java b/services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialEmail.java
index 678aac2..a66126d 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialEmail.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialEmail.java
@@ -8,7 +8,7 @@ import org.keycloak.authentication.Authenticator;
 import org.keycloak.authentication.AuthenticatorFactory;
 import org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator;
 import org.keycloak.email.EmailException;
-import org.keycloak.email.EmailProvider;
+import org.keycloak.email.EmailTemplateProvider;
 import org.keycloak.events.Details;
 import org.keycloak.events.Errors;
 import org.keycloak.events.EventBuilder;
@@ -72,7 +72,7 @@ public class ResetCredentialEmail implements Authenticator, AuthenticatorFactory
         long expiration = TimeUnit.SECONDS.toMinutes(context.getRealm().getAccessCodeLifespanUserAction());
         try {
 
-            context.getSession().getProvider(EmailProvider.class).setRealm(context.getRealm()).setUser(user).sendPasswordReset(link, expiration);
+            context.getSession().getProvider(EmailTemplateProvider.class).setRealm(context.getRealm()).setUser(user).sendPasswordReset(link, expiration);
             event.clone().event(EventType.SEND_RESET_PASSWORD)
                          .user(user)
                          .detail(Details.USERNAME, username)
diff --git a/services/src/main/java/org/keycloak/email/DefaultEmailSenderProvider.java b/services/src/main/java/org/keycloak/email/DefaultEmailSenderProvider.java
new file mode 100644
index 0000000..1a06877
--- /dev/null
+++ b/services/src/main/java/org/keycloak/email/DefaultEmailSenderProvider.java
@@ -0,0 +1,102 @@
+package org.keycloak.email;
+
+import org.jboss.logging.Logger;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+
+import javax.mail.Message;
+import javax.mail.Multipart;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import java.util.Date;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class DefaultEmailSenderProvider implements EmailSenderProvider {
+
+    private static final Logger log = Logger.getLogger(DefaultEmailSenderProvider.class);
+
+    @Override
+    public void send(RealmModel realm, UserModel user, String subject, String textBody, String htmlBody) throws EmailException {
+        try {
+            String address = user.getEmail();
+            Map<String, String> config = realm.getSmtpConfig();
+
+            Properties props = new Properties();
+            props.setProperty("mail.smtp.host", config.get("host"));
+
+            boolean auth = "true".equals(config.get("auth"));
+            boolean ssl = "true".equals(config.get("ssl"));
+            boolean starttls = "true".equals(config.get("starttls"));
+
+            if (config.containsKey("port")) {
+                props.setProperty("mail.smtp.port", config.get("port"));
+            }
+
+            if (auth) {
+                props.setProperty("mail.smtp.auth", "true");
+            }
+
+            if (ssl) {
+                props.setProperty("mail.smtp.ssl.enable", "true");
+            }
+
+            if (starttls) {
+                props.setProperty("mail.smtp.starttls.enable", "true");
+            }
+
+            props.setProperty("mail.smtp.timeout", "10000");
+            props.setProperty("mail.smtp.connectiontimeout", "10000");
+
+            String from = config.get("from");
+
+            Session session = Session.getInstance(props);
+
+            Multipart multipart = new MimeMultipart("alternative");
+
+            if(textBody != null) {
+                MimeBodyPart textPart = new MimeBodyPart();
+                textPart.setText(textBody, "UTF-8");
+                multipart.addBodyPart(textPart);
+            }
+
+            if(htmlBody != null) {
+                MimeBodyPart htmlPart = new MimeBodyPart();
+                htmlPart.setContent(htmlBody, "text/html; charset=UTF-8");
+                multipart.addBodyPart(htmlPart);
+            }
+
+            Message msg = new MimeMessage(session);
+            msg.setFrom(new InternetAddress(from));
+            msg.setHeader("To", address);
+            msg.setSubject(subject);
+            msg.setContent(multipart);
+            msg.saveChanges();
+            msg.setSentDate(new Date());
+
+            Transport transport = session.getTransport("smtp");
+            if (auth) {
+                transport.connect(config.get("user"), config.get("password"));
+            } else {
+                transport.connect();
+            }
+            transport.sendMessage(msg, new InternetAddress[]{new InternetAddress(address)});
+        } catch (Exception e) {
+            log.error("Failed to send email", e);
+            throw new EmailException(e);
+        }
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+}
diff --git a/services/src/main/java/org/keycloak/email/DefaultEmailSenderProviderFactory.java b/services/src/main/java/org/keycloak/email/DefaultEmailSenderProviderFactory.java
new file mode 100644
index 0000000..9677000
--- /dev/null
+++ b/services/src/main/java/org/keycloak/email/DefaultEmailSenderProviderFactory.java
@@ -0,0 +1,34 @@
+package org.keycloak.email;
+
+import org.keycloak.Config;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class DefaultEmailSenderProviderFactory implements EmailSenderProviderFactory {
+
+    @Override
+    public EmailSenderProvider create(KeycloakSession session) {
+        return new DefaultEmailSenderProvider();
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+    }
+
+    @Override
+    public void postInit(KeycloakSessionFactory factory) {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public String getId() {
+        return "default";
+    }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
index 4423c54..dfd2119 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java
@@ -2,61 +2,37 @@ package org.keycloak.services.resources.admin;
 
 import org.jboss.logging.Logger;
 import org.jboss.resteasy.annotations.cache.NoCache;
-import org.jboss.resteasy.spi.BadRequestException;
 import org.jboss.resteasy.spi.NotFoundException;
 import org.keycloak.common.ClientConnection;
-import org.keycloak.email.EmailException;
-import org.keycloak.email.EmailProvider;
 import org.keycloak.events.admin.OperationType;
 import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientSessionModel;
-import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ModelReadOnlyException;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleMapperModel;
 import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.utils.ModelToRepresentation;
-import org.keycloak.models.utils.RepresentationToModel;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.TokenManager;
-import org.keycloak.protocol.oidc.utils.RedirectUtils;
 import org.keycloak.representations.idm.ClientMappingsRepresentation;
-import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.MappingsRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.services.ErrorResponse;
-import org.keycloak.services.Urls;
 import org.keycloak.services.managers.BruteForceProtector;
-import org.keycloak.services.managers.ClientSessionCode;
 import org.keycloak.services.managers.RealmManager;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Base resource for managing users
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
index 2028610..901de1f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java
@@ -8,7 +8,7 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.common.ClientConnection;
 import org.keycloak.authentication.RequiredActionProvider;
 import org.keycloak.email.EmailException;
-import org.keycloak.email.EmailProvider;
+import org.keycloak.email.EmailTemplateProvider;
 import org.keycloak.events.Details;
 import org.keycloak.events.EventBuilder;
 import org.keycloak.events.EventType;
@@ -23,7 +23,6 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.ModelReadOnlyException;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserConsentModel;
 import org.keycloak.models.UserCredentialModel;
 import org.keycloak.models.UserModel;
@@ -34,18 +33,14 @@ import org.keycloak.protocol.oidc.OIDCLoginProtocol;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.protocol.oidc.utils.RedirectUtils;
 import org.keycloak.provider.ProviderFactory;
-import org.keycloak.representations.idm.ClientMappingsRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.FederatedIdentityRepresentation;
 import org.keycloak.representations.idm.GroupRepresentation;
-import org.keycloak.representations.idm.MappingsRepresentation;
-import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.UserConsentRepresentation;
 import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.representations.idm.UserSessionRepresentation;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.ClientSessionCode;
-import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.UserManager;
 import org.keycloak.services.ErrorResponse;
 import org.keycloak.services.Urls;
@@ -804,7 +799,7 @@ public class UsersResource {
             String link = builder.build(realm.getName()).toString();
             long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction());
 
-            this.session.getProvider(EmailProvider.class).setRealm(realm).setUser(user).sendExecuteActions(link, expiration);
+            this.session.getProvider(EmailTemplateProvider.class).setRealm(realm).setUser(user).sendExecuteActions(link, expiration);
 
             //audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, accessCode.getCodeId()).success();
 
@@ -856,7 +851,7 @@ public class UsersResource {
             String link = builder.build(realm.getName()).toString();
             long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction());
 
-            this.session.getProvider(EmailProvider.class).setRealm(realm).setUser(user).sendVerifyEmail(link, expiration);
+            this.session.getProvider(EmailTemplateProvider.class).setRealm(realm).setUser(user).sendVerifyEmail(link, expiration);
 
             //audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, accessCode.getCodeId()).success();
 
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.email.EmailSenderProviderFactory b/services/src/main/resources/META-INF/services/org.keycloak.email.EmailSenderProviderFactory
new file mode 100644
index 0000000..42c5890
--- /dev/null
+++ b/services/src/main/resources/META-INF/services/org.keycloak.email.EmailSenderProviderFactory
@@ -0,0 +1 @@
+org.keycloak.email.DefaultEmailSenderProviderFactory
\ No newline at end of file