KEYCLOAK-361 it shouldn't be possible to remove last social link if user don't have password
This commit is contained in:
parent
d523242dbb
commit
6b1e0401ba
6 changed files with 34 additions and 7 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue