keycloak-memoizeit
Changes
forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java 12(+12 -0)
testsuite/integration/pom.xml 4(+4 -0)
Details
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java
index 2fbe8c6..481f1d9 100644
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java
@@ -21,6 +21,7 @@ import org.keycloak.social.SocialProvider;
public class AccountSocialBean {
private final List<SocialLinkEntry> socialLinks;
+ private final boolean removeLinkPossible;
public AccountSocialBean(RealmModel realm, UserModel user, URI baseUri) {
URI accountSocialUpdateUri = Urls.accountSocialUpdate(baseUri, realm.getName());
@@ -29,12 +30,16 @@ public class AccountSocialBean {
Map<String, String> socialConfig = realm.getSocialConfig();
Set<SocialLinkModel> userSocialLinks = realm.getSocialLinks(user);
+ int availableLinks = 0;
if (socialConfig != null && !socialConfig.isEmpty()) {
for (SocialProvider provider : SocialLoader.load()) {
String socialProviderId = provider.getId();
if (socialConfig.containsKey(socialProviderId + ".key")) {
SocialLinkModel socialLink = getSocialLink(userSocialLinks, socialProviderId);
+ if (socialLink != null) {
+ availableLinks++;
+ }
String action = socialLink != null ? "remove" : "add";
String actionUrl = UriBuilder.fromUri(accountSocialUpdateUri).queryParam("action", action).queryParam("provider_id", socialProviderId).build().toString();
@@ -43,6 +48,9 @@ public class AccountSocialBean {
}
}
}
+
+ // Removing last social provider is not possible if you don't have other possibility to authenticate
+ this.removeLinkPossible = availableLinks > 1 || realm.getAuthenticationLink(user) != null;
}
private SocialLinkModel getSocialLink(Set<SocialLinkModel> userSocialLinks, String socialProviderId) {
@@ -58,6 +66,10 @@ public class AccountSocialBean {
return socialLinks;
}
+ public boolean isRemoveLinkPossible() {
+ return removeLinkPossible;
+ }
+
public class SocialLinkEntry {
private SocialLinkModel link;
diff --git a/forms/common-themes/src/main/resources/theme/account/base/messages/messages.properties b/forms/common-themes/src/main/resources/theme/account/base/messages/messages.properties
index 1945c64..152f61c 100755
--- a/forms/common-themes/src/main/resources/theme/account/base/messages/messages.properties
+++ b/forms/common-themes/src/main/resources/theme/account/base/messages/messages.properties
@@ -30,6 +30,7 @@ missingSocialProvider=Social provider not specified
invalidSocialAction=Invalid or missing action
socialProviderNotFound=Specified social provider not found
socialLinkNotActive=This social link is not active anymore
+socialRemovingLastProvider=You can't remove last social provider as you don't have password
socialRedirectError=Failed to redirect to social provider
socialProviderRemoved=Social provider removed successfully
diff --git a/forms/common-themes/src/main/resources/theme/account/base/social.ftl b/forms/common-themes/src/main/resources/theme/account/base/social.ftl
index e238248..2bba805 100644
--- a/forms/common-themes/src/main/resources/theme/account/base/social.ftl
+++ b/forms/common-themes/src/main/resources/theme/account/base/social.ftl
@@ -18,7 +18,9 @@
</div>
<div class="col-sm-5 col-md-5">
<#if socialLink.connected>
- <a href="${socialLink.actionUrl}" type="submit" class="btn btn-primary btn-lg">Remove ${socialLink.providerName!}</a>
+ <#if social.removeLinkPossible>
+ <a href="${socialLink.actionUrl}" type="submit" class="btn btn-primary btn-lg">Remove ${socialLink.providerName!}</a>
+ </#if>
<#else>
<a href="${socialLink.actionUrl}" type="submit" class="btn btn-primary btn-lg">Add ${socialLink.providerName!}</a>
</#if>
diff --git a/services/src/main/java/org/keycloak/services/messages/Messages.java b/services/src/main/java/org/keycloak/services/messages/Messages.java
index cc0ab1d..01c6f80 100755
--- a/services/src/main/java/org/keycloak/services/messages/Messages.java
+++ b/services/src/main/java/org/keycloak/services/messages/Messages.java
@@ -71,6 +71,8 @@ public class Messages {
public static final String SOCIAL_LINK_NOT_ACTIVE = "socialLinkNotActive";
+ public static final String SOCIAL_REMOVING_LAST_PROVIDER = "socialRemovingLastProvider";
+
public static final String SOCIAL_REDIRECT_ERROR = "socialRedirectError";
public static final String SOCIAL_PROVIDER_REMOVED = "socialProviderRemoved";
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 1a45b6c..3666600 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -422,15 +422,21 @@ public class AccountService {
case REMOVE:
SocialLinkModel link = realm.getSocialLink(user, providerId);
if (link != null) {
- realm.removeSocialLink(user, providerId);
- logger.debug("Social provider " + providerId + " removed successfully from user " + user.getLoginName());
+ // Removing last social provider is not possible if you don't have other possibility to authenticate
+ if (realm.getSocialLinks(user).size() > 1 || realm.getAuthenticationLink(user) != null) {
+ realm.removeSocialLink(user, providerId);
- audit.event(Events.REMOVE_SOCIAL_LINK).client(auth.getClient()).user(auth.getUser())
- .detail(Details.USERNAME, link.getSocialUserId() + "@" + link.getSocialProvider())
- .success();
+ logger.debug("Social provider " + providerId + " removed successfully from user " + user.getLoginName());
- return account.setSuccess(Messages.SOCIAL_PROVIDER_REMOVED).createResponse(AccountPages.SOCIAL);
+ audit.event(Events.REMOVE_SOCIAL_LINK).client(auth.getClient()).user(auth.getUser())
+ .detail(Details.USERNAME, link.getSocialUserId() + "@" + link.getSocialProvider())
+ .success();
+
+ return account.setSuccess(Messages.SOCIAL_PROVIDER_REMOVED).createResponse(AccountPages.SOCIAL);
+ } else {
+ return account.setError(Messages.SOCIAL_REMOVING_LAST_PROVIDER).createResponse(AccountPages.SOCIAL);
+ }
} else {
return account.setError(Messages.SOCIAL_LINK_NOT_ACTIVE).createResponse(AccountPages.SOCIAL);
}
testsuite/integration/pom.xml 4(+4 -0)
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
index b0be76b..74c30bb 100755
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -174,6 +174,10 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.twitter4j</groupId>
+ <artifactId>twitter4j-core</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-social-facebook</artifactId>
<version>${project.version}</version>