keycloak-uncached
Changes
examples/test-cordova.json 27(+27 -0)
forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/AccountSocialBean.java 28(+15 -13)
keycloak.json 8(+8 -0)
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/SocialLinkEntity.java 16(+13 -3)
model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java 12(+6 -6)
Details
diff --git a/core/src/main/java/org/keycloak/representations/idm/SocialLinkRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/SocialLinkRepresentation.java
index a6e1838..8203261 100644
--- a/core/src/main/java/org/keycloak/representations/idm/SocialLinkRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/SocialLinkRepresentation.java
@@ -6,6 +6,7 @@ package org.keycloak.representations.idm;
public class SocialLinkRepresentation {
protected String socialProvider;
+ protected String socialUserId;
protected String socialUsername;
public String getSocialProvider() {
@@ -16,6 +17,14 @@ public class SocialLinkRepresentation {
this.socialProvider = socialProvider;
}
+ public String getSocialUserId() {
+ return socialUserId;
+ }
+
+ public void setSocialUserId(String socialUserId) {
+ this.socialUserId = socialUserId;
+ }
+
public String getSocialUsername() {
return socialUsername;
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/SocialMappingRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/SocialMappingRepresentation.java
index 57dd874..c4d852c 100644
--- a/core/src/main/java/org/keycloak/representations/idm/SocialMappingRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/SocialMappingRepresentation.java
@@ -32,9 +32,10 @@ public class SocialMappingRepresentation {
return socialLinks;
}
- public SocialLinkRepresentation socialLink(String socialProvider, String socialUsername) {
+ public SocialLinkRepresentation socialLink(String socialProvider, String socialUserId, String socialUsername) {
SocialLinkRepresentation link = new SocialLinkRepresentation();
link.setSocialProvider(socialProvider);
+ link.setSocialUserId(socialUserId);
link.setSocialUsername(socialUsername);
if (socialLinks == null) socialLinks = new ArrayList<SocialLinkRepresentation>();
socialLinks.add(link);
diff --git a/docbook/reference/en/en-US/modules/social-facebook.xml b/docbook/reference/en/en-US/modules/social-facebook.xml
index bc87171..6e5e832 100644
--- a/docbook/reference/en/en-US/modules/social-facebook.xml
+++ b/docbook/reference/en/en-US/modules/social-facebook.xml
@@ -40,10 +40,4 @@
</para>
</listitem>
</orderedlist>
- <tip>
- <para>
- Facebook doesn't allow <literal>localhost</literal> in the redirect URI. To test on a local server
- replace <literal>localhost</literal> with <literal>127.0.0.1</literal>.
- </para>
- </tip>
</section>
\ No newline at end of file
examples/test-cordova.json 27(+27 -0)
diff --git a/examples/test-cordova.json b/examples/test-cordova.json
new file mode 100644
index 0000000..9de2ee3
--- /dev/null
+++ b/examples/test-cordova.json
@@ -0,0 +1,27 @@
+{
+ "id": "test",
+ "realm": "test",
+ "enabled": true,
+ "sslNotRequired": true,
+ "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
+ "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+ "requiredCredentials": [ "password" ],
+ "users" : [
+ {
+ "username" : "test",
+ "enabled": true,
+ "email" : "test-user@localhost",
+ "credentials" : [
+ { "type" : "password",
+ "value" : "test" }
+ ]
+ }
+ ],
+ "applications": [
+ {
+ "name": "test",
+ "enabled": true,
+ "secret": "password"
+ }
+ ]
+}
\ No newline at end of file
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 ed94d69..2fbe8c6 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
@@ -33,22 +33,22 @@ public class AccountSocialBean {
for (SocialProvider provider : SocialLoader.load()) {
String socialProviderId = provider.getId();
if (socialConfig.containsKey(socialProviderId + ".key")) {
- String socialUsername = getSocialUsername(userSocialLinks, socialProviderId);
+ SocialLinkModel socialLink = getSocialLink(userSocialLinks, socialProviderId);
- String action = socialUsername!=null ? "remove" : "add";
+ String action = socialLink != null ? "remove" : "add";
String actionUrl = UriBuilder.fromUri(accountSocialUpdateUri).queryParam("action", action).queryParam("provider_id", socialProviderId).build().toString();
- SocialLinkEntry entry = new SocialLinkEntry(socialProviderId, provider.getName(), socialUsername, actionUrl);
+ SocialLinkEntry entry = new SocialLinkEntry(socialLink, provider.getName(), actionUrl);
this.socialLinks.add(entry);
}
}
}
}
- private String getSocialUsername(Set<SocialLinkModel> userSocialLinks, String socialProviderId) {
+ private SocialLinkModel getSocialLink(Set<SocialLinkModel> userSocialLinks, String socialProviderId) {
for (SocialLinkModel link : userSocialLinks) {
if (socialProviderId.equals(link.getSocialProvider())) {
- return link.getSocialUsername();
+ return link;
}
}
return null;
@@ -60,32 +60,34 @@ public class AccountSocialBean {
public class SocialLinkEntry {
- private final String providerId;
+ private SocialLinkModel link;
private final String providerName;
- private final String socialUsername;
private final String actionUrl;
- public SocialLinkEntry(String providerId, String providerName, String socialUsername, String actionUrl) {
- this.providerId = providerId;
+ public SocialLinkEntry(SocialLinkModel link, String providerName, String actionUrl) {
+ this.link = link;
this.providerName = providerName;
- this.socialUsername = socialUsername!=null ? socialUsername : "";
this.actionUrl = actionUrl;
}
public String getProviderId() {
- return providerId;
+ return link != null ? link.getSocialProvider() : null;
}
public String getProviderName() {
return providerName;
}
+ public String getSocialUserId() {
+ return link != null ? link.getSocialUserId() : null;
+ }
+
public String getSocialUsername() {
- return socialUsername;
+ return link != null ? link.getSocialUsername() : null;
}
public boolean isConnected() {
- return !socialUsername.isEmpty();
+ return link != null;
}
public String getActionUrl() {
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 a1941de..e238248 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
@@ -11,16 +11,16 @@
<#list social.links as socialLink>
<div class="form-group">
<div class="col-sm-2 col-md-2">
- <label for="${socialLink.providerId}" class="control-label">${socialLink.providerName}</label>
+ <label for="${socialLink.providerId!}" class="control-label">${socialLink.providerName!}</label>
</div>
<div class="col-sm-5 col-md-5">
- <input disabled="true" class="form-control" value="${socialLink.socialUsername}">
+ <input disabled="true" class="form-control" value="${socialLink.socialUsername!}">
</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>
+ <a href="${socialLink.actionUrl}" type="submit" class="btn btn-primary btn-lg">Remove ${socialLink.providerName!}</a>
<#else>
- <a href="${socialLink.actionUrl}" type="submit" class="btn btn-primary btn-lg">Add ${socialLink.providerName}</a>
+ <a href="${socialLink.actionUrl}" type="submit" class="btn btn-primary btn-lg">Add ${socialLink.providerName!}</a>
</#if>
</div>
</div>
diff --git a/integration/js/src/main/resources/META-INF/resources/js/test.html b/integration/js/src/main/resources/META-INF/resources/js/test.html
new file mode 100644
index 0000000..fb20e03
--- /dev/null
+++ b/integration/js/src/main/resources/META-INF/resources/js/test.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+ <script src="http://192.168.0.16/js/keycloak.js"></script>
+</head>
+<body>
+<button onclick="keycloak.login()">Login</button>
+
+<script>
+ var keycloak = Keycloak({ realm: 'test', clientId: 'test', clientSecret: 'password' });
+
+ keycloak.init(function () {
+ console.debug('Token: ' + keycloak.tokenParsed);
+ console.debug('Realm access: ' + keycloak.realmAccess);
+ console.debug('Resource access: ' + keycloak.resourceAccess);
+
+ keycloak.loadUserProfile(function (profile) {
+ console.debug(profile);
+ }, function (error) {
+ console.debug(error);
+ })
+ });
+</script>
+</body>
+</html>
keycloak.json 8(+8 -0)
diff --git a/keycloak.json b/keycloak.json
new file mode 100644
index 0000000..35e49cd
--- /dev/null
+++ b/keycloak.json
@@ -0,0 +1,8 @@
+{
+ "realm" : "test",
+ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDddHi8/MoYNtdafydQ+e4P0qrvClCW0o/x9fAbZ09dET/VBZCU28M54LmgJT7snXfreyYBpaQpHkW52/tyuEcJ5KO28LIcvObDQFDq3Z7esrovHl4NRETJBF9Xqwt+XLTZF6m37fYzaUK6MVJzUHP9qmu90LYyyvQ+hBJD0GSw1QIDAQAB",
+ "auth-server-url" : "http://localhost:8081/auth",
+ "ssl-not-required" : true,
+ "resource" : "test",
+ "public-client" : true
+}
\ No newline at end of file
diff --git a/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java b/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java
index 742da11..76e8929 100755
--- a/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java
+++ b/model/api/src/main/java/org/keycloak/models/SocialLinkModel.java
@@ -5,20 +5,22 @@ package org.keycloak.models;
*/
public class SocialLinkModel {
- private String socialUsername;
+ private String socialUserId;
private String socialProvider;
+ private String socialUsername;
- public SocialLinkModel(String socialProvider, String socialUsername) {
- this.socialUsername = socialUsername;
+ public SocialLinkModel(String socialProvider, String socialUserId, String socialUsername) {
+ this.socialUserId = socialUserId;
this.socialProvider = socialProvider;
+ this.socialUsername = socialUsername;
}
- public String getSocialUsername() {
- return socialUsername;
+ public String getSocialUserId() {
+ return socialUserId;
}
- public void setSocialUsername(String socialUsername) {
- this.socialUsername = socialUsername;
+ public void setSocialUserId(String socialUserId) {
+ this.socialUserId = socialUserId;
}
public String getSocialProvider() {
@@ -28,4 +30,12 @@ public class SocialLinkModel {
public void setSocialProvider(String socialProvider) {
this.socialProvider = socialProvider;
}
+
+ public String getSocialUsername() {
+ return socialUsername;
+ }
+
+ public void setSocialUsername(String socialUsername) {
+ this.socialUsername = socialUsername;
+ }
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
index 8d53f14..84db8f6 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/SocialLinkEntity.java
@@ -16,7 +16,7 @@ import org.hibernate.annotations.GenericGenerator;
@NamedQueries({
@NamedQuery(name="findSocialLinkByUser", query="select link from SocialLinkEntity link where link.user = :user"),
@NamedQuery(name="findSocialLinkByUserAndProvider", query="select link from SocialLinkEntity link where link.user = :user and link.socialProvider = :socialProvider"),
- @NamedQuery(name="findUserByLinkAndRealm", query="select link.user from SocialLinkEntity link where link.realm = :realm and link.socialProvider = :socialProvider and link.socialUsername = :socialUsername")
+ @NamedQuery(name="findUserByLinkAndRealm", query="select link.user from SocialLinkEntity link where link.realm = :realm and link.socialProvider = :socialProvider and link.socialUserId = :socialUserId")
})
@Entity
public class SocialLinkEntity {
@@ -32,6 +32,7 @@ public class SocialLinkEntity {
protected RealmEntity realm;
protected String socialProvider;
+ protected String socialUserId;
protected String socialUsername;
public String getId() {
@@ -58,6 +59,14 @@ public class SocialLinkEntity {
this.socialProvider = socialProvider;
}
+ public String getSocialUserId() {
+ return socialUserId;
+ }
+
+ public void setSocialUserId(String socialUserId) {
+ this.socialUserId = socialUserId;
+ }
+
public String getSocialUsername() {
return socialUsername;
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 986e565..465f717 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -543,13 +543,13 @@ public class RealmAdapter implements RealmModel {
TypedQuery<UserEntity> query = em.createNamedQuery("findUserByLinkAndRealm", UserEntity.class);
query.setParameter("realm", realm);
query.setParameter("socialProvider", socialLink.getSocialProvider());
- query.setParameter("socialUsername", socialLink.getSocialUsername());
+ 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() +
- ", socialUsername=" + socialLink.getSocialUsername() + ", results=" + results);
+ ", socialUserId=" + socialLink.getSocialUserId() + ", results=" + results);
} else {
UserEntity user = results.get(0);
return new UserAdapter(user);
@@ -563,7 +563,7 @@ public class RealmAdapter implements RealmModel {
List<SocialLinkEntity> results = query.getResultList();
Set<SocialLinkModel> set = new HashSet<SocialLinkModel>();
for (SocialLinkEntity entity : results) {
- set.add(new SocialLinkModel(entity.getSocialProvider(), entity.getSocialUsername()));
+ set.add(new SocialLinkModel(entity.getSocialProvider(), entity.getSocialUserId(), entity.getSocialUsername()));
}
return set;
}
@@ -571,7 +571,7 @@ public class RealmAdapter implements RealmModel {
@Override
public SocialLinkModel getSocialLink(UserModel user, String socialProvider) {
SocialLinkEntity entity = findSocialLink(user, socialProvider);
- return (entity != null) ? new SocialLinkModel(entity.getSocialProvider(), entity.getSocialUsername()) : null;
+ return (entity != null) ? new SocialLinkModel(entity.getSocialProvider(), entity.getSocialUserId(), entity.getSocialUsername()) : null;
}
@Override
@@ -579,6 +579,7 @@ public class RealmAdapter implements RealmModel {
SocialLinkEntity entity = new SocialLinkEntity();
entity.setRealm(realm);
entity.setSocialProvider(socialLink.getSocialProvider());
+ entity.setSocialUserId(socialLink.getSocialUserId());
entity.setSocialUsername(socialLink.getSocialUsername());
entity.setUser(((UserAdapter) user).getUser());
em.persist(entity);
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index d2b5a33..90910f9 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -853,7 +853,7 @@ public class RealmAdapter extends AbstractMongoAdapter<RealmEntity> implements R
public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
DBObject query = new QueryBuilder()
.and("socialLinks.socialProvider").is(socialLink.getSocialProvider())
- .and("socialLinks.socialUsername").is(socialLink.getSocialUsername())
+ .and("socialLinks.socialUserId").is(socialLink.getSocialUserId())
.and("realmId").is(getId())
.get();
UserEntity userEntity = getMongoStore().loadSingleEntity(UserEntity.class, query, invocationContext);
@@ -871,7 +871,7 @@ public class RealmAdapter extends AbstractMongoAdapter<RealmEntity> implements R
Set<SocialLinkModel> result = new HashSet<SocialLinkModel>();
for (SocialLinkEntity socialLinkEntity : linkEntities) {
- SocialLinkModel model = new SocialLinkModel(socialLinkEntity.getSocialProvider(), socialLinkEntity.getSocialUsername());
+ SocialLinkModel model = new SocialLinkModel(socialLinkEntity.getSocialProvider(), socialLinkEntity.getSocialUserId(), socialLinkEntity.getSocialUsername());
result.add(model);
}
return result;
@@ -880,7 +880,7 @@ public class RealmAdapter extends AbstractMongoAdapter<RealmEntity> implements R
@Override
public SocialLinkModel getSocialLink(UserModel user, String socialProvider) {
SocialLinkEntity socialLinkEntity = findSocialLink(user, socialProvider);
- return socialLinkEntity!=null ? new SocialLinkModel(socialLinkEntity.getSocialProvider(), socialLinkEntity.getSocialUsername()) : null;
+ return socialLinkEntity!=null ? new SocialLinkModel(socialLinkEntity.getSocialProvider(), socialLinkEntity.getSocialUserId(), socialLinkEntity.getSocialUsername()) : null;
}
@Override
@@ -888,6 +888,7 @@ public class RealmAdapter extends AbstractMongoAdapter<RealmEntity> implements R
UserEntity userEntity = ((UserAdapter)user).getUser();
SocialLinkEntity socialLinkEntity = new SocialLinkEntity();
socialLinkEntity.setSocialProvider(socialLink.getSocialProvider());
+ socialLinkEntity.setSocialUserId(socialLink.getSocialUserId());
socialLinkEntity.setSocialUsername(socialLink.getSocialUsername());
getMongoStore().pushItemToList(userEntity, "socialLinks", socialLinkEntity, true, invocationContext);
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/SocialLinkEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/SocialLinkEntity.java
index 85ae5c0..85afa11 100644
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/SocialLinkEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/SocialLinkEntity.java
@@ -8,10 +8,20 @@ import org.keycloak.models.mongo.api.MongoField;
*/
public class SocialLinkEntity implements MongoEntity {
+ private String socialUserId;
private String socialUsername;
private String socialProvider;
@MongoField
+ public String getSocialUserId() {
+ return socialUserId;
+ }
+
+ public void setSocialUserId(String socialUserId) {
+ this.socialUserId = socialUserId;
+ }
+
+ @MongoField
public String getSocialUsername() {
return socialUsername;
}
@@ -37,9 +47,9 @@ public class SocialLinkEntity implements MongoEntity {
SocialLinkEntity that = (SocialLinkEntity) o;
if (socialProvider != null && (that.socialProvider == null || !socialProvider.equals(that.socialProvider))) return false;
- if (socialUsername != null && (that.socialUsername == null || !socialUsername.equals(that.socialUsername))) return false;
+ if (socialUserId != null && (that.socialUserId == null || !socialUserId.equals(that.socialUserId))) return false;
if (socialProvider == null && that.socialProvider != null)return false;
- if (socialUsername == null && that.socialUsername != null) return false;
+ if (socialUserId == null && that.socialUserId != null) return false;
return true;
}
@@ -47,7 +57,7 @@ public class SocialLinkEntity implements MongoEntity {
@Override
public int hashCode() {
int code = 1;
- if (socialUsername != null) {
+ if (socialUserId != null) {
code = code * 13;
}
if (socialProvider != null) {
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
index d4c1624..36d7098 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/RealmAdapter.java
@@ -880,14 +880,14 @@ public class RealmAdapter implements RealmModel {
public UserModel getUserBySocialLink(SocialLinkModel socialLink) {
RelationshipQuery<SocialLinkRelationship> query = getRelationshipManager().createRelationshipQuery(SocialLinkRelationship.class);
query.setParameter(SocialLinkRelationship.SOCIAL_PROVIDER, socialLink.getSocialProvider());
- query.setParameter(SocialLinkRelationship.SOCIAL_USERNAME, socialLink.getSocialUsername());
+ query.setParameter(SocialLinkRelationship.SOCIAL_USERNAME, socialLink.getSocialUserId());
query.setParameter(SocialLinkRelationship.REALM, realm.getName());
List<SocialLinkRelationship> results = query.getResultList();
if (results.isEmpty()) {
return null;
} else if (results.size() > 1) {
throw new IllegalStateException("More results found for socialProvider=" + socialLink.getSocialProvider() +
- ", socialUsername=" + socialLink.getSocialUsername() + ", results=" + results);
+ ", socialUserId=" + socialLink.getSocialUserId() + ", results=" + results);
} else {
User user = results.get(0).getUser();
return new UserAdapter(user, getIdm());
@@ -902,7 +902,7 @@ public class RealmAdapter implements RealmModel {
Set<SocialLinkModel> results = new HashSet<SocialLinkModel>();
for (SocialLinkRelationship relationship : plSocialLinks) {
- results.add(new SocialLinkModel(relationship.getSocialProvider(), relationship.getSocialUsername()));
+ results.add(new SocialLinkModel(relationship.getSocialProvider(), relationship.getSocialUserId()));
}
return results;
}
@@ -912,7 +912,7 @@ public class RealmAdapter implements RealmModel {
SocialLinkRelationship relationship = new SocialLinkRelationship();
relationship.setUser(((UserAdapter)user).getUser());
relationship.setSocialProvider(socialLink.getSocialProvider());
- relationship.setSocialUsername(socialLink.getSocialUsername());
+ relationship.setSocialUserId(socialLink.getSocialUserId());
relationship.setRealm(realm.getName());
getRelationshipManager().add(relationship);
@@ -923,7 +923,7 @@ public class RealmAdapter implements RealmModel {
SocialLinkRelationship relationship = new SocialLinkRelationship();
relationship.setUser(((UserAdapter)user).getUser());
relationship.setSocialProvider(socialLink.getSocialProvider());
- relationship.setSocialUsername(socialLink.getSocialUsername());
+ relationship.setSocialUserId(socialLink.getSocialUserId());
relationship.setRealm(realm.getName());
getRelationshipManager().remove(relationship);
diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java
index 62ec7e3..12f8d03 100755
--- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java
+++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/relationships/SocialLinkRelationship.java
@@ -20,9 +20,9 @@ public class SocialLinkRelationship extends AbstractAttributedType implements Re
private static final long serialVersionUID = 154879L;
public static final AttributeParameter SOCIAL_PROVIDER = new AttributeParameter("socialProvider");
- public static final AttributeParameter SOCIAL_USERNAME = new AttributeParameter("socialUsername");
+ public static final AttributeParameter SOCIAL_USERID = new AttributeParameter("socialUserId");
- // realm is needed to allow searching as combination socialUsername+socialProvider may not be unique
+ // realm is needed to allow searching as combination socialUserId+socialProvider may not be unique
// (Same user could have mapped same facebook account to username "foo" in "realm1" and to username "bar" in "realm2")
public static final AttributeParameter REALM = new AttributeParameter("realm");
@@ -54,12 +54,12 @@ public class SocialLinkRelationship extends AbstractAttributedType implements Re
}
@AttributeProperty
- public String getSocialUsername() {
- return (String)getAttribute("socialUsername").getValue();
+ public String getSocialUserId() {
+ return (String)getAttribute("socialUserId").getValue();
}
- public void setSocialUsername(String socialProviderUserId) {
- setAttribute(new Attribute<String>("socialUsername", socialProviderUserId));
+ public void setSocialUserId(String socialUserId) {
+ setAttribute(new Attribute<String>("socialUserId", socialUserId));
}
@AttributeProperty
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
index 7a29945..9ea7b1e 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
@@ -156,7 +156,7 @@ public class AdapterTest extends AbstractModelTest {
RoleModel appRole = app.addRole("test");
realmModel.grantRole(user, appRole);
- SocialLinkModel socialLink = new SocialLinkModel("google", user.getLoginName());
+ SocialLinkModel socialLink = new SocialLinkModel("google", "google1", user.getLoginName());
realmModel.addSocialLink(user, socialLink);
UserCredentialModel cred = new UserCredentialModel();
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
index 3c41a5d..ae83661 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
@@ -133,22 +133,26 @@ public class ImportTest extends AbstractModelTest {
for (SocialLinkModel socialLinkModel : socialLinks) {
if ("facebook".equals(socialLinkModel.getSocialProvider())) {
facebookFound = true;
+ Assert.assertEquals(socialLinkModel.getSocialUserId(), "facebook1");
Assert.assertEquals(socialLinkModel.getSocialUsername(), "fbuser1");
} else if ("google".equals(socialLinkModel.getSocialProvider())) {
googleFound = true;
+ Assert.assertEquals(socialLinkModel.getSocialUserId(), "google1");
Assert.assertEquals(socialLinkModel.getSocialUsername(), "mySocialUser@gmail.com");
} else if ("twitter".equals(socialLinkModel.getSocialProvider())) {
twitterFound = true;
+ Assert.assertEquals(socialLinkModel.getSocialUserId(), "twitter1");
Assert.assertEquals(socialLinkModel.getSocialUsername(), "twuser1");
}
}
Assert.assertTrue(facebookFound && twitterFound && googleFound);
- UserModel foundSocialUser = realm.getUserBySocialLink(new SocialLinkModel("facebook", "fbuser1"));
+ UserModel foundSocialUser = realm.getUserBySocialLink(new SocialLinkModel("facebook", "facebook1", "fbuser1"));
Assert.assertEquals(foundSocialUser.getLoginName(), socialUser.getLoginName());
- Assert.assertNull(realm.getUserBySocialLink(new SocialLinkModel("facebook", "not-existing")));
+ Assert.assertNull(realm.getUserBySocialLink(new SocialLinkModel("facebook", "not-existing", "not-existing")));
SocialLinkModel foundSocialLink = realm.getSocialLink(socialUser, "facebook");
+ Assert.assertEquals("facebook1", foundSocialLink.getSocialUserId());
Assert.assertEquals("fbuser1", foundSocialLink.getSocialUsername());
Assert.assertEquals("facebook", foundSocialLink.getSocialProvider());
diff --git a/model/tests/src/test/resources/testrealm.json b/model/tests/src/test/resources/testrealm.json
index 6f573d4..e0d6cfb 100755
--- a/model/tests/src/test/resources/testrealm.json
+++ b/model/tests/src/test/resources/testrealm.json
@@ -52,14 +52,17 @@
"socialLinks": [
{
"socialProvider": "facebook",
+ "socialUserId": "facebook1",
"socialUsername": "fbuser1"
},
{
"socialProvider": "twitter",
+ "socialUserId": "twitter1",
"socialUsername": "twuser1"
},
{
"socialProvider": "google",
+ "socialUserId": "google1",
"socialUsername": "mySocialUser@gmail.com"
}
]
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index dae9ae3..face034 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -366,7 +366,7 @@ public class RealmManager {
for (SocialMappingRepresentation socialMapping : rep.getSocialMappings()) {
UserModel user = userMap.get(socialMapping.getUsername());
for (SocialLinkRepresentation link : socialMapping.getSocialLinks()) {
- SocialLinkModel mappingModel = new SocialLinkModel(link.getSocialProvider(), link.getSocialUsername());
+ SocialLinkModel mappingModel = new SocialLinkModel(link.getSocialProvider(), link.getSocialUserId(), link.getSocialUsername());
newRealm.addSocialLink(user, mappingModel);
}
}
diff --git a/services/src/main/java/org/keycloak/services/resources/SocialResource.java b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
index 55cb9a3..4566c2e 100755
--- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
@@ -146,7 +146,7 @@ public class SocialResource {
return oauth.forwardToSecurityFailure("Failed to process social callback");
}
- SocialLinkModel socialLink = new SocialLinkModel(provider.getId(), socialUser.getId());
+ SocialLinkModel socialLink = new SocialLinkModel(provider.getId(), socialUser.getId(), socialUser.getUsername());
UserModel user = realm.getUserBySocialLink(socialLink);
// Check if user is already authenticated (this means linking social into existing user account)
diff --git a/social/core/src/main/java/org/keycloak/social/AuthCallback.java b/social/core/src/main/java/org/keycloak/social/AuthCallback.java
index d9c579a..3ad0774 100644
--- a/social/core/src/main/java/org/keycloak/social/AuthCallback.java
+++ b/social/core/src/main/java/org/keycloak/social/AuthCallback.java
@@ -43,7 +43,7 @@ public class AuthCallback {
public String getQueryParam(String name) {
String[] value = queryParams.get(name);
- if (value.length > 0) {
+ if (value != null && value.length > 0) {
return value[0];
}
return null;
diff --git a/social/core/src/main/java/org/keycloak/social/SocialUser.java b/social/core/src/main/java/org/keycloak/social/SocialUser.java
index 2c69456..9a1faed 100644
--- a/social/core/src/main/java/org/keycloak/social/SocialUser.java
+++ b/social/core/src/main/java/org/keycloak/social/SocialUser.java
@@ -3,12 +3,14 @@ package org.keycloak.social;
public class SocialUser {
private String id;
+ private String username;
private String firstName;
private String lastName;
private String email;
- public SocialUser(String id) {
+ public SocialUser(String id, String username) {
this.id = id;
+ this.username = username;
}
public String getId() {
@@ -19,6 +21,14 @@ public class SocialUser {
this.id = id;
}
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
public String getFirstName() {
return firstName;
}
diff --git a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java
index cc62c52..9f64036 100755
--- a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java
+++ b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookProvider.java
@@ -52,7 +52,7 @@ public class FacebookProvider extends AbstractOAuth2Provider {
try {
JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson();
- SocialUser user = new SocialUser(profile.getString("id"));
+ SocialUser user = new SocialUser(profile.getString("id"), profile.getString("username"));
user.setName(profile.optString("first_name"), profile.optString("last_name"));
user.setEmail(profile.optString("email"));
@@ -64,10 +64,6 @@ public class FacebookProvider extends AbstractOAuth2Provider {
@Override
public AuthRequest getAuthUrl(SocialProviderConfig config) throws SocialProviderException {
- if (config.getCallbackUrl().contains("//localhost")) {
- String callbackUrl = config.getCallbackUrl().replace("//localhost", "//127.0.0.1");
- config = new SocialProviderConfig(config.getKey(), config.getSecret(), callbackUrl);
- }
return super.getAuthUrl(config);
}
diff --git a/social/github/src/main/java/org/keycloak/social/github/GitHubProvider.java b/social/github/src/main/java/org/keycloak/social/github/GitHubProvider.java
index ad38dcd..95c1067 100755
--- a/social/github/src/main/java/org/keycloak/social/github/GitHubProvider.java
+++ b/social/github/src/main/java/org/keycloak/social/github/GitHubProvider.java
@@ -52,7 +52,7 @@ public class GitHubProvider extends AbstractOAuth2Provider {
try {
JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson();
- SocialUser user = new SocialUser(profile.get("id").toString());
+ SocialUser user = new SocialUser(profile.get("id").toString(), profile.getString("login"));
user.setName(profile.optString("name"));
user.setEmail(profile.optString("email"));
diff --git a/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java b/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java
index 08b1104..ab3d8f4 100755
--- a/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java
+++ b/social/google/src/main/java/org/keycloak/social/google/GoogleProvider.java
@@ -71,7 +71,7 @@ public class GoogleProvider extends AbstractOAuth2Provider {
try {
JSONObject profile = SimpleHttp.doGet(PROFILE_URL).header("Authorization", "Bearer " + accessToken).asJson();
- SocialUser user = new SocialUser(profile.getString("sub"));
+ SocialUser user = new SocialUser(profile.getString("sub"), profile.getString("email"));
user.setName(profile.optString("given_name"), profile.optString("family_name"));
user.setEmail(profile.optString("email"));
diff --git a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
index fda4c6a..7842ff4 100755
--- a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
+++ b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterProvider.java
@@ -77,7 +77,7 @@ public class TwitterProvider implements SocialProvider {
twitter.getOAuthAccessToken(requestToken, verifier);
twitter4j.User twitterUser = twitter.verifyCredentials();
- SocialUser user = new SocialUser(Long.toString(twitterUser.getId()));
+ SocialUser user = new SocialUser(Long.toString(twitterUser.getId()), twitterUser.getScreenName());
user.setName(twitterUser.getName());
return user;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java
index ee4607e..71a3563 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java
@@ -42,8 +42,9 @@ public class DummySocial implements SocialProvider {
throw new SocialProviderException("Invalid state");
}
+ String id = callback.getQueryParam("id");
String username = callback.getQueryParam("username");
- SocialUser user = new SocialUser(username);
+ SocialUser user = new SocialUser(id, username);
user.setName(callback.getQueryParam("firstname"), callback.getQueryParam("lastname"));
user.setEmail(callback.getQueryParam("email"));
return user;
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java
index 9278d36..cc93a39 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java
@@ -22,11 +22,13 @@ public class DummySocialServlet extends HttpServlet {
pw.print("<html>");
pw.print("<body>");
pw.print("<form method=\"post\">");
+ pw.print("<label for=\"id\">ID</label><input type=\"text\" id=\"id\" name=\"id\" />");
pw.print("<label for=\"username\">Username</label><input type=\"text\" id=\"username\" name=\"username\" />");
pw.print("<label for=\"firstname\">First Name</label><input type=\"text\" id=\"firstname\" name=\"firstname\" />");
pw.print("<label for=\"lastname\">Last Name</label><input type=\"text\" id=\"lastname\" name=\"lastname\" />");
pw.print("<label for=\"email\">Email</label><input type=\"text\" id=\"email\" name=\"email\" />");
pw.print("<input type=\"submit\" id=\"submit\" value=\"login\" />");
+ pw.print("<input type=\"submit\" id=\"cancel\" value=\"cancel\" />");
pw.print("</form>");
pw.print("</body>");
pw.print("</html>");
@@ -53,15 +55,20 @@ public class DummySocialServlet extends HttpServlet {
}
}
- String redirect = redirectUri + "?username=" + req.getParameter("username") + "&state=" + state + "&code=" + UUID.randomUUID().toString();
- if (req.getParameter("firstname") != null) {
- redirect += "&firstname=" + req.getParameter("firstname");
- }
- if (req.getParameter("lastname") != null) {
- redirect += "&lastname=" + req.getParameter("lastname");
- }
- if (req.getParameter("email") != null) {
- redirect += "&email=" + req.getParameter("email");
+ String redirect;
+ if (req.getParameter("login") != null) {
+ redirect = redirectUri + "?id=" + req.getParameter("id") + "&username=" + req.getParameter("username") + "&state=" + state + "&code=" + UUID.randomUUID().toString();
+ if (req.getParameter("firstname") != null) {
+ redirect += "&firstname=" + req.getParameter("firstname");
+ }
+ if (req.getParameter("lastname") != null) {
+ redirect += "&lastname=" + req.getParameter("lastname");
+ }
+ if (req.getParameter("email") != null) {
+ redirect += "&email=" + req.getParameter("email");
+ }
+ } else {
+ redirect = redirectUri + "?error=access_denied&state=" + state;
}
resp.sendRedirect(redirect);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
index 27e7a87..01d136f 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java
@@ -97,6 +97,7 @@ public class SocialLoginTest {
loginPage.clickSocial("dummy");
+ driver.findElement(By.id("id")).sendKeys("1");
driver.findElement(By.id("username")).sendKeys("dummy-user1");
driver.findElement(By.id("firstname")).sendKeys("Bob");
driver.findElement(By.id("lastname")).sendKeys("Builder");
@@ -118,6 +119,30 @@ public class SocialLoginTest {
Assert.assertEquals("bob@builder.com", profile.getEmail());
}
+
+ @Test
+ public void loginCancelled() throws Exception {
+ loginPage.open();
+
+ loginPage.clickSocial("dummy");
+
+ driver.findElement(By.id("cancel")).click();
+
+ Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+ AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get("code"), "password");
+
+ AccessToken token = oauth.verifyToken(response.getAccessToken());
+ Assert.assertEquals(36, token.getSubject().length());
+
+ UserRepresentation profile = keycloakRule.getUserById("test", token.getSubject());
+ Assert.assertEquals(36, profile.getUsername().length());
+
+ Assert.assertEquals("Bob", profile.getFirstName());
+ Assert.assertEquals("Builder", profile.getLastName());
+ Assert.assertEquals("bob@builder.com", profile.getEmail());
+ }
+
@Test
public void profileUpdateRequired() {
keycloakRule.configure(new KeycloakSetup() {
@@ -132,6 +157,7 @@ public class SocialLoginTest {
loginPage.clickSocial("dummy");
+ driver.findElement(By.id("id")).sendKeys("2");
driver.findElement(By.id("username")).sendKeys("dummy-user2");
driver.findElement(By.id("firstname")).sendKeys("Bob");
driver.findElement(By.id("lastname")).sendKeys("Builder");
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java
index 12fced6..62d22af 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateUsersWorker.java
@@ -97,7 +97,7 @@ public class CreateUsersWorker implements Worker {
+ " which is too big.");
}
- SocialLinkModel socialLink = new SocialLinkModel(socialProvider, username);
+ SocialLinkModel socialLink = new SocialLinkModel(socialProvider, username, username);
realm.addSocialLink(user, socialLink);
}
diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
index 80c8b57..c125ac5 100755
--- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
+++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/ReadUsersWorker.java
@@ -112,7 +112,7 @@ public class ReadUsersWorker implements Worker {
// Try to search by social links
if (searchBySocialLinks) {
- SocialLinkModel socialLink = new SocialLinkModel("facebook", username);
+ SocialLinkModel socialLink = new SocialLinkModel("facebook", username, username);
realm.getUserBySocialLink(socialLink);
}
}