KEYCLOAK-361 it shouldn't be possible to remove last social link if user don't have password

This commit is contained in:
mposolda 2014-05-07 15:02:57 +02:00
parent d523242dbb
commit 6b1e0401ba
6 changed files with 34 additions and 7 deletions

View file

@ -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;

View file

@ -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

View file

@ -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>

View file

@ -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";

View file

@ -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);
}

View file

@ -173,6 +173,10 @@
<artifactId>keycloak-social-twitter</artifactId>
<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>