From dcfb83b0f2a881037c0f62dc5f1b68d517fce627 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Thu, 16 Jan 2014 12:51:18 +0000 Subject: [PATCH 1/3] KEYCLOAK-64 KEYCLOAK-246 Updated social to use update profile required action instead of registration form. Fixed Google provider --- .../admin/partials/realm-detail.html | 4 +- .../idm/RealmRepresentation.java | 10 +- examples/as7-eap-demo/testrealm.json | 2 +- examples/wildfly-demo/testrealm.json | 2 +- .../java/org/keycloak/forms/RegisterBean.java | 10 +- .../java/org/keycloak/forms/SocialBean.java | 2 +- .../main/java/org/keycloak/forms/UrlBean.java | 12 -- .../org/keycloak/service/FormServiceImpl.java | 7 +- .../java/org/keycloak/models/RealmModel.java | 4 +- .../org/keycloak/models/jpa/RealmAdapter.java | 8 +- .../models/jpa/entities/RealmEntity.java | 10 +- .../models/picketlink/RealmAdapter.java | 8 +- .../models/picketlink/mappings/RealmData.java | 10 +- .../picketlink/mappings/RealmEntity.java | 10 +- pom.xml | 7 + .../org/keycloak/services/FormService.java | 10 -- .../services/managers/RealmManager.java | 10 +- .../services/resources/SocialResource.java | 146 ++++-------------- .../services/resources/TokenService.java | 26 +--- .../services/resources/flows/FormFlows.java | 10 +- .../services/resources/flows/Urls.java | 4 - .../java/org/keycloak/test/AdapterTest.java | 8 +- .../java/org/keycloak/test/ImportTest.java | 4 +- .../java/org/keycloak/test/ModelTest.java | 4 +- .../src/test/resources/testrealm-demo.json | 2 +- social/core/pom.xml | 20 ++- .../java/org/keycloak/social/AuthRequest.java | 36 ++++- .../org/keycloak/social/utils/SimpleHttp.java | 142 +++++++++++++++++ .../keycloak/social/utils/SimpleHttpTest.java | 100 ++++++++++++ .../keycloak/social/utils/ToJsonServlet.java | 50 ++++++ .../keycloak/social/utils/UndertowServer.java | 63 ++++++++ social/google/pom.xml | 14 -- .../social/google/GoogleProvider.java | 51 ++---- .../org/keycloak/testsuite/DummySocial.java | 2 +- .../testsuite/DummySocialServlet.java | 4 +- .../pages/LoginUpdateProfilePage.java | 12 ++ .../testsuite/social/SocialLoginTest.java | 22 +-- 37 files changed, 544 insertions(+), 302 deletions(-) create mode 100644 social/core/src/main/java/org/keycloak/social/utils/SimpleHttp.java create mode 100644 social/core/src/main/test/java/org/keycloak/social/utils/SimpleHttpTest.java create mode 100644 social/core/src/main/test/java/org/keycloak/social/utils/ToJsonServlet.java create mode 100644 social/core/src/main/test/java/org/keycloak/social/utils/UndertowServer.java diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html index 2628dcca1b..7975742bbf 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html @@ -46,8 +46,8 @@
- - + +
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index 45ec844664..376de43a5e 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -23,7 +23,7 @@ public class RealmRepresentation { protected Boolean verifyEmail; protected Boolean resetPasswordAllowed; protected Boolean social; - protected Boolean automaticRegistrationAfterSocialLogin; + protected Boolean updateProfileOnInitialSocialLogin; protected String privateKey; protected String publicKey; protected List roles; @@ -279,12 +279,12 @@ public class RealmRepresentation { this.social = social; } - public Boolean isAutomaticRegistrationAfterSocialLogin() { - return automaticRegistrationAfterSocialLogin; + public Boolean isUpdateProfileOnInitialSocialLogin() { + return updateProfileOnInitialSocialLogin; } - public void setAutomaticRegistrationAfterSocialLogin(Boolean automaticRegistrationAfterSocialLogin) { - this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin; + public void setUpdateProfileOnInitialSocialLogin(Boolean updateProfileOnInitialSocialLogin) { + this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin; } public Map getSocialProviders() { diff --git a/examples/as7-eap-demo/testrealm.json b/examples/as7-eap-demo/testrealm.json index f9354df4c8..da8b804b03 100755 --- a/examples/as7-eap-demo/testrealm.json +++ b/examples/as7-eap-demo/testrealm.json @@ -8,7 +8,7 @@ "sslNotRequired": true, "registrationAllowed": false, "social": false, - "automaticRegistrationAfterSocialLogin": false, + "updateProfileOnInitialSocialLogin": false, "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" ], diff --git a/examples/wildfly-demo/testrealm.json b/examples/wildfly-demo/testrealm.json index f9354df4c8..da8b804b03 100755 --- a/examples/wildfly-demo/testrealm.json +++ b/examples/wildfly-demo/testrealm.json @@ -8,7 +8,7 @@ "sslNotRequired": true, "registrationAllowed": false, "social": false, - "automaticRegistrationAfterSocialLogin": false, + "updateProfileOnInitialSocialLogin": false, "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" ], diff --git a/forms/src/main/java/org/keycloak/forms/RegisterBean.java b/forms/src/main/java/org/keycloak/forms/RegisterBean.java index 94bb83cc66..d801a42205 100755 --- a/forms/src/main/java/org/keycloak/forms/RegisterBean.java +++ b/forms/src/main/java/org/keycloak/forms/RegisterBean.java @@ -32,14 +32,10 @@ public class RegisterBean { private Map formData = new HashMap(); - private boolean socialRegistration; - - public RegisterBean(MultivaluedMap formData, boolean socialRegistration) { + public RegisterBean(MultivaluedMap formData) { this.formData = new HashMap(); - this.socialRegistration = socialRegistration; - if (formData != null) { for (String k : formData.keySet()) { this.formData.put(k, formData.getFirst(k)); @@ -51,8 +47,4 @@ public class RegisterBean { return formData; } - public boolean isSocialRegistration() { - return socialRegistration; - } - } diff --git a/forms/src/main/java/org/keycloak/forms/SocialBean.java b/forms/src/main/java/org/keycloak/forms/SocialBean.java index 0861b55404..939aa2953d 100755 --- a/forms/src/main/java/org/keycloak/forms/SocialBean.java +++ b/forms/src/main/java/org/keycloak/forms/SocialBean.java @@ -64,7 +64,7 @@ public class SocialBean { // Display panel with social providers just in case that social is enabled for realm, but we are not in the middle of registration with social public boolean isDisplaySocialProviders() { - return realm.isSocial() && !providers.isEmpty() && !registerBean.isSocialRegistration(); + return realm.isSocial() && !providers.isEmpty(); } public RealmBean getRealm() { diff --git a/forms/src/main/java/org/keycloak/forms/UrlBean.java b/forms/src/main/java/org/keycloak/forms/UrlBean.java index c3e24b119a..4637cc200a 100755 --- a/forms/src/main/java/org/keycloak/forms/UrlBean.java +++ b/forms/src/main/java/org/keycloak/forms/UrlBean.java @@ -34,18 +34,8 @@ public class UrlBean { private RealmBean realm; - private boolean socialRegistration; - private String referrerURI; - public boolean isSocialRegistration() { - return socialRegistration; - } - - public void setSocialRegistration(boolean socialRegistration) { - this.socialRegistration = socialRegistration; - } - public UrlBean(RealmBean realm, URI baseURI, String referrerURI){ this.realm = realm; this.baseURI = baseURI; @@ -91,8 +81,6 @@ public class UrlBean { public String getRegistrationAction() { if (realm.isSaas()) { return Urls.saasRegisterAction(baseURI).toString(); - } else if (socialRegistration){ - return Urls.socialRegisterAction(baseURI, getRealmIdentifier()).toString(); } else { return Urls.realmRegisterAction(baseURI, getRealmIdentifier()).toString(); } diff --git a/forms/src/main/java/org/keycloak/service/FormServiceImpl.java b/forms/src/main/java/org/keycloak/service/FormServiceImpl.java index 33d36ea51e..128bb9795a 100755 --- a/forms/src/main/java/org/keycloak/service/FormServiceImpl.java +++ b/forms/src/main/java/org/keycloak/service/FormServiceImpl.java @@ -140,7 +140,6 @@ public class FormServiceImpl implements FormService { } url = new UrlBean(realm, dataBean.getBaseURI(), referrerUri); - url.setSocialRegistration(dataBean.getSocialRegistration()); user = new UserBean(dataBean.getUserModel()); login = new LoginBean(realm, dataBean.getFormData()); @@ -163,7 +162,7 @@ public class FormServiceImpl implements FormService { public void exec(Map attributes, FormServiceDataBean dataBean) { super.exec(attributes, dataBean); - RegisterBean register = new RegisterBean(dataBean.getFormData(), dataBean.getSocialRegistration()); + RegisterBean register = new RegisterBean(dataBean.getFormData()); SocialBean social = new SocialBean(realm, dataBean.getSocialProviders(), register, url); attributes.put("social", social); } @@ -173,7 +172,7 @@ public class FormServiceImpl implements FormService { public void exec(Map attributes, FormServiceDataBean dataBean) { super.exec(attributes, dataBean); - RegisterBean register = new RegisterBean(dataBean.getFormData(), dataBean.getSocialRegistration()); + RegisterBean register = new RegisterBean(dataBean.getFormData()); SocialBean social = new SocialBean(realm, dataBean.getSocialProviders(), register, url); attributes.put("social", social); } @@ -183,7 +182,7 @@ public class FormServiceImpl implements FormService { public void exec(Map attributes, FormServiceDataBean dataBean) { super.exec(attributes, dataBean); - RegisterBean register = new RegisterBean(dataBean.getFormData(), dataBean.getSocialRegistration()); + RegisterBean register = new RegisterBean(dataBean.getFormData()); attributes.put("register", register); SocialBean social = new SocialBean(realm, dataBean.getSocialProviders(), register, url); diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java index 42ab0e684a..184e6aafa7 100755 --- a/model/api/src/main/java/org/keycloak/models/RealmModel.java +++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java @@ -132,9 +132,9 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa void setSocial(boolean social); - public boolean isAutomaticRegistrationAfterSocialLogin(); + public boolean isUpdateProfileOnInitialSocialLogin(); - public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin); + public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin); List getUsers(); 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 d08ed73b53..0488bddd81 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 @@ -663,13 +663,13 @@ public class RealmAdapter implements RealmModel { } @Override - public boolean isAutomaticRegistrationAfterSocialLogin() { - return realm.isAutomaticRegistrationAfterSocialLogin(); + public boolean isUpdateProfileOnInitialSocialLogin() { + return realm.isUpdateProfileOnInitialSocialLogin(); } @Override - public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) { - realm.setAutomaticRegistrationAfterSocialLogin(automaticRegistrationAfterSocialLogin); + public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) { + realm.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin); em.flush(); } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java index 6f4fadf3a2..067b8dcdfd 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java @@ -38,7 +38,7 @@ public class RealmEntity { protected boolean verifyEmail; protected boolean resetPasswordAllowed; protected boolean social; - protected boolean automaticRegistrationAfterSocialLogin; + protected boolean updateProfileOnInitialSocialLogin; protected String passwordPolicy; protected int tokenLifespan; @@ -149,12 +149,12 @@ public class RealmEntity { this.social = social; } - public boolean isAutomaticRegistrationAfterSocialLogin() { - return automaticRegistrationAfterSocialLogin; + public boolean isUpdateProfileOnInitialSocialLogin() { + return updateProfileOnInitialSocialLogin; } - public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) { - this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin; + public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) { + this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin; } public int getTokenLifespan() { 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 0fb2c22a0f..13d78a35ed 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 @@ -125,13 +125,13 @@ public class RealmAdapter implements RealmModel { } @Override - public boolean isAutomaticRegistrationAfterSocialLogin() { - return realm.isAutomaticRegistrationAfterSocialLogin(); + public boolean isUpdateProfileOnInitialSocialLogin() { + return realm.isUpdateProfileOnInitialSocialLogin(); } @Override - public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) { - realm.setAutomaticRegistrationAfterSocialLogin(automaticRegistrationAfterSocialLogin); + public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) { + realm.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin); updateRealm(); } diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmData.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmData.java index 2914cbcc8d..03c346665d 100755 --- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmData.java +++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmData.java @@ -17,7 +17,7 @@ public class RealmData extends AbstractPartition { private boolean verifyEmail; private boolean resetPasswordAllowed; private boolean social; - private boolean automaticRegistrationAfterSocialLogin; + private boolean updateProfileOnInitialSocialLogin; private int tokenLifespan; private int accessCodeLifespan; private int accessCodeLifespanUserAction; @@ -63,12 +63,12 @@ public class RealmData extends AbstractPartition { } @AttributeProperty - public boolean isAutomaticRegistrationAfterSocialLogin() { - return automaticRegistrationAfterSocialLogin; + public boolean isUpdateProfileOnInitialSocialLogin() { + return updateProfileOnInitialSocialLogin; } - public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) { - this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin; + public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) { + this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin; } @AttributeProperty diff --git a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmEntity.java b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmEntity.java index 21913c7f4d..fe0a448fbd 100755 --- a/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmEntity.java +++ b/model/picketlink/src/main/java/org/keycloak/models/picketlink/mappings/RealmEntity.java @@ -41,7 +41,7 @@ public class RealmEntity implements Serializable { @AttributeValue private boolean social; @AttributeValue - private boolean automaticRegistrationAfterSocialLogin; + private boolean updateProfileOnInitialSocialLogin; @AttributeValue private int tokenLifespan; @AttributeValue @@ -128,12 +128,12 @@ public class RealmEntity implements Serializable { this.social = social; } - public boolean isAutomaticRegistrationAfterSocialLogin() { - return automaticRegistrationAfterSocialLogin; + public boolean isUpdateProfileOnInitialSocialLogin() { + return updateProfileOnInitialSocialLogin; } - public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) { - this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin; + public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) { + this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin; } public int getTokenLifespan() { diff --git a/pom.xml b/pom.xml index 48246591d2..91fd676291 100755 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,7 @@ 1.6.1 7.1.1.Final 8.0.0.CR1 + 20131018 http://keycloak.org @@ -245,6 +246,12 @@ freemarker 2.3.19 + + + org.json + json + ${json.version} + diff --git a/services/src/main/java/org/keycloak/services/FormService.java b/services/src/main/java/org/keycloak/services/FormService.java index f525bbd6f4..74629004e5 100755 --- a/services/src/main/java/org/keycloak/services/FormService.java +++ b/services/src/main/java/org/keycloak/services/FormService.java @@ -57,16 +57,6 @@ public interface FormService { private List socialProviders; - public Boolean getSocialRegistration() { - return socialRegistration; - } - - public void setSocialRegistration(Boolean socialRegistration) { - this.socialRegistration = socialRegistration; - } - - private Boolean socialRegistration; - public String getCode() { return code; } 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 0cd9fe3951..7f1ead8d42 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -102,8 +102,8 @@ public class RealmManager { if (rep.isRegistrationAllowed() != null) realm.setRegistrationAllowed(rep.isRegistrationAllowed()); if (rep.isVerifyEmail() != null) realm.setVerifyEmail(rep.isVerifyEmail()); if (rep.isResetPasswordAllowed() != null) realm.setResetPasswordAllowed(rep.isResetPasswordAllowed()); - if (rep.isAutomaticRegistrationAfterSocialLogin() != null) - realm.setAutomaticRegistrationAfterSocialLogin(rep.isAutomaticRegistrationAfterSocialLogin()); + if (rep.isUpdateProfileOnInitialSocialLogin() != null) + realm.setUpdateProfileOnInitialSocialLogin(rep.isUpdateProfileOnInitialSocialLogin()); if (rep.isSslNotRequired() != null) realm.setSslNotRequired((rep.isSslNotRequired())); if (rep.getAccessCodeLifespan() != null) realm.setAccessCodeLifespan(rep.getAccessCodeLifespan()); if (rep.getAccessCodeLifespanUserAction() != null) @@ -200,8 +200,8 @@ public class RealmManager { if (rep.isRegistrationAllowed() != null) newRealm.setRegistrationAllowed(rep.isRegistrationAllowed()); if (rep.isVerifyEmail() != null) newRealm.setVerifyEmail(rep.isVerifyEmail()); if (rep.isResetPasswordAllowed() != null) newRealm.setResetPasswordAllowed(rep.isResetPasswordAllowed()); - if (rep.isAutomaticRegistrationAfterSocialLogin() != null) - newRealm.setAutomaticRegistrationAfterSocialLogin(rep.isAutomaticRegistrationAfterSocialLogin()); + if (rep.isUpdateProfileOnInitialSocialLogin() != null) + newRealm.setUpdateProfileOnInitialSocialLogin(rep.isUpdateProfileOnInitialSocialLogin()); if (rep.getPrivateKey() == null || rep.getPublicKey() == null) { generateRealmKeys(newRealm); } else { @@ -475,7 +475,7 @@ public class RealmManager { rep.setRealm(realm.getName()); rep.setEnabled(realm.isEnabled()); rep.setSocial(realm.isSocial()); - rep.setAutomaticRegistrationAfterSocialLogin(realm.isAutomaticRegistrationAfterSocialLogin()); + rep.setUpdateProfileOnInitialSocialLogin(realm.isUpdateProfileOnInitialSocialLogin()); rep.setSslNotRequired(realm.isSslNotRequired()); rep.setPublicKey(realm.getPublicKeyPem()); rep.setPrivateKey(realm.getPrivateKeyPem()); 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 83fa595ea9..770d38641d 100755 --- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java +++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java @@ -143,7 +143,7 @@ public class SocialResource { AuthCallback callback = new AuthCallback(requestData.getSocialAttributes(), queryParams); - SocialUser socialUser = null; + SocialUser socialUser; try { socialUser = provider.processCallback(config, callback); } catch (SocialProviderException e) { @@ -160,41 +160,26 @@ public class SocialResource { } // Automatically register user into realm with his social username (don't redirect to registration screen) - if (realm.isAutomaticRegistrationAfterSocialLogin()) { + if (realm.getUser(socialUser.getUsername()) != null) { + // TODO: Username is already in realm. Show message and let user to bind accounts after he re-authenticate + throw new IllegalStateException("Username " + socialUser.getUsername() + + " already registered in the realm. TODO: bind accounts..."); - if (realm.getUser(socialUser.getUsername()) != null) { - // TODO: Username is already in realm. Show message and let user to bind accounts after he re-authenticate - throw new IllegalStateException("Username " + socialUser.getUsername() + - " already registered in the realm. TODO: bind accounts..."); - - // TODO: Maybe we should search also by email and bind accounts if user with this email is - // already registered. But actually Keycloak allows duplicate emails - } else { - user = realm.addUser(socialUser.getUsername()); - user.setEnabled(true); - user.setFirstName(socialUser.getFirstName()); - user.setLastName(socialUser.getLastName()); - user.setEmail(socialUser.getEmail()); - } - - realm.addSocialLink(user, socialLink); + // TODO: Maybe we should search also by email and bind accounts if user with this email is + // already registered. But actually Keycloak allows duplicate emails } else { - // Redirect user to registration screen with prefilled data from social provider - MultivaluedMap formData = fillRegistrationFormWithSocialData(socialUser); + user = realm.addUser(socialUser.getUsername()); + user.setEnabled(true); + user.setFirstName(socialUser.getFirstName()); + user.setLastName(socialUser.getLastName()); + user.setEmail(socialUser.getEmail()); - String requestId = UUID.randomUUID().toString(); - socialRequestManager.addRequest(requestId, RequestDetails.create(requestData).build()); - boolean secureOnly = !realm.isSslNotRequired(); - String cookiePath = Urls.socialBase(uriInfo.getBaseUri()).build().getPath(); - logger.debug("creating cookie for social registration - name: {0} path: {1}", SocialConstants.SOCIAL_REGISTRATION_COOKIE, - cookiePath); - NewCookie newCookie = new NewCookie(SocialConstants.SOCIAL_REGISTRATION_COOKIE, requestId, - cookiePath, null, "Added social cookie", NewCookie.DEFAULT_MAX_AGE, secureOnly); - response.addNewCookie(newCookie); - - return Flows.forms(realm, request, uriInfo).setFormData(formData).setSocialRegistration(true) - .forwardToRegistration(); + if (realm.isUpdateProfileOnInitialSocialLogin()) { + user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE); + } } + + realm.addSocialLink(user, socialLink); } if (!user.isEnabled()) { @@ -213,7 +198,7 @@ public class SocialResource { public Response redirectToProviderAuth(@PathParam("realm") final String realmId, @QueryParam("provider_id") final String providerId, @QueryParam("client_id") final String clientId, @QueryParam("scope") final String scope, @QueryParam("state") final String state, - @QueryParam("redirect_uri") final String redirectUri) { + @QueryParam("redirect_uri") String redirectUri) { RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealm(realmId); @@ -228,6 +213,21 @@ public class SocialResource { SocialProviderConfig config = new SocialProviderConfig(key, secret, callbackUri); + UserModel client = realm.getUser(clientId); + if (client == null) { + logger.warn("Unknown login requester: " + clientId); + return Flows.forms(realm, request, uriInfo).setError("Unknown login requester.").forwardToErrorPage(); + } + + if (!client.isEnabled()) { + logger.warn("Login requester not enabled."); + return Flows.forms(realm, request, uriInfo).setError("Login requester not enabled.").forwardToErrorPage(); + } + redirectUri = TokenService.verifyRedirectUri(redirectUri, client); + if (redirectUri == null) { + return Flows.forms(realm, request, uriInfo).setError("Invalid redirect_uri.").forwardToErrorPage(); + } + try { AuthRequest authRequest = provider.getAuthUrl(config); @@ -244,65 +244,6 @@ public class SocialResource { } } - @POST - @Path("{realm}/socialRegistration") - @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - public Response socialRegistration(@PathParam("realm") final String realmId, - final MultivaluedMap formData) { - RealmManager realmManager = new RealmManager(session); - RealmModel realm = realmManager.getRealm(realmId); - - Cookie cookie = headers.getCookies().get(SocialConstants.SOCIAL_REGISTRATION_COOKIE); - if (cookie == null) { - return Flows.forms(realm, request, uriInfo).setError("Social registration cookie not found").forwardToErrorPage(); - } - - String requestId = cookie.getValue(); - if (!socialRequestManager.isRequestId(requestId)) { - logger.error("Unknown requestId found in cookie. Maybe it's expired. requestId=" + requestId); - return Flows.forms(realm, request, uriInfo).setError("Unknown requestId found in cookie. Maybe it's expired.").forwardToErrorPage(); - } - - RequestDetails requestData = socialRequestManager.getData(requestId); - - if (realm == null || !realm.isEnabled()) { - return Flows.forms(realm, request, uriInfo).setError("Realm doesn't exists or is not enabled.").forwardToErrorPage(); - } - TokenService tokenService = new TokenService(realm, tokenManager); - resourceContext.initResource(tokenService); - - String clientId = requestData.getClientAttribute("clientId"); - String scope = requestData.getClientAttribute("scope"); - String state = requestData.getClientAttribute("state"); - String redirectUri = requestData.getClientAttribute("redirectUri"); - - Response response1 = tokenService.processRegisterImpl(clientId, scope, state, redirectUri, formData, true); - - // Some error occured during registration - if (response1 != null || request.wasForwarded()) { - logger.warn("Registration attempt wasn't successful. Request already forwarded or redirected."); - return response1; - } - - String username = formData.getFirst("username"); - UserModel user = realm.getUser(username); - if (user == null) { - // Normally shouldn't happen - throw new IllegalStateException("User " + username + " not found in the realm"); - } - realm.addSocialLink(user, new SocialLinkModel(requestData.getProviderId(), username)); - - // Expire cookie and invalidate requestData - String cookiePath = Urls.socialBase(uriInfo.getBaseUri()).build().getPath(); - NewCookie newCookie = new NewCookie(SocialConstants.SOCIAL_REGISTRATION_COOKIE, "", cookiePath, null, - "Expire social cookie", 0, false); - logger.debug("Expiring social registration cookie: {0}, path: {1}", SocialConstants.SOCIAL_REGISTRATION_COOKIE, cookiePath); - response.addNewCookie(newCookie); - socialRequestManager.retrieveData(requestId); - - return tokenService.processLogin(clientId, scope, state, redirectUri, formData); - } - private RequestDetails getRequestDetails(Map queryParams) { for (SocialProvider provider : SocialLoader.load()) { if (queryParams.containsKey(provider.getRequestIdParamName())) { @@ -324,25 +265,4 @@ public class SocialResource { return queryParams; } - protected MultivaluedMap fillRegistrationFormWithSocialData(SocialUser socialUser) { - MultivaluedMap formData = new MultivaluedMapImpl(); - formData.putSingle("username", socialUser.getUsername()); - - if (socialUser.getEmail() != null) { - formData.putSingle("email", socialUser.getEmail()); - } - - String fullName = null; - if (socialUser.getFirstName() == null) { - fullName = socialUser.getLastName(); - } else if (socialUser.getLastName() == null) { - fullName = socialUser.getFirstName(); - } else { - fullName = socialUser.getFirstName() + " " + socialUser.getLastName(); - } - - formData.putSingle("name", fullName); - return formData; - } - } diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java index 36bd3f4554..24c014cdc6 100755 --- a/services/src/main/java/org/keycloak/services/resources/TokenService.java +++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java @@ -276,20 +276,7 @@ public class TokenService { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processRegister(@QueryParam("client_id") final String clientId, @QueryParam("scope") final String scopeParam, @QueryParam("state") final String state, - @QueryParam("redirect_uri") final String redirect, final MultivaluedMap formData) { - Response registrationResponse = processRegisterImpl(clientId, scopeParam, state, redirect, formData, false); - - // If request has been already forwarded (either due to security or validation error) then we won't continue with login - if (registrationResponse != null || request.wasForwarded()) { - logger.warn("Registration attempt wasn't successful. Request already forwarded or redirected."); - return registrationResponse; - } else { - return processLogin(clientId, scopeParam, state, redirect, formData); - } - } - - public Response processRegisterImpl(String clientId, String scopeParam, String state, String redirect, - MultivaluedMap formData, boolean isSocialRegistration) { + @QueryParam("redirect_uri") String redirect, final MultivaluedMap formData) { OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager); if (!realm.isEnabled()) { @@ -328,16 +315,14 @@ public class TokenService { } if (error != null) { - return Flows.forms(realm, request, uriInfo).setError(error).setFormData(formData) - .setSocialRegistration(isSocialRegistration).forwardToRegistration(); + return Flows.forms(realm, request, uriInfo).setError(error).setFormData(formData).forwardToRegistration(); } String username = formData.getFirst("username"); UserModel user = realm.getUser(username); if (user != null) { - return Flows.forms(realm, request, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData) - .setSocialRegistration(isSocialRegistration).forwardToRegistration(); + return Flows.forms(realm, request, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData).forwardToRegistration(); } user = realm.addUser(username); @@ -364,8 +349,7 @@ public class TokenService { } } - - return null; + return processLogin(clientId, scopeParam, state, redirect, formData); } @Path("access/codes") @@ -647,7 +631,7 @@ public class TokenService { return location.build(); } - protected String verifyRedirectUri(String redirectUri, UserModel client) { + public static String verifyRedirectUri(String redirectUri, UserModel client) { if (redirectUri == null) { return client.getRedirectUris().size() == 1 ? client.getRedirectUris().iterator().next() : null; } else if (client.getRedirectUris().isEmpty()) { diff --git a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java index 5657ecf22c..d92e40326e 100755 --- a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java @@ -66,7 +66,6 @@ public class FormFlows { private HttpRequest request; private UserModel userModel; - private boolean socialRegistration; private AccessCodeEntry accessCode; private UriInfo uriInfo; @@ -119,7 +118,7 @@ public class FormFlows { } if (accessCode != null) { - uriBuilder.queryParam(CODE, accessCode.getCode()); + uriBuilder.replaceQueryParam(CODE, accessCode.getCode()); } if (queryParams != null) { @@ -134,7 +133,6 @@ public class FormFlows { // TODO find a better way to obtain contextPath // Getting context path by removing "rest/" substring from the BaseUri path formDataBean.setContextPath(requestURI.substring(0, requestURI.length() - 6)); - formDataBean.setSocialRegistration(socialRegistration); // Find the service and process relevant template Iterator itr = ServiceLoader.load(FormService.class).iterator(); @@ -261,12 +259,6 @@ public class FormFlows { return this; } - // Set flag whether user registration is triggered from social login - public FormFlows setSocialRegistration(boolean socialRegistration) { - this.socialRegistration = socialRegistration; - return this; - } - public FormFlows setFormData(MultivaluedMap formData) { this.formData = formData; return this; diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java index 042efaffde..7859c78595 100755 --- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java @@ -165,10 +165,6 @@ public class Urls { .build(realmId); } - public static URI socialRegisterAction(URI baseUri, String realmId) { - return socialBase(baseUri).path(SocialResource.class, "socialRegistration").build(realmId); - } - private static UriBuilder requiredActionsBase(URI baseUri) { return tokenBase(baseUri).path(TokenService.class, "getRequiredActionsService"); } diff --git a/services/src/test/java/org/keycloak/test/AdapterTest.java b/services/src/test/java/org/keycloak/test/AdapterTest.java index 0fc412fb9c..cd522d8f39 100755 --- a/services/src/test/java/org/keycloak/test/AdapterTest.java +++ b/services/src/test/java/org/keycloak/test/AdapterTest.java @@ -65,7 +65,7 @@ public class AdapterTest extends AbstractKeycloakTest { realmModel.setPrivateKeyPem("0234234"); realmModel.setPublicKeyPem("0234234"); realmModel.setTokenLifespan(1000); - realmModel.setAutomaticRegistrationAfterSocialLogin(true); + realmModel.setUpdateProfileOnInitialSocialLogin(true); realmModel.addDefaultRole("foo"); System.out.println(realmModel.getId()); @@ -78,7 +78,7 @@ public class AdapterTest extends AbstractKeycloakTest { Assert.assertEquals(realmModel.getName(), "JUGGLER"); Assert.assertEquals(realmModel.getPrivateKeyPem(), "0234234"); Assert.assertEquals(realmModel.getPublicKeyPem(), "0234234"); - Assert.assertEquals(realmModel.isAutomaticRegistrationAfterSocialLogin(), true); + Assert.assertEquals(realmModel.isUpdateProfileOnInitialSocialLogin(), true); Assert.assertEquals(1, realmModel.getDefaultRoles().size()); Assert.assertEquals("foo", realmModel.getDefaultRoles().get(0)); } @@ -93,7 +93,7 @@ public class AdapterTest extends AbstractKeycloakTest { realmModel.setPrivateKeyPem("0234234"); realmModel.setPublicKeyPem("0234234"); realmModel.setTokenLifespan(1000); - realmModel.setAutomaticRegistrationAfterSocialLogin(true); + realmModel.setUpdateProfileOnInitialSocialLogin(true); realmModel.addDefaultRole("foo"); System.out.println(realmModel.getId()); @@ -106,7 +106,7 @@ public class AdapterTest extends AbstractKeycloakTest { Assert.assertEquals(realmModel.getName(), "JUGGLER"); Assert.assertEquals(realmModel.getPrivateKeyPem(), "0234234"); Assert.assertEquals(realmModel.getPublicKeyPem(), "0234234"); - Assert.assertEquals(realmModel.isAutomaticRegistrationAfterSocialLogin(), true); + Assert.assertEquals(realmModel.isUpdateProfileOnInitialSocialLogin(), true); Assert.assertEquals(1, realmModel.getDefaultRoles().size()); Assert.assertEquals("foo", realmModel.getDefaultRoles().get(0)); diff --git a/services/src/test/java/org/keycloak/test/ImportTest.java b/services/src/test/java/org/keycloak/test/ImportTest.java index 2645f6d2a5..5c4550964c 100755 --- a/services/src/test/java/org/keycloak/test/ImportTest.java +++ b/services/src/test/java/org/keycloak/test/ImportTest.java @@ -37,7 +37,7 @@ public class ImportTest extends AbstractKeycloakTest { Assert.assertTrue(realm.isVerifyEmail()); - Assert.assertFalse(realm.isAutomaticRegistrationAfterSocialLogin()); + Assert.assertFalse(realm.isUpdateProfileOnInitialSocialLogin()); List creds = realm.getRequiredCredentials(); Assert.assertEquals(1, creds.size()); RequiredCredentialModel cred = creds.get(0); @@ -94,7 +94,7 @@ public class ImportTest extends AbstractKeycloakTest { RealmModel realm = manager.createRealm("demo", rep.getRealm()); manager.importRealm(rep, realm); - Assert.assertTrue(realm.isAutomaticRegistrationAfterSocialLogin()); + Assert.assertFalse(realm.isUpdateProfileOnInitialSocialLogin()); Assert.assertEquals(600, realm.getAccessCodeLifespanUserAction()); verifyRequiredCredentials(realm.getRequiredCredentials(), "password"); verifyRequiredCredentials(realm.getRequiredApplicationCredentials(), "totp"); diff --git a/services/src/test/java/org/keycloak/test/ModelTest.java b/services/src/test/java/org/keycloak/test/ModelTest.java index 35ea589728..32a428bc85 100755 --- a/services/src/test/java/org/keycloak/test/ModelTest.java +++ b/services/src/test/java/org/keycloak/test/ModelTest.java @@ -71,8 +71,8 @@ public class ModelTest extends AbstractKeycloakServerTest { } public static void assertEquals(RealmModel expected, RealmModel actual) { - Assert.assertEquals(expected.isAutomaticRegistrationAfterSocialLogin(), - actual.isAutomaticRegistrationAfterSocialLogin()); + Assert.assertEquals(expected.isUpdateProfileOnInitialSocialLogin(), + actual.isUpdateProfileOnInitialSocialLogin()); Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed()); Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed()); Assert.assertEquals(expected.isSocial(), actual.isSocial()); diff --git a/services/src/test/resources/testrealm-demo.json b/services/src/test/resources/testrealm-demo.json index fab9e9d364..753dfb0780 100755 --- a/services/src/test/resources/testrealm-demo.json +++ b/services/src/test/resources/testrealm-demo.json @@ -5,7 +5,7 @@ "accessCodeLifespan": 10, "accessCodeLifespanUserAction": 600, "sslNotRequired": true, - "automaticRegistrationAfterSocialLogin": true, + "updateProfileOnInitialSocialLogin": false, "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" ], diff --git a/social/core/pom.xml b/social/core/pom.xml index 47a694d180..473d1c0b53 100755 --- a/social/core/pom.xml +++ b/social/core/pom.xml @@ -14,9 +14,23 @@ - org.jboss.resteasy - jaxrs-api - provided + org.json + json + + + junit + junit + test + + + io.undertow + undertow-servlet + test + + + io.undertow + undertow-core + test diff --git a/social/core/src/main/java/org/keycloak/social/AuthRequest.java b/social/core/src/main/java/org/keycloak/social/AuthRequest.java index 481885dacd..9b213b0f05 100644 --- a/social/core/src/main/java/org/keycloak/social/AuthRequest.java +++ b/social/core/src/main/java/org/keycloak/social/AuthRequest.java @@ -21,8 +21,10 @@ */ package org.keycloak.social; -import javax.ws.rs.core.UriBuilder; +import java.io.UnsupportedEncodingException; import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; @@ -40,7 +42,10 @@ public class AuthRequest { public static AuthRequestBuilder create(String id, String path) { AuthRequestBuilder req = new AuthRequestBuilder(); req.id = id; - req.b = UriBuilder.fromUri(path); + + req.b = new StringBuilder(); + req.b.append(path); + req.attributes = new HashMap(); return req; } @@ -65,18 +70,33 @@ public class AuthRequest { public static class AuthRequestBuilder { - private UriBuilder b; + private StringBuilder b; + + private char sep; private Map attributes; private String id; private AuthRequestBuilder() { + sep = '?'; } public AuthRequestBuilder setQueryParam(String name, String value) { - b.queryParam(name, value); - return this; + try { + if (sep == '?') { + b.append(sep); + sep = '&'; + } else { + b.append(sep); + } + b.append(URLEncoder.encode(name, "UTF-8")); + b.append("="); + b.append(URLEncoder.encode(value, "UTF-8")); + return this; + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException(e); + } } public AuthRequestBuilder setAttribute(String name, String value) { @@ -85,7 +105,11 @@ public class AuthRequest { } public AuthRequest build() { - return new AuthRequest(id, b.build(), attributes); + try { + return new AuthRequest(id, new URI(b.toString()), attributes); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e); + } } } diff --git a/social/core/src/main/java/org/keycloak/social/utils/SimpleHttp.java b/social/core/src/main/java/org/keycloak/social/utils/SimpleHttp.java new file mode 100644 index 0000000000..d5ef204f07 --- /dev/null +++ b/social/core/src/main/java/org/keycloak/social/utils/SimpleHttp.java @@ -0,0 +1,142 @@ +package org.keycloak.social.utils; + +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.StringWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Stian Thorgersen + */ +public class SimpleHttp { + + private String url; + private String method; + private Map headers; + private Map params; + + private SimpleHttp(String url, String method) { + this.url = url; + this.method = method; + } + + public static SimpleHttp doGet(String url) { + return new SimpleHttp(url, "GET"); + } + + public static SimpleHttp doPost(String url) { + return new SimpleHttp(url, "POST"); + } + + public SimpleHttp header(String name, String value) { + if (headers == null) { + headers = new HashMap(); + } + headers.put(name, value); + return this; + } + + public SimpleHttp param(String name, String value) { + if (params == null) { + params = new HashMap(); + } + params.put(name, value); + return this; + } + + public JSONObject asJson() throws IOException { + return new JSONObject(asString()); + } + + public String asString() throws IOException { + boolean get = method.equals("GET"); + boolean post = method.equals("POST"); + + StringBuilder sb = new StringBuilder(); + if (get) { + sb.append(url); + } + + if (params != null) { + boolean f = true; + for (Map.Entry p : params.entrySet()) { + if (f) { + f = false; + if (get) { + sb.append("?"); + } + } else { + sb.append("&"); + } + sb.append(URLEncoder.encode(p.getKey(), "UTF-8")); + sb.append("="); + sb.append(URLEncoder.encode(p.getValue(), "UTF-8")); + } + } + + if (get) { + url = sb.toString(); + } + + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + OutputStream os = null; + InputStream is = null; + + try { + connection.setRequestMethod(method); + + if (headers != null) { + for (Map.Entry h : headers.entrySet()) { + connection.setRequestProperty(h.getKey(), h.getValue()); + } + } + + if (post) { + String data = sb.toString(); + + connection.setDoOutput(true); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + connection.setRequestProperty("Content-Length", String.valueOf(data.length())); + + os = connection.getOutputStream(); + os.write(data.getBytes()); + } else { + connection.setDoOutput(false); + } + + is = connection.getInputStream(); + return toString(is); + } finally { + if (os != null) { + os.close(); + } + + if (is != null) { + is.close(); + } + } + } + + private String toString(InputStream is) throws IOException { + InputStreamReader reader = new InputStreamReader(is); + + StringWriter writer = new StringWriter(); + + char[] buffer = new char[1024 * 4]; + for (int n = reader.read(buffer); n != -1; n = reader.read(buffer)) { + writer.write(buffer, 0, n); + } + + return writer.toString(); + } + +} diff --git a/social/core/src/main/test/java/org/keycloak/social/utils/SimpleHttpTest.java b/social/core/src/main/test/java/org/keycloak/social/utils/SimpleHttpTest.java new file mode 100644 index 0000000000..dea58c7f1d --- /dev/null +++ b/social/core/src/main/test/java/org/keycloak/social/utils/SimpleHttpTest.java @@ -0,0 +1,100 @@ +package org.keycloak.social.utils; + +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.ServletInfo; +import org.json.JSONObject; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +import static io.undertow.servlet.Servlets.servlet; +import static org.junit.Assert.assertEquals; + +/** + * @author Stian Thorgersen + */ +public class SimpleHttpTest { + + private UndertowServer server; + + @Before + public void before() { + server = new UndertowServer("localhost", 8081); + + DeploymentInfo deploymentInfo = new DeploymentInfo(); + deploymentInfo.setClassLoader(getClass().getClassLoader()); + deploymentInfo.setDeploymentName("test"); + deploymentInfo.setContextPath("/"); + + ServletInfo servlet = servlet("ToJsonServlet", ToJsonServlet.class) + .addMapping("/tojson"); + + deploymentInfo.addServlet(servlet); + + server.deploy(deploymentInfo); + + server.start(); + } + + @After + public void after() { + server.stop(); + } + + @Test + public void testPostNoParams() throws IOException { + JSONObject o = SimpleHttp.doPost("http://localhost:8081/tojson").asJson(); + JSONObject p = o.getJSONObject("params"); + + assertEquals(0, p.length()); + } + + @Test + public void testPost() throws IOException { + JSONObject o = SimpleHttp.doPost("http://localhost:8081/tojson").param("key-one", "value one ;)").param("key-two", "value two!&").asJson(); + JSONObject p = o.getJSONObject("params"); + + assertEquals(2, p.length()); + assertEquals("value one ;)", p.getString("key-one")); + assertEquals("value two!&", p.getString("key-two")); + } + + @Test + public void testPostCustomHeader() throws IOException { + JSONObject o = SimpleHttp.doPost("http://localhost:8081/tojson").header("Accept", "application/json").header("Authorization", "bearer dsfsadfsdf").asJson(); + JSONObject h = o.getJSONObject("headers"); + + assertEquals("application/json", h.getString("Accept")); + assertEquals("bearer dsfsadfsdf", h.getString("Authorization")); + } + + @Test + public void testGetNoParams() throws IOException { + JSONObject o = SimpleHttp.doGet("http://localhost:8081/tojson").asJson(); + JSONObject p = o.getJSONObject("params"); + + assertEquals(0, p.length()); + } + + @Test + public void testGet() throws IOException { + JSONObject o = SimpleHttp.doGet("http://localhost:8081/tojson").param("key-one", "value one ;)").param("key-two", "value two!&").asJson(); + JSONObject p = o.getJSONObject("params"); + + assertEquals(2, p.length()); + assertEquals("value one ;)", p.getString("key-one")); + assertEquals("value two!&", p.getString("key-two")); + } + + @Test + public void testGetCustomHeader() throws IOException { + JSONObject o = SimpleHttp.doGet("http://localhost:8081/tojson").header("Accept", "application/json").header("Authorization", "bearer dsfsadfsdf").asJson(); + JSONObject h = o.getJSONObject("headers"); + + assertEquals("application/json", h.getString("Accept")); + assertEquals("bearer dsfsadfsdf", h.getString("Authorization")); + } + +} diff --git a/social/core/src/main/test/java/org/keycloak/social/utils/ToJsonServlet.java b/social/core/src/main/test/java/org/keycloak/social/utils/ToJsonServlet.java new file mode 100644 index 0000000000..1d738e7da1 --- /dev/null +++ b/social/core/src/main/test/java/org/keycloak/social/utils/ToJsonServlet.java @@ -0,0 +1,50 @@ +package org.keycloak.social.utils; + +import org.json.JSONObject; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Enumeration; + +/** + * @author Stian Thorgersen + */ +public class ToJsonServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + toJson(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + toJson(req, resp); + } + + private void toJson(HttpServletRequest req, HttpServletResponse resp) throws IOException { + JSONObject o = new JSONObject(); + + JSONObject headers = new JSONObject(); + Enumeration headerNames = req.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String n = headerNames.nextElement(); + headers.put(n, req.getHeader(n)); + } + o.put("headers", headers); + + JSONObject params = new JSONObject(); + Enumeration parameterNames = req.getParameterNames(); + while (parameterNames.hasMoreElements()) { + String n = parameterNames.nextElement(); + params.put(n, req.getParameter(n)); + } + o.put("params", params); + + resp.setContentType("application/json"); + resp.getOutputStream().write(o.toString().getBytes()); + } + +} diff --git a/social/core/src/main/test/java/org/keycloak/social/utils/UndertowServer.java b/social/core/src/main/test/java/org/keycloak/social/utils/UndertowServer.java new file mode 100644 index 0000000000..f856a429c6 --- /dev/null +++ b/social/core/src/main/test/java/org/keycloak/social/utils/UndertowServer.java @@ -0,0 +1,63 @@ +package org.keycloak.social.utils; + +import io.undertow.Undertow; +import io.undertow.server.handlers.PathHandler; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.DeploymentManager; +import io.undertow.servlet.api.ServletContainer; + +import javax.servlet.ServletException; + +/** + * @author Stian Thorgersen + */ +public class UndertowServer { + + private PathHandler root; + private ServletContainer container; + private Undertow server; + private String hostname; + private int port; + + public UndertowServer(String hostname, int port) { + this.hostname = hostname; + this.port = port; + + root = new PathHandler(); + container = ServletContainer.Factory.newInstance(); + } + + public void start() { + Undertow.Builder builder = Undertow.builder().addListener(port, hostname); + server = builder.setHandler(root).build(); + server.start(); + } + + public void stop() { + if (server != null) { + server.stop(); + server = null; + } + } + + public void deploy(DeploymentInfo deploymentInfo) { + DeploymentManager manager = container.addDeployment(deploymentInfo); + manager.deploy(); + try { + root.addPath(deploymentInfo.getContextPath(), manager.start()); + } catch (ServletException e) { + throw new RuntimeException(e); + } + } + + public void undeploy(String deploymentName) { + DeploymentManager deployment = container.getDeployment(deploymentName); + try { + deployment.stop(); + } catch (ServletException e) { + throw new RuntimeException(e); + } + } + +} + diff --git a/social/google/pom.xml b/social/google/pom.xml index cda69f8847..e7a72d3a23 100755 --- a/social/google/pom.xml +++ b/social/google/pom.xml @@ -17,20 +17,6 @@ org.keycloak keycloak-social-core ${project.version} - provided - - - - com.google.api-client - google-api-client - - - com.google.http-client - google-http-client-jackson - - - com.google.apis - google-api-services-oauth2 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 2f743b796f..87ea93f348 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 @@ -21,23 +21,16 @@ */ package org.keycloak.social.google; -import java.util.UUID; - +import org.json.JSONObject; import org.keycloak.social.AuthCallback; import org.keycloak.social.AuthRequest; +import org.keycloak.social.utils.SimpleHttp; import org.keycloak.social.SocialProvider; import org.keycloak.social.SocialProviderConfig; import org.keycloak.social.SocialProviderException; import org.keycloak.social.SocialUser; -import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.client.json.jackson.JacksonFactory; -import com.google.api.services.oauth2.Oauth2; -import com.google.api.services.oauth2.model.Tokeninfo; -import com.google.api.services.oauth2.model.Userinfo; +import java.util.UUID; /** * @author Stian Thorgersen @@ -48,11 +41,11 @@ public class GoogleProvider implements SocialProvider { private static final String AUTH_PATH = "https://accounts.google.com/o/oauth2/auth"; - private static final String DEFAULT_SCOPE = "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email"; + private static final String TOKEN_PATH = "https://accounts.google.com/o/oauth2/token"; - private static final JacksonFactory JSON_FACTORY = new JacksonFactory(); + private static final String PROFILE_PATH = "https://www.googleapis.com/plus/v1/people/me/openIdConnect"; - private static final NetHttpTransport TRANSPORT = new NetHttpTransport(); + private static final String DEFAULT_SCOPE = "openid profile email"; @Override public String getId() { @@ -82,32 +75,22 @@ public class GoogleProvider implements SocialProvider { throw new SocialProviderException("Invalid state"); } - GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(TRANSPORT, JSON_FACTORY, - config.getKey(), config.getSecret(), code, config.getCallbackUrl().toString()) - .execute(); + JSONObject token = SimpleHttp.doPost(TOKEN_PATH).param("code", code).param("client_id", config.getKey()) + .param("client_secret", config.getSecret()) + .param("redirect_uri", config.getCallbackUrl()) + .param("grant_type", "authorization_code").asJson(); - GoogleCredential credential = new GoogleCredential.Builder().setJsonFactory(JSON_FACTORY).setTransport(TRANSPORT) - .setClientSecrets(config.getKey(), config.getSecret()).build() - .setFromTokenResponse(tokenResponse); + String accessToken = token.getString("access_token"); - Oauth2 oauth2 = new Oauth2.Builder(TRANSPORT, JSON_FACTORY, credential).build(); + JSONObject profile = SimpleHttp.doGet(PROFILE_PATH).header("Authorization", "Bearer " + accessToken).asJson(); - Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(credential.getAccessToken()).execute(); + SocialUser user = new SocialUser(profile.getString("sub")); - if (tokenInfo.containsKey("error")) { - throw new SocialProviderException((String) tokenInfo.get("error")); - } + user.setUsername(profile.getString("email")); - Userinfo userInfo = oauth2.userinfo().get().execute(); - - SocialUser user = new SocialUser(userInfo.getId()); - - // Use email as username for Google - user.setUsername(userInfo.getEmail()); - - user.setFirstName(userInfo.getGivenName()); - user.setLastName(userInfo.getFamilyName()); - user.setEmail(userInfo.getEmail()); + user.setFirstName(profile.optString("given_name")); + user.setLastName(profile.optString("family_name")); + user.setEmail(profile.optString("email")); return user; } catch (Exception e) { 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 bab9f434fa..5e5bd1dc3e 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocial.java @@ -42,7 +42,7 @@ public class DummySocial implements SocialProvider { throw new SocialProviderException("Invalid state"); } - String username = callback.getQueryParam("access_token"); + String username = callback.getQueryParam("username"); SocialUser user = new SocialUser(username); user.setEmail(username + "@dummy-social"); user.setUsername(username); 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 f6a49112e4..fe55e34a2c 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/DummySocialServlet.java @@ -12,6 +12,7 @@ import java.io.PrintWriter; import java.net.URI; import java.nio.charset.Charset; import java.util.List; +import java.util.UUID; public class DummySocialServlet extends HttpServlet { @@ -31,7 +32,6 @@ public class DummySocialServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - String accessToken = req.getParameter("username"); String state = null; String redirectUri = null; @@ -50,7 +50,7 @@ public class DummySocialServlet extends HttpServlet { } } - String redirect = redirectUri + "?access_token=" + accessToken + "&token_type=bearer&state=" + state; + String redirect = redirectUri + "?username=" + req.getParameter("username") + "&state=" + state + "&code=" + UUID.randomUUID().toString(); resp.sendRedirect(redirect); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java index d25959d6e1..9fe02ef3fb 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java @@ -59,6 +59,18 @@ public class LoginUpdateProfilePage extends AbstractPage { return loginErrorMessage != null ? loginErrorMessage.getText() : null; } + public String getFirstName() { + return firstNameInput.getAttribute("value"); + } + + public String getLastName() { + return lastNameInput.getAttribute("value"); + } + + public String getEmail() { + return emailInput.getAttribute("value"); + } + public boolean isCurrent() { return driver.getTitle().equals("Update Account Information"); } 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 d247d392df..d1b3d51b95 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 @@ -35,6 +35,7 @@ import org.keycloak.testsuite.OAuthClient.AccessTokenResponse; import org.keycloak.testsuite.pages.AppPage; import org.keycloak.testsuite.pages.AppPage.RequestType; import org.keycloak.testsuite.pages.LoginPage; +import org.keycloak.testsuite.pages.LoginUpdateProfilePage; import org.keycloak.testsuite.pages.RegisterPage; import org.keycloak.testsuite.rule.KeycloakRule; import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup; @@ -55,7 +56,7 @@ public class SocialLoginTest { @Override public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) { appRealm.setSocial(true); - appRealm.setAutomaticRegistrationAfterSocialLogin(true); + appRealm.setUpdateProfileOnInitialSocialLogin(false); HashMap socialConfig = new HashMap(); socialConfig.put("dummy.key", "1234"); @@ -77,7 +78,7 @@ public class SocialLoginTest { protected LoginPage loginPage; @WebResource - protected RegisterPage registerPage; + protected LoginUpdateProfilePage profilePage; @WebResource protected OAuthClient oauth; @@ -106,11 +107,11 @@ public class SocialLoginTest { } @Test - public void registerRequired() { + public void profileUpdateRequired() { keycloakRule.configure(new KeycloakSetup() { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - appRealm.setAutomaticRegistrationAfterSocialLogin(false); + appRealm.setUpdateProfileOnInitialSocialLogin(true); } }); @@ -122,21 +123,20 @@ public class SocialLoginTest { driver.findElement(By.id("username")).sendKeys("dummy-user-reg"); driver.findElement(By.id("submit")).click(); - registerPage.isCurrent(); + profilePage.isCurrent(); - Assert.assertEquals("", registerPage.getFirstName()); - Assert.assertEquals("", registerPage.getLastName()); - Assert.assertEquals("dummy-user-reg@dummy-social", registerPage.getEmail()); - Assert.assertEquals("dummy-user-reg", registerPage.getUsername()); + Assert.assertEquals("", profilePage.getFirstName()); + Assert.assertEquals("", profilePage.getLastName()); + Assert.assertEquals("dummy-user-reg@dummy-social", profilePage.getEmail()); - registerPage.register("Dummy", "User", "dummy-user-reg@dummy-social", "dummy-user-reg", "password", "password"); + profilePage.update("Dummy", "User", "dummy-user-reg@dummy-social"); Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); } finally { keycloakRule.configure(new KeycloakSetup() { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - appRealm.setAutomaticRegistrationAfterSocialLogin(true); + appRealm.setUpdateProfileOnInitialSocialLogin(false); } }); } From c5366f1c817aa8f2af854f3559c92978283bb1e4 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Fri, 17 Jan 2014 09:30:56 +0000 Subject: [PATCH 2/3] KEYCLOAK-264 Remove option to enable/disable acct mngmt --- .../admin/partials/realm-detail.html | 4 --- .../idm/RealmRepresentation.java | 9 ------- examples/as7-eap-demo/testrealm.json | 1 - examples/wildfly-demo/testrealm.json | 1 - .../services/managers/ApplianceBootstrap.java | 1 - .../services/managers/RealmManager.java | 27 +++++-------------- .../java/org/keycloak/test/AdapterTest.java | 4 +-- .../keycloak/test/ApplicationModelTest.java | 2 +- .../java/org/keycloak/test/ImportTest.java | 2 +- .../src/test/resources/testrealm.json | 1 - 10 files changed, 10 insertions(+), 42 deletions(-) diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html index 7975742bbf..f0117d514d 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html @@ -61,10 +61,6 @@
-
- - -
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index 376de43a5e..5cb379975d 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -17,7 +17,6 @@ public class RealmRepresentation { protected Integer accessCodeLifespan; protected Integer accessCodeLifespanUserAction; protected Boolean enabled; - protected Boolean accountManagement; protected Boolean sslNotRequired; protected Boolean registrationAllowed; protected Boolean verifyEmail; @@ -107,14 +106,6 @@ public class RealmRepresentation { this.enabled = enabled; } - public Boolean getAccountManagement() { - return accountManagement; - } - - public void setAccountManagement(Boolean accountManagement) { - this.accountManagement = accountManagement; - } - public Boolean isSslNotRequired() { return sslNotRequired; } diff --git a/examples/as7-eap-demo/testrealm.json b/examples/as7-eap-demo/testrealm.json index da8b804b03..7f39c9adc8 100755 --- a/examples/as7-eap-demo/testrealm.json +++ b/examples/as7-eap-demo/testrealm.json @@ -4,7 +4,6 @@ "tokenLifespan": 3000, "accessCodeLifespan": 10, "accessCodeLifespanUserAction": 6000, - "accountManagement": true, "sslNotRequired": true, "registrationAllowed": false, "social": false, diff --git a/examples/wildfly-demo/testrealm.json b/examples/wildfly-demo/testrealm.json index da8b804b03..7f39c9adc8 100755 --- a/examples/wildfly-demo/testrealm.json +++ b/examples/wildfly-demo/testrealm.json @@ -4,7 +4,6 @@ "tokenLifespan": 3000, "accessCodeLifespan": 10, "accessCodeLifespanUserAction": 6000, - "accountManagement": true, "sslNotRequired": true, "registrationAllowed": false, "social": false, diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java index 554a910f0b..04986f3b36 100755 --- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java +++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java @@ -76,7 +76,6 @@ public class ApplianceBootstrap { adminConsole.grantRole(adminUser, adminRole); - manager.enableAccountManagement(realm); ApplicationModel accountApp = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION); for (String r : accountApp.getDefaultRoles()) { accountApp.grantRole(adminUser, accountApp.getRole(r)); 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 7f1ead8d42..54908a0cd0 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -78,6 +78,9 @@ public class RealmManager { realm.setName(name); realm.addRole(Constants.APPLICATION_ROLE); realm.addRole(Constants.IDENTITY_REQUESTER_ROLE); + + setupAccountManagement(realm); + return realm; } @@ -125,12 +128,6 @@ public class RealmManager { realm.updateDefaultRoles(rep.getDefaultRoles().toArray(new String[rep.getDefaultRoles().size()])); } - if (rep.getAccountManagement() != null && rep.getAccountManagement()) { - enableAccountManagement(realm); - } else { - disableAccountManagement(realm); - } - if (rep.getSmtpServer() != null) { realm.setSmtpConfig(new HashMap(rep.getSmtpServer())); } @@ -144,10 +141,12 @@ public class RealmManager { } } - public void enableAccountManagement(RealmModel realm) { + private void setupAccountManagement(RealmModel realm) { ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION); if (application == null) { application = realm.addApplication(Constants.ACCOUNT_APPLICATION); + application.setEnabled(true); + application.addDefaultRole(Constants.ACCOUNT_PROFILE_ROLE); application.addDefaultRole(Constants.ACCOUNT_MANAGE_ROLE); @@ -160,14 +159,6 @@ public class RealmManager { RoleModel applicationRole = realm.getRole(Constants.APPLICATION_ROLE); realm.grantRole(application.getApplicationUser(), applicationRole); } - application.setEnabled(true); - } - - public void disableAccountManagement(RealmModel realm) { - ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION); - if (application != null) { - application.setEnabled(false); // TODO Should we delete the application instead? - } } public RealmModel importRealm(RealmRepresentation rep, UserModel realmCreator) { @@ -180,7 +171,6 @@ public class RealmManager { return realm; } - public void importRealm(RealmRepresentation rep, RealmModel newRealm) { newRealm.setName(rep.getRealm()); if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled()); @@ -270,10 +260,6 @@ public class RealmManager { } - if (rep.getAccountManagement() != null && rep.getAccountManagement()) { - enableAccountManagement(newRealm); - } - // Now that all possible users and applications are created (users, apps, and oauth clients), do role mappings and scope mappings Map appMap = newRealm.getApplicationNameMap(); @@ -492,7 +478,6 @@ public class RealmManager { } ApplicationModel accountManagementApplication = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION); - rep.setAccountManagement(accountManagementApplication != null && accountManagementApplication.isEnabled()); List defaultRoles = realm.getDefaultRoles(); if (!defaultRoles.isEmpty()) { diff --git a/services/src/test/java/org/keycloak/test/AdapterTest.java b/services/src/test/java/org/keycloak/test/AdapterTest.java index cd522d8f39..08a0057f3a 100755 --- a/services/src/test/java/org/keycloak/test/AdapterTest.java +++ b/services/src/test/java/org/keycloak/test/AdapterTest.java @@ -438,8 +438,8 @@ public class AdapterTest extends AbstractKeycloakTest { RealmModel otherRealm = adapter.createRealm("other"); otherRealm.addUser("bburke"); - Assert.assertEquals(1, otherRealm.getUsers().size()); - Assert.assertEquals(1, otherRealm.searchForUser("u").size()); + Assert.assertEquals(2, otherRealm.getUsers().size()); + Assert.assertEquals(1, otherRealm.searchForUser("bu").size()); } diff --git a/services/src/test/java/org/keycloak/test/ApplicationModelTest.java b/services/src/test/java/org/keycloak/test/ApplicationModelTest.java index e32248195c..1942b41f01 100755 --- a/services/src/test/java/org/keycloak/test/ApplicationModelTest.java +++ b/services/src/test/java/org/keycloak/test/ApplicationModelTest.java @@ -68,7 +68,7 @@ public class ApplicationModelTest extends AbstractKeycloakServerTest { public void persist() { RealmModel persisted = manager.getRealm(realm.getId()); - assertEquals(application, persisted.getApplications().get(0)); + assertEquals(application, persisted.getApplicationNameMap().get("app-name")); } @Test diff --git a/services/src/test/java/org/keycloak/test/ImportTest.java b/services/src/test/java/org/keycloak/test/ImportTest.java index 5c4550964c..383c683dc4 100755 --- a/services/src/test/java/org/keycloak/test/ImportTest.java +++ b/services/src/test/java/org/keycloak/test/ImportTest.java @@ -54,7 +54,7 @@ public class ImportTest extends AbstractKeycloakTest { Assert.assertEquals(0, realm.getSocialLinks(user).size()); List resources = realm.getApplications(); - Assert.assertEquals(2, resources.size()); + Assert.assertEquals(3, resources.size()); // Test scope relationship ApplicationModel application = realm.getApplicationNameMap().get("Application"); diff --git a/testsuite/integration/src/test/resources/testrealm.json b/testsuite/integration/src/test/resources/testrealm.json index c25ece4f1c..755d9ea516 100755 --- a/testsuite/integration/src/test/resources/testrealm.json +++ b/testsuite/integration/src/test/resources/testrealm.json @@ -7,7 +7,6 @@ "accessCodeLifespanUserAction": 600, "sslNotRequired": true, "registrationAllowed": true, - "accountManagement": true, "resetPasswordAllowed": 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", From 070c0ddba4f74e2feeef0b4a05124009153442ca Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Fri, 17 Jan 2014 10:03:13 +0000 Subject: [PATCH 3/3] Renamed registration to default roles, add default roles to all users when they are created --- .../resources/META-INF/resources/admin/js/app.js | 6 +++--- .../resources/admin/js/controllers/realm.js | 4 ++-- .../admin/partials/realm-credentials.html | 2 +- ...egistration.html => realm-default-roles.html} | 2 +- .../resources/admin/partials/realm-detail.html | 2 +- .../resources/admin/partials/realm-keys.html | 2 +- .../resources/admin/partials/realm-smtp.html | 2 +- .../resources/admin/partials/realm-social.html | 2 +- .../resources/admin/partials/realm-tokens.html | 2 +- .../resources/admin/partials/role-detail.html | 2 +- .../resources/admin/partials/role-list.html | 2 +- .../org/keycloak/models/jpa/RealmAdapter.java | 14 +++++++++++++- .../keycloak/models/picketlink/RealmAdapter.java | 16 ++++++++++++++-- .../services/resources/TokenService.java | 10 ---------- .../keycloak/testsuite/account/ProfileTest.java | 6 +++--- .../keycloak/testsuite/forms/AccountTest.java | 7 ++++--- 16 files changed, 48 insertions(+), 33 deletions(-) rename admin-ui/src/main/resources/META-INF/resources/admin/partials/{realm-registration.html => realm-default-roles.html} (99%) diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js index 701d4a0389..401be0c6bc 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js +++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js @@ -82,8 +82,8 @@ module.config([ '$routeProvider', function($routeProvider) { }, controller : 'RealmSocialCtrl' }) - .when('/realms/:realm/registration-settings', { - templateUrl : 'partials/realm-registration.html', + .when('/realms/:realm/default-roles', { + templateUrl : 'partials/realm-default-roles.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); @@ -95,7 +95,7 @@ module.config([ '$routeProvider', function($routeProvider) { return RoleListLoader(); } }, - controller : 'RealmRegistrationCtrl' + controller : 'RealmDefaultRolesCtrl' }) .when('/realms/:realm/required-credentials', { templateUrl : 'partials/realm-credentials.html', diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js index d74a7ae092..aa6199320d 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js +++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/realm.js @@ -427,9 +427,9 @@ module.controller('RealmRequiredCredentialsCtrl', function($scope, Realm, realm, }; }); -module.controller('RealmRegistrationCtrl', function ($scope, Realm, realm, applications, roles, Notifications, ApplicationRole, Application) { +module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, applications, roles, Notifications, ApplicationRole, Application) { - console.log('RealmRegistrationCtrl'); + console.log('RealmDefaultRolesCtrl'); $scope.realm = realm; diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html index 9d0e0f68cf..d027574ebe 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html @@ -6,8 +6,8 @@
  • General
  • Social
  • -
  • Registration
  • Roles
  • +
  • Default Roles
  • Credentials
  • Token
  • Keys
  • diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-registration.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-default-roles.html similarity index 99% rename from admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-registration.html rename to admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-default-roles.html index 867305f2b4..e2a5314a64 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-registration.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-default-roles.html @@ -6,8 +6,8 @@
    • General
    • Social
    • -
    • Registration
    • Roles
    • +
    • Default Roles
    • Credentials
    • Token
    • Keys
    • diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html index f0117d514d..726d56f005 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-detail.html @@ -6,8 +6,8 @@
      • General
      • Social
      • -
      • Registration
      • Roles
      • +
      • Default Roles
      • Credentials
      • Token
      • Keys
      • diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-keys.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-keys.html index f60f38b993..a05f12bae2 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-keys.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-keys.html @@ -6,8 +6,8 @@
        • General
        • Social
        • -
        • Registration
        • Roles
        • +
        • Default Roles
        • Credentials
        • Token
        • Keys
        • diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html index f731d19c06..1f685f9f0f 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-smtp.html @@ -6,8 +6,8 @@
          • General
          • Social
          • -
          • Registration
          • Roles
          • +
          • Default Roles
          • Credentials
          • Token
          • Keys
          • diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html index 723d5fc18a..bd6dde2871 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-social.html @@ -6,8 +6,8 @@
            • General
            • Social
            • -
            • Registration
            • Roles
            • +
            • Default Roles
            • Credentials
            • Token
            • Keys
            • diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html index 7c77f6adb3..0ea6617ef7 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-tokens.html @@ -6,8 +6,8 @@
              • General
              • Social
              • -
              • Registration
              • Roles
              • +
              • Default Roles
              • Credentials
              • Token
              • Keys
              • diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html index 6fd412b257..3e05f3495c 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-detail.html @@ -6,8 +6,8 @@
                • General
                • Social
                • -
                • Registration
                • Roles
                • +
                • Default Roles
                • Credentials
                • Token
                • Keys
                • diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html index 49d6a9a920..213342a9ba 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/role-list.html @@ -6,8 +6,8 @@
                  • General
                  • Social
                  • -
                  • Registration
                  • Roles
                  • +
                  • Default Roles
                  • Credentials
                  • Token
                  • Keys
                  • 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 0488bddd81..9b9679d7fc 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 @@ -444,7 +444,19 @@ public class RealmAdapter implements RealmModel { entity.setRealm(realm); em.persist(entity); em.flush(); - return new UserAdapter(entity); + UserModel userModel = new UserAdapter(entity); + + for (String r : getDefaultRoles()) { + grantRole(userModel, getRole(r)); + } + + for (ApplicationModel application : getApplications()) { + for (String r : application.getDefaultRoles()) { + application.grantRole(userModel, application.getRole(r)); + } + } + + return userModel; } @Override 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 13d78a35ed..4b0b005477 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 @@ -516,7 +516,19 @@ public class RealmAdapter implements RealmModel { if (user != null) throw new IllegalStateException("User already exists"); user = new User(username); getIdm().add(user); - return new UserAdapter(user, getIdm()); + UserAdapter userModel = new UserAdapter(user, getIdm()); + + for (String r : getDefaultRoles()) { + grantRole(userModel, getRole(r)); + } + + for (ApplicationModel application : getApplications()) { + for (String r : application.getDefaultRoles()) { + application.grantRole(userModel, application.getRole(r)); + } + } + + return userModel; } @Override @@ -885,7 +897,7 @@ public class RealmAdapter implements RealmModel { @Override public Set getSocialLinks(UserModel user) { RelationshipQuery query = getRelationshipManager().createRelationshipQuery(SocialLinkRelationship.class); - query.setParameter(SocialLinkRelationship.USER, ((UserAdapter)user).getUser()); + query.setParameter(SocialLinkRelationship.USER, ((UserAdapter) user).getUser()); List plSocialLinks = query.getResultList(); Set results = new HashSet(); diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java index 24c014cdc6..2ce30a524d 100755 --- a/services/src/main/java/org/keycloak/services/resources/TokenService.java +++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java @@ -339,16 +339,6 @@ public class TokenService { realm.updateCredential(user, credentials); } - for (String r : realm.getDefaultRoles()) { - realm.grantRole(user, realm.getRole(r)); - } - - for (ApplicationModel application : realm.getApplications()) { - for (String r : application.getDefaultRoles()) { - application.grantRole(user, application.getRole(r)); - } - } - return processLogin(clientId, scopeParam, state, redirect, formData); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java index e3fe2dd4e9..7a8f2a24bb 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java @@ -54,12 +54,12 @@ public class ProfileTest { user.setAttribute("key2", "value2"); ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION); - for (String r : accountApp.getDefaultRoles()) { - accountApp.grantRole(user, accountApp.getRole(r)); - } UserModel user2 = appRealm.addUser("test-user-no-access@localhost"); user2.setEnabled(true); + for (String r : accountApp.getDefaultRoles()) { + accountApp.deleteRoleMapping(user2, accountApp.getRole(r)); + } UserCredentialModel creds = new UserCredentialModel(); creds.setType(CredentialRepresentation.PASSWORD); creds.setValue("password"); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java index 020a838fea..3a06d4495f 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/AccountTest.java @@ -52,13 +52,14 @@ public class AccountTest { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { UserModel user = appRealm.getUser("test-user@localhost"); + ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION); - for (String r : accountApp.getDefaultRoles()) { - accountApp.grantRole(user, accountApp.getRole(r)); - } UserModel user2 = appRealm.addUser("test-user-no-access@localhost"); user2.setEnabled(true); + for (String r : accountApp.getDefaultRoles()) { + accountApp.deleteRoleMapping(user2, accountApp.getRole(r)); + } UserCredentialModel creds = new UserCredentialModel(); creds.setType(CredentialRepresentation.PASSWORD); creds.setValue("password");