Merge pull request #159 from stianst/master
KEYCLOAK-64 KEYCLOAK-246 Updated social to use update profile required a...
This commit is contained in:
commit
7a6f67dfdd
37 changed files with 544 additions and 302 deletions
|
@ -46,8 +46,8 @@
|
||||||
<input ng-model="realm.social" name="social" id="social" onoffswitch />
|
<input ng-model="realm.social" name="social" id="social" onoffswitch />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix block" data-ng-show="realm.social">
|
<div class="form-group clearfix block" data-ng-show="realm.social">
|
||||||
<label for="automaticRegistrationAfterSocialLogin" class="control-label">Auto Reg on Social Login</label>
|
<label for="updateProfileOnInitialSocialLogin" class="control-label">Update profile on first social login</label>
|
||||||
<input ng-model="realm.automaticRegistrationAfterSocialLogin" name="automaticRegistrationAfterSocialLogin" id="automaticRegistrationAfterSocialLogin" onoffswitch />
|
<input ng-model="realm.updateProfileOnInitialSocialLogin" name="updateProfileOnInitialSocialLogin" id="updateProfileOnInitialSocialLogin" onoffswitch />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix block">
|
<div class="form-group clearfix block">
|
||||||
<label for="registrationAllowed" class="control-label">User registration</label>
|
<label for="registrationAllowed" class="control-label">User registration</label>
|
||||||
|
|
|
@ -23,7 +23,7 @@ public class RealmRepresentation {
|
||||||
protected Boolean verifyEmail;
|
protected Boolean verifyEmail;
|
||||||
protected Boolean resetPasswordAllowed;
|
protected Boolean resetPasswordAllowed;
|
||||||
protected Boolean social;
|
protected Boolean social;
|
||||||
protected Boolean automaticRegistrationAfterSocialLogin;
|
protected Boolean updateProfileOnInitialSocialLogin;
|
||||||
protected String privateKey;
|
protected String privateKey;
|
||||||
protected String publicKey;
|
protected String publicKey;
|
||||||
protected List<RoleRepresentation> roles;
|
protected List<RoleRepresentation> roles;
|
||||||
|
@ -279,12 +279,12 @@ public class RealmRepresentation {
|
||||||
this.social = social;
|
this.social = social;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isAutomaticRegistrationAfterSocialLogin() {
|
public Boolean isUpdateProfileOnInitialSocialLogin() {
|
||||||
return automaticRegistrationAfterSocialLogin;
|
return updateProfileOnInitialSocialLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAutomaticRegistrationAfterSocialLogin(Boolean automaticRegistrationAfterSocialLogin) {
|
public void setUpdateProfileOnInitialSocialLogin(Boolean updateProfileOnInitialSocialLogin) {
|
||||||
this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin;
|
this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getSocialProviders() {
|
public Map<String, String> getSocialProviders() {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"sslNotRequired": true,
|
"sslNotRequired": true,
|
||||||
"registrationAllowed": false,
|
"registrationAllowed": false,
|
||||||
"social": 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=",
|
"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",
|
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||||
"requiredCredentials": [ "password" ],
|
"requiredCredentials": [ "password" ],
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"sslNotRequired": true,
|
"sslNotRequired": true,
|
||||||
"registrationAllowed": false,
|
"registrationAllowed": false,
|
||||||
"social": 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=",
|
"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",
|
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||||
"requiredCredentials": [ "password" ],
|
"requiredCredentials": [ "password" ],
|
||||||
|
|
|
@ -32,14 +32,10 @@ public class RegisterBean {
|
||||||
|
|
||||||
private Map<String, String> formData = new HashMap<String, String>();
|
private Map<String, String> formData = new HashMap<String, String>();
|
||||||
|
|
||||||
private boolean socialRegistration;
|
public RegisterBean(MultivaluedMap<String, String> formData) {
|
||||||
|
|
||||||
public RegisterBean(MultivaluedMap<String, String> formData, boolean socialRegistration) {
|
|
||||||
|
|
||||||
this.formData = new HashMap<String, String>();
|
this.formData = new HashMap<String, String>();
|
||||||
|
|
||||||
this.socialRegistration = socialRegistration;
|
|
||||||
|
|
||||||
if (formData != null) {
|
if (formData != null) {
|
||||||
for (String k : formData.keySet()) {
|
for (String k : formData.keySet()) {
|
||||||
this.formData.put(k, formData.getFirst(k));
|
this.formData.put(k, formData.getFirst(k));
|
||||||
|
@ -51,8 +47,4 @@ public class RegisterBean {
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSocialRegistration() {
|
|
||||||
return socialRegistration;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// 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() {
|
public boolean isDisplaySocialProviders() {
|
||||||
return realm.isSocial() && !providers.isEmpty() && !registerBean.isSocialRegistration();
|
return realm.isSocial() && !providers.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RealmBean getRealm() {
|
public RealmBean getRealm() {
|
||||||
|
|
|
@ -34,18 +34,8 @@ public class UrlBean {
|
||||||
|
|
||||||
private RealmBean realm;
|
private RealmBean realm;
|
||||||
|
|
||||||
private boolean socialRegistration;
|
|
||||||
|
|
||||||
private String referrerURI;
|
private String referrerURI;
|
||||||
|
|
||||||
public boolean isSocialRegistration() {
|
|
||||||
return socialRegistration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSocialRegistration(boolean socialRegistration) {
|
|
||||||
this.socialRegistration = socialRegistration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UrlBean(RealmBean realm, URI baseURI, String referrerURI){
|
public UrlBean(RealmBean realm, URI baseURI, String referrerURI){
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.baseURI = baseURI;
|
this.baseURI = baseURI;
|
||||||
|
@ -91,8 +81,6 @@ public class UrlBean {
|
||||||
public String getRegistrationAction() {
|
public String getRegistrationAction() {
|
||||||
if (realm.isSaas()) {
|
if (realm.isSaas()) {
|
||||||
return Urls.saasRegisterAction(baseURI).toString();
|
return Urls.saasRegisterAction(baseURI).toString();
|
||||||
} else if (socialRegistration){
|
|
||||||
return Urls.socialRegisterAction(baseURI, getRealmIdentifier()).toString();
|
|
||||||
} else {
|
} else {
|
||||||
return Urls.realmRegisterAction(baseURI, getRealmIdentifier()).toString();
|
return Urls.realmRegisterAction(baseURI, getRealmIdentifier()).toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,6 @@ public class FormServiceImpl implements FormService {
|
||||||
}
|
}
|
||||||
|
|
||||||
url = new UrlBean(realm, dataBean.getBaseURI(), referrerUri);
|
url = new UrlBean(realm, dataBean.getBaseURI(), referrerUri);
|
||||||
url.setSocialRegistration(dataBean.getSocialRegistration());
|
|
||||||
user = new UserBean(dataBean.getUserModel());
|
user = new UserBean(dataBean.getUserModel());
|
||||||
login = new LoginBean(realm, dataBean.getFormData());
|
login = new LoginBean(realm, dataBean.getFormData());
|
||||||
|
|
||||||
|
@ -163,7 +162,7 @@ public class FormServiceImpl implements FormService {
|
||||||
public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
|
public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
|
||||||
super.exec(attributes, 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);
|
SocialBean social = new SocialBean(realm, dataBean.getSocialProviders(), register, url);
|
||||||
attributes.put("social", social);
|
attributes.put("social", social);
|
||||||
}
|
}
|
||||||
|
@ -173,7 +172,7 @@ public class FormServiceImpl implements FormService {
|
||||||
public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
|
public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
|
||||||
super.exec(attributes, 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);
|
SocialBean social = new SocialBean(realm, dataBean.getSocialProviders(), register, url);
|
||||||
attributes.put("social", social);
|
attributes.put("social", social);
|
||||||
}
|
}
|
||||||
|
@ -183,7 +182,7 @@ public class FormServiceImpl implements FormService {
|
||||||
public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
|
public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
|
||||||
super.exec(attributes, dataBean);
|
super.exec(attributes, dataBean);
|
||||||
|
|
||||||
RegisterBean register = new RegisterBean(dataBean.getFormData(), dataBean.getSocialRegistration());
|
RegisterBean register = new RegisterBean(dataBean.getFormData());
|
||||||
attributes.put("register", register);
|
attributes.put("register", register);
|
||||||
|
|
||||||
SocialBean social = new SocialBean(realm, dataBean.getSocialProviders(), register, url);
|
SocialBean social = new SocialBean(realm, dataBean.getSocialProviders(), register, url);
|
||||||
|
|
|
@ -132,9 +132,9 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
|
||||||
|
|
||||||
void setSocial(boolean social);
|
void setSocial(boolean social);
|
||||||
|
|
||||||
public boolean isAutomaticRegistrationAfterSocialLogin();
|
public boolean isUpdateProfileOnInitialSocialLogin();
|
||||||
|
|
||||||
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin);
|
public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin);
|
||||||
|
|
||||||
List<UserModel> getUsers();
|
List<UserModel> getUsers();
|
||||||
|
|
||||||
|
|
|
@ -663,13 +663,13 @@ public class RealmAdapter implements RealmModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAutomaticRegistrationAfterSocialLogin() {
|
public boolean isUpdateProfileOnInitialSocialLogin() {
|
||||||
return realm.isAutomaticRegistrationAfterSocialLogin();
|
return realm.isUpdateProfileOnInitialSocialLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) {
|
public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
|
||||||
realm.setAutomaticRegistrationAfterSocialLogin(automaticRegistrationAfterSocialLogin);
|
realm.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin);
|
||||||
em.flush();
|
em.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class RealmEntity {
|
||||||
protected boolean verifyEmail;
|
protected boolean verifyEmail;
|
||||||
protected boolean resetPasswordAllowed;
|
protected boolean resetPasswordAllowed;
|
||||||
protected boolean social;
|
protected boolean social;
|
||||||
protected boolean automaticRegistrationAfterSocialLogin;
|
protected boolean updateProfileOnInitialSocialLogin;
|
||||||
protected String passwordPolicy;
|
protected String passwordPolicy;
|
||||||
|
|
||||||
protected int tokenLifespan;
|
protected int tokenLifespan;
|
||||||
|
@ -149,12 +149,12 @@ public class RealmEntity {
|
||||||
this.social = social;
|
this.social = social;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAutomaticRegistrationAfterSocialLogin() {
|
public boolean isUpdateProfileOnInitialSocialLogin() {
|
||||||
return automaticRegistrationAfterSocialLogin;
|
return updateProfileOnInitialSocialLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) {
|
public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
|
||||||
this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin;
|
this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTokenLifespan() {
|
public int getTokenLifespan() {
|
||||||
|
|
|
@ -125,13 +125,13 @@ public class RealmAdapter implements RealmModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAutomaticRegistrationAfterSocialLogin() {
|
public boolean isUpdateProfileOnInitialSocialLogin() {
|
||||||
return realm.isAutomaticRegistrationAfterSocialLogin();
|
return realm.isUpdateProfileOnInitialSocialLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) {
|
public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
|
||||||
realm.setAutomaticRegistrationAfterSocialLogin(automaticRegistrationAfterSocialLogin);
|
realm.setUpdateProfileOnInitialSocialLogin(updateProfileOnInitialSocialLogin);
|
||||||
updateRealm();
|
updateRealm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class RealmData extends AbstractPartition {
|
||||||
private boolean verifyEmail;
|
private boolean verifyEmail;
|
||||||
private boolean resetPasswordAllowed;
|
private boolean resetPasswordAllowed;
|
||||||
private boolean social;
|
private boolean social;
|
||||||
private boolean automaticRegistrationAfterSocialLogin;
|
private boolean updateProfileOnInitialSocialLogin;
|
||||||
private int tokenLifespan;
|
private int tokenLifespan;
|
||||||
private int accessCodeLifespan;
|
private int accessCodeLifespan;
|
||||||
private int accessCodeLifespanUserAction;
|
private int accessCodeLifespanUserAction;
|
||||||
|
@ -63,12 +63,12 @@ public class RealmData extends AbstractPartition {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AttributeProperty
|
@AttributeProperty
|
||||||
public boolean isAutomaticRegistrationAfterSocialLogin() {
|
public boolean isUpdateProfileOnInitialSocialLogin() {
|
||||||
return automaticRegistrationAfterSocialLogin;
|
return updateProfileOnInitialSocialLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) {
|
public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
|
||||||
this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin;
|
this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@AttributeProperty
|
@AttributeProperty
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class RealmEntity implements Serializable {
|
||||||
@AttributeValue
|
@AttributeValue
|
||||||
private boolean social;
|
private boolean social;
|
||||||
@AttributeValue
|
@AttributeValue
|
||||||
private boolean automaticRegistrationAfterSocialLogin;
|
private boolean updateProfileOnInitialSocialLogin;
|
||||||
@AttributeValue
|
@AttributeValue
|
||||||
private int tokenLifespan;
|
private int tokenLifespan;
|
||||||
@AttributeValue
|
@AttributeValue
|
||||||
|
@ -128,12 +128,12 @@ public class RealmEntity implements Serializable {
|
||||||
this.social = social;
|
this.social = social;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAutomaticRegistrationAfterSocialLogin() {
|
public boolean isUpdateProfileOnInitialSocialLogin() {
|
||||||
return automaticRegistrationAfterSocialLogin;
|
return updateProfileOnInitialSocialLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAutomaticRegistrationAfterSocialLogin(boolean automaticRegistrationAfterSocialLogin) {
|
public void setUpdateProfileOnInitialSocialLogin(boolean updateProfileOnInitialSocialLogin) {
|
||||||
this.automaticRegistrationAfterSocialLogin = automaticRegistrationAfterSocialLogin;
|
this.updateProfileOnInitialSocialLogin = updateProfileOnInitialSocialLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTokenLifespan() {
|
public int getTokenLifespan() {
|
||||||
|
|
7
pom.xml
7
pom.xml
|
@ -26,6 +26,7 @@
|
||||||
<slf4j.version>1.6.1</slf4j.version>
|
<slf4j.version>1.6.1</slf4j.version>
|
||||||
<jboss.version>7.1.1.Final</jboss.version>
|
<jboss.version>7.1.1.Final</jboss.version>
|
||||||
<wildfly.version>8.0.0.CR1</wildfly.version>
|
<wildfly.version>8.0.0.CR1</wildfly.version>
|
||||||
|
<json.version>20131018</json.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<url>http://keycloak.org</url>
|
<url>http://keycloak.org</url>
|
||||||
|
@ -246,6 +247,12 @@
|
||||||
<version>2.3.19</version>
|
<version>2.3.19</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
<version>${json.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Google+ -->
|
<!-- Google+ -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.http-client</groupId>
|
<groupId>com.google.http-client</groupId>
|
||||||
|
|
|
@ -57,16 +57,6 @@ public interface FormService {
|
||||||
|
|
||||||
private List<SocialProvider> socialProviders;
|
private List<SocialProvider> socialProviders;
|
||||||
|
|
||||||
public Boolean getSocialRegistration() {
|
|
||||||
return socialRegistration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSocialRegistration(Boolean socialRegistration) {
|
|
||||||
this.socialRegistration = socialRegistration;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Boolean socialRegistration;
|
|
||||||
|
|
||||||
public String getCode() {
|
public String getCode() {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,8 +102,8 @@ public class RealmManager {
|
||||||
if (rep.isRegistrationAllowed() != null) realm.setRegistrationAllowed(rep.isRegistrationAllowed());
|
if (rep.isRegistrationAllowed() != null) realm.setRegistrationAllowed(rep.isRegistrationAllowed());
|
||||||
if (rep.isVerifyEmail() != null) realm.setVerifyEmail(rep.isVerifyEmail());
|
if (rep.isVerifyEmail() != null) realm.setVerifyEmail(rep.isVerifyEmail());
|
||||||
if (rep.isResetPasswordAllowed() != null) realm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
|
if (rep.isResetPasswordAllowed() != null) realm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
|
||||||
if (rep.isAutomaticRegistrationAfterSocialLogin() != null)
|
if (rep.isUpdateProfileOnInitialSocialLogin() != null)
|
||||||
realm.setAutomaticRegistrationAfterSocialLogin(rep.isAutomaticRegistrationAfterSocialLogin());
|
realm.setUpdateProfileOnInitialSocialLogin(rep.isUpdateProfileOnInitialSocialLogin());
|
||||||
if (rep.isSslNotRequired() != null) realm.setSslNotRequired((rep.isSslNotRequired()));
|
if (rep.isSslNotRequired() != null) realm.setSslNotRequired((rep.isSslNotRequired()));
|
||||||
if (rep.getAccessCodeLifespan() != null) realm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
|
if (rep.getAccessCodeLifespan() != null) realm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
|
||||||
if (rep.getAccessCodeLifespanUserAction() != null)
|
if (rep.getAccessCodeLifespanUserAction() != null)
|
||||||
|
@ -200,8 +200,8 @@ public class RealmManager {
|
||||||
if (rep.isRegistrationAllowed() != null) newRealm.setRegistrationAllowed(rep.isRegistrationAllowed());
|
if (rep.isRegistrationAllowed() != null) newRealm.setRegistrationAllowed(rep.isRegistrationAllowed());
|
||||||
if (rep.isVerifyEmail() != null) newRealm.setVerifyEmail(rep.isVerifyEmail());
|
if (rep.isVerifyEmail() != null) newRealm.setVerifyEmail(rep.isVerifyEmail());
|
||||||
if (rep.isResetPasswordAllowed() != null) newRealm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
|
if (rep.isResetPasswordAllowed() != null) newRealm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
|
||||||
if (rep.isAutomaticRegistrationAfterSocialLogin() != null)
|
if (rep.isUpdateProfileOnInitialSocialLogin() != null)
|
||||||
newRealm.setAutomaticRegistrationAfterSocialLogin(rep.isAutomaticRegistrationAfterSocialLogin());
|
newRealm.setUpdateProfileOnInitialSocialLogin(rep.isUpdateProfileOnInitialSocialLogin());
|
||||||
if (rep.getPrivateKey() == null || rep.getPublicKey() == null) {
|
if (rep.getPrivateKey() == null || rep.getPublicKey() == null) {
|
||||||
generateRealmKeys(newRealm);
|
generateRealmKeys(newRealm);
|
||||||
} else {
|
} else {
|
||||||
|
@ -475,7 +475,7 @@ public class RealmManager {
|
||||||
rep.setRealm(realm.getName());
|
rep.setRealm(realm.getName());
|
||||||
rep.setEnabled(realm.isEnabled());
|
rep.setEnabled(realm.isEnabled());
|
||||||
rep.setSocial(realm.isSocial());
|
rep.setSocial(realm.isSocial());
|
||||||
rep.setAutomaticRegistrationAfterSocialLogin(realm.isAutomaticRegistrationAfterSocialLogin());
|
rep.setUpdateProfileOnInitialSocialLogin(realm.isUpdateProfileOnInitialSocialLogin());
|
||||||
rep.setSslNotRequired(realm.isSslNotRequired());
|
rep.setSslNotRequired(realm.isSslNotRequired());
|
||||||
rep.setPublicKey(realm.getPublicKeyPem());
|
rep.setPublicKey(realm.getPublicKeyPem());
|
||||||
rep.setPrivateKey(realm.getPrivateKeyPem());
|
rep.setPrivateKey(realm.getPrivateKeyPem());
|
||||||
|
|
|
@ -143,7 +143,7 @@ public class SocialResource {
|
||||||
|
|
||||||
AuthCallback callback = new AuthCallback(requestData.getSocialAttributes(), queryParams);
|
AuthCallback callback = new AuthCallback(requestData.getSocialAttributes(), queryParams);
|
||||||
|
|
||||||
SocialUser socialUser = null;
|
SocialUser socialUser;
|
||||||
try {
|
try {
|
||||||
socialUser = provider.processCallback(config, callback);
|
socialUser = provider.processCallback(config, callback);
|
||||||
} catch (SocialProviderException e) {
|
} 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)
|
// 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: Maybe we should search also by email and bind accounts if user with this email is
|
||||||
// TODO: Username is already in realm. Show message and let user to bind accounts after he re-authenticate
|
// already registered. But actually Keycloak allows duplicate emails
|
||||||
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);
|
|
||||||
} else {
|
} else {
|
||||||
// Redirect user to registration screen with prefilled data from social provider
|
user = realm.addUser(socialUser.getUsername());
|
||||||
MultivaluedMap<String, String> formData = fillRegistrationFormWithSocialData(socialUser);
|
user.setEnabled(true);
|
||||||
|
user.setFirstName(socialUser.getFirstName());
|
||||||
|
user.setLastName(socialUser.getLastName());
|
||||||
|
user.setEmail(socialUser.getEmail());
|
||||||
|
|
||||||
String requestId = UUID.randomUUID().toString();
|
if (realm.isUpdateProfileOnInitialSocialLogin()) {
|
||||||
socialRequestManager.addRequest(requestId, RequestDetails.create(requestData).build());
|
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
realm.addSocialLink(user, socialLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.isEnabled()) {
|
if (!user.isEnabled()) {
|
||||||
|
@ -213,7 +198,7 @@ public class SocialResource {
|
||||||
public Response redirectToProviderAuth(@PathParam("realm") final String realmId,
|
public Response redirectToProviderAuth(@PathParam("realm") final String realmId,
|
||||||
@QueryParam("provider_id") final String providerId, @QueryParam("client_id") final String clientId,
|
@QueryParam("provider_id") final String providerId, @QueryParam("client_id") final String clientId,
|
||||||
@QueryParam("scope") final String scope, @QueryParam("state") final String state,
|
@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);
|
RealmManager realmManager = new RealmManager(session);
|
||||||
RealmModel realm = realmManager.getRealm(realmId);
|
RealmModel realm = realmManager.getRealm(realmId);
|
||||||
|
|
||||||
|
@ -228,6 +213,21 @@ public class SocialResource {
|
||||||
|
|
||||||
SocialProviderConfig config = new SocialProviderConfig(key, secret, callbackUri);
|
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 {
|
try {
|
||||||
AuthRequest authRequest = provider.getAuthUrl(config);
|
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<String, String> 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<String, String[]> queryParams) {
|
private RequestDetails getRequestDetails(Map<String, String[]> queryParams) {
|
||||||
for (SocialProvider provider : SocialLoader.load()) {
|
for (SocialProvider provider : SocialLoader.load()) {
|
||||||
if (queryParams.containsKey(provider.getRequestIdParamName())) {
|
if (queryParams.containsKey(provider.getRequestIdParamName())) {
|
||||||
|
@ -324,25 +265,4 @@ public class SocialResource {
|
||||||
return queryParams;
|
return queryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MultivaluedMap<String, String> fillRegistrationFormWithSocialData(SocialUser socialUser) {
|
|
||||||
MultivaluedMap<String, String> formData = new MultivaluedMapImpl<String, String>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,20 +276,7 @@ public class TokenService {
|
||||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
public Response processRegister(@QueryParam("client_id") final String clientId,
|
public Response processRegister(@QueryParam("client_id") final String clientId,
|
||||||
@QueryParam("scope") final String scopeParam, @QueryParam("state") final String state,
|
@QueryParam("scope") final String scopeParam, @QueryParam("state") final String state,
|
||||||
@QueryParam("redirect_uri") final String redirect, final MultivaluedMap<String, String> formData) {
|
@QueryParam("redirect_uri") String redirect, final MultivaluedMap<String, String> 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<String, String> formData, boolean isSocialRegistration) {
|
|
||||||
OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager);
|
OAuthFlows oauth = Flows.oauth(realm, request, uriInfo, authManager, tokenManager);
|
||||||
|
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
|
@ -328,16 +315,14 @@ public class TokenService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
return Flows.forms(realm, request, uriInfo).setError(error).setFormData(formData)
|
return Flows.forms(realm, request, uriInfo).setError(error).setFormData(formData).forwardToRegistration();
|
||||||
.setSocialRegistration(isSocialRegistration).forwardToRegistration();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String username = formData.getFirst("username");
|
String username = formData.getFirst("username");
|
||||||
|
|
||||||
UserModel user = realm.getUser(username);
|
UserModel user = realm.getUser(username);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
return Flows.forms(realm, request, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData)
|
return Flows.forms(realm, request, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData).forwardToRegistration();
|
||||||
.setSocialRegistration(isSocialRegistration).forwardToRegistration();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user = realm.addUser(username);
|
user = realm.addUser(username);
|
||||||
|
@ -364,8 +349,7 @@ public class TokenService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return processLogin(clientId, scopeParam, state, redirect, formData);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Path("access/codes")
|
@Path("access/codes")
|
||||||
|
@ -647,7 +631,7 @@ public class TokenService {
|
||||||
return location.build();
|
return location.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String verifyRedirectUri(String redirectUri, UserModel client) {
|
public static String verifyRedirectUri(String redirectUri, UserModel client) {
|
||||||
if (redirectUri == null) {
|
if (redirectUri == null) {
|
||||||
return client.getRedirectUris().size() == 1 ? client.getRedirectUris().iterator().next() : null;
|
return client.getRedirectUris().size() == 1 ? client.getRedirectUris().iterator().next() : null;
|
||||||
} else if (client.getRedirectUris().isEmpty()) {
|
} else if (client.getRedirectUris().isEmpty()) {
|
||||||
|
|
|
@ -66,7 +66,6 @@ public class FormFlows {
|
||||||
private HttpRequest request;
|
private HttpRequest request;
|
||||||
private UserModel userModel;
|
private UserModel userModel;
|
||||||
|
|
||||||
private boolean socialRegistration;
|
|
||||||
private AccessCodeEntry accessCode;
|
private AccessCodeEntry accessCode;
|
||||||
private UriInfo uriInfo;
|
private UriInfo uriInfo;
|
||||||
|
|
||||||
|
@ -119,7 +118,7 @@ public class FormFlows {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accessCode != null) {
|
if (accessCode != null) {
|
||||||
uriBuilder.queryParam(CODE, accessCode.getCode());
|
uriBuilder.replaceQueryParam(CODE, accessCode.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queryParams != null) {
|
if (queryParams != null) {
|
||||||
|
@ -134,7 +133,6 @@ public class FormFlows {
|
||||||
// TODO find a better way to obtain contextPath
|
// TODO find a better way to obtain contextPath
|
||||||
// Getting context path by removing "rest/" substring from the BaseUri path
|
// Getting context path by removing "rest/" substring from the BaseUri path
|
||||||
formDataBean.setContextPath(requestURI.substring(0, requestURI.length() - 6));
|
formDataBean.setContextPath(requestURI.substring(0, requestURI.length() - 6));
|
||||||
formDataBean.setSocialRegistration(socialRegistration);
|
|
||||||
|
|
||||||
// Find the service and process relevant template
|
// Find the service and process relevant template
|
||||||
Iterator<FormService> itr = ServiceLoader.load(FormService.class).iterator();
|
Iterator<FormService> itr = ServiceLoader.load(FormService.class).iterator();
|
||||||
|
@ -261,12 +259,6 @@ public class FormFlows {
|
||||||
return this;
|
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<String, String> formData) {
|
public FormFlows setFormData(MultivaluedMap<String, String> formData) {
|
||||||
this.formData = formData;
|
this.formData = formData;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -165,10 +165,6 @@ public class Urls {
|
||||||
.build(realmId);
|
.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) {
|
private static UriBuilder requiredActionsBase(URI baseUri) {
|
||||||
return tokenBase(baseUri).path(TokenService.class, "getRequiredActionsService");
|
return tokenBase(baseUri).path(TokenService.class, "getRequiredActionsService");
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class AdapterTest extends AbstractKeycloakTest {
|
||||||
realmModel.setPrivateKeyPem("0234234");
|
realmModel.setPrivateKeyPem("0234234");
|
||||||
realmModel.setPublicKeyPem("0234234");
|
realmModel.setPublicKeyPem("0234234");
|
||||||
realmModel.setTokenLifespan(1000);
|
realmModel.setTokenLifespan(1000);
|
||||||
realmModel.setAutomaticRegistrationAfterSocialLogin(true);
|
realmModel.setUpdateProfileOnInitialSocialLogin(true);
|
||||||
realmModel.addDefaultRole("foo");
|
realmModel.addDefaultRole("foo");
|
||||||
|
|
||||||
System.out.println(realmModel.getId());
|
System.out.println(realmModel.getId());
|
||||||
|
@ -78,7 +78,7 @@ public class AdapterTest extends AbstractKeycloakTest {
|
||||||
Assert.assertEquals(realmModel.getName(), "JUGGLER");
|
Assert.assertEquals(realmModel.getName(), "JUGGLER");
|
||||||
Assert.assertEquals(realmModel.getPrivateKeyPem(), "0234234");
|
Assert.assertEquals(realmModel.getPrivateKeyPem(), "0234234");
|
||||||
Assert.assertEquals(realmModel.getPublicKeyPem(), "0234234");
|
Assert.assertEquals(realmModel.getPublicKeyPem(), "0234234");
|
||||||
Assert.assertEquals(realmModel.isAutomaticRegistrationAfterSocialLogin(), true);
|
Assert.assertEquals(realmModel.isUpdateProfileOnInitialSocialLogin(), true);
|
||||||
Assert.assertEquals(1, realmModel.getDefaultRoles().size());
|
Assert.assertEquals(1, realmModel.getDefaultRoles().size());
|
||||||
Assert.assertEquals("foo", realmModel.getDefaultRoles().get(0));
|
Assert.assertEquals("foo", realmModel.getDefaultRoles().get(0));
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ public class AdapterTest extends AbstractKeycloakTest {
|
||||||
realmModel.setPrivateKeyPem("0234234");
|
realmModel.setPrivateKeyPem("0234234");
|
||||||
realmModel.setPublicKeyPem("0234234");
|
realmModel.setPublicKeyPem("0234234");
|
||||||
realmModel.setTokenLifespan(1000);
|
realmModel.setTokenLifespan(1000);
|
||||||
realmModel.setAutomaticRegistrationAfterSocialLogin(true);
|
realmModel.setUpdateProfileOnInitialSocialLogin(true);
|
||||||
realmModel.addDefaultRole("foo");
|
realmModel.addDefaultRole("foo");
|
||||||
|
|
||||||
System.out.println(realmModel.getId());
|
System.out.println(realmModel.getId());
|
||||||
|
@ -106,7 +106,7 @@ public class AdapterTest extends AbstractKeycloakTest {
|
||||||
Assert.assertEquals(realmModel.getName(), "JUGGLER");
|
Assert.assertEquals(realmModel.getName(), "JUGGLER");
|
||||||
Assert.assertEquals(realmModel.getPrivateKeyPem(), "0234234");
|
Assert.assertEquals(realmModel.getPrivateKeyPem(), "0234234");
|
||||||
Assert.assertEquals(realmModel.getPublicKeyPem(), "0234234");
|
Assert.assertEquals(realmModel.getPublicKeyPem(), "0234234");
|
||||||
Assert.assertEquals(realmModel.isAutomaticRegistrationAfterSocialLogin(), true);
|
Assert.assertEquals(realmModel.isUpdateProfileOnInitialSocialLogin(), true);
|
||||||
Assert.assertEquals(1, realmModel.getDefaultRoles().size());
|
Assert.assertEquals(1, realmModel.getDefaultRoles().size());
|
||||||
Assert.assertEquals("foo", realmModel.getDefaultRoles().get(0));
|
Assert.assertEquals("foo", realmModel.getDefaultRoles().get(0));
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class ImportTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
Assert.assertTrue(realm.isVerifyEmail());
|
Assert.assertTrue(realm.isVerifyEmail());
|
||||||
|
|
||||||
Assert.assertFalse(realm.isAutomaticRegistrationAfterSocialLogin());
|
Assert.assertFalse(realm.isUpdateProfileOnInitialSocialLogin());
|
||||||
List<RequiredCredentialModel> creds = realm.getRequiredCredentials();
|
List<RequiredCredentialModel> creds = realm.getRequiredCredentials();
|
||||||
Assert.assertEquals(1, creds.size());
|
Assert.assertEquals(1, creds.size());
|
||||||
RequiredCredentialModel cred = creds.get(0);
|
RequiredCredentialModel cred = creds.get(0);
|
||||||
|
@ -94,7 +94,7 @@ public class ImportTest extends AbstractKeycloakTest {
|
||||||
RealmModel realm = manager.createRealm("demo", rep.getRealm());
|
RealmModel realm = manager.createRealm("demo", rep.getRealm());
|
||||||
manager.importRealm(rep, realm);
|
manager.importRealm(rep, realm);
|
||||||
|
|
||||||
Assert.assertTrue(realm.isAutomaticRegistrationAfterSocialLogin());
|
Assert.assertFalse(realm.isUpdateProfileOnInitialSocialLogin());
|
||||||
Assert.assertEquals(600, realm.getAccessCodeLifespanUserAction());
|
Assert.assertEquals(600, realm.getAccessCodeLifespanUserAction());
|
||||||
verifyRequiredCredentials(realm.getRequiredCredentials(), "password");
|
verifyRequiredCredentials(realm.getRequiredCredentials(), "password");
|
||||||
verifyRequiredCredentials(realm.getRequiredApplicationCredentials(), "totp");
|
verifyRequiredCredentials(realm.getRequiredApplicationCredentials(), "totp");
|
||||||
|
|
|
@ -71,8 +71,8 @@ public class ModelTest extends AbstractKeycloakServerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void assertEquals(RealmModel expected, RealmModel actual) {
|
public static void assertEquals(RealmModel expected, RealmModel actual) {
|
||||||
Assert.assertEquals(expected.isAutomaticRegistrationAfterSocialLogin(),
|
Assert.assertEquals(expected.isUpdateProfileOnInitialSocialLogin(),
|
||||||
actual.isAutomaticRegistrationAfterSocialLogin());
|
actual.isUpdateProfileOnInitialSocialLogin());
|
||||||
Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed());
|
Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed());
|
||||||
Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed());
|
Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed());
|
||||||
Assert.assertEquals(expected.isSocial(), actual.isSocial());
|
Assert.assertEquals(expected.isSocial(), actual.isSocial());
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"accessCodeLifespan": 10,
|
"accessCodeLifespan": 10,
|
||||||
"accessCodeLifespanUserAction": 600,
|
"accessCodeLifespanUserAction": 600,
|
||||||
"sslNotRequired": true,
|
"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=",
|
"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",
|
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||||
"requiredCredentials": [ "password" ],
|
"requiredCredentials": [ "password" ],
|
||||||
|
|
|
@ -14,9 +14,23 @@
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.resteasy</groupId>
|
<groupId>org.json</groupId>
|
||||||
<artifactId>jaxrs-api</artifactId>
|
<artifactId>json</artifactId>
|
||||||
<scope>provided</scope>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.undertow</groupId>
|
||||||
|
<artifactId>undertow-servlet</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.undertow</groupId>
|
||||||
|
<artifactId>undertow-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,10 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.social;
|
package org.keycloak.social;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -40,7 +42,10 @@ public class AuthRequest {
|
||||||
public static AuthRequestBuilder create(String id, String path) {
|
public static AuthRequestBuilder create(String id, String path) {
|
||||||
AuthRequestBuilder req = new AuthRequestBuilder();
|
AuthRequestBuilder req = new AuthRequestBuilder();
|
||||||
req.id = id;
|
req.id = id;
|
||||||
req.b = UriBuilder.fromUri(path);
|
|
||||||
|
req.b = new StringBuilder();
|
||||||
|
req.b.append(path);
|
||||||
|
|
||||||
req.attributes = new HashMap<String, String>();
|
req.attributes = new HashMap<String, String>();
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
@ -65,18 +70,33 @@ public class AuthRequest {
|
||||||
|
|
||||||
public static class AuthRequestBuilder {
|
public static class AuthRequestBuilder {
|
||||||
|
|
||||||
private UriBuilder b;
|
private StringBuilder b;
|
||||||
|
|
||||||
|
private char sep;
|
||||||
|
|
||||||
private Map<String, String> attributes;
|
private Map<String, String> attributes;
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
private AuthRequestBuilder() {
|
private AuthRequestBuilder() {
|
||||||
|
sep = '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthRequestBuilder setQueryParam(String name, String value) {
|
public AuthRequestBuilder setQueryParam(String name, String value) {
|
||||||
b.queryParam(name, value);
|
try {
|
||||||
return this;
|
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) {
|
public AuthRequestBuilder setAttribute(String name, String value) {
|
||||||
|
@ -85,7 +105,11 @@ public class AuthRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthRequest build() {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
public class SimpleHttp {
|
||||||
|
|
||||||
|
private String url;
|
||||||
|
private String method;
|
||||||
|
private Map<String, String> headers;
|
||||||
|
private Map<String, String> 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<String, String>();
|
||||||
|
}
|
||||||
|
headers.put(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleHttp param(String name, String value) {
|
||||||
|
if (params == null) {
|
||||||
|
params = new HashMap<String, String>();
|
||||||
|
}
|
||||||
|
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<String, String> 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<String, String> 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
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<String> 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<String> 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -17,20 +17,6 @@
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-social-core</artifactId>
|
<artifactId>keycloak-social-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.api-client</groupId>
|
|
||||||
<artifactId>google-api-client</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.http-client</groupId>
|
|
||||||
<artifactId>google-http-client-jackson</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.apis</groupId>
|
|
||||||
<artifactId>google-api-services-oauth2</artifactId>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -21,23 +21,16 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.social.google;
|
package org.keycloak.social.google;
|
||||||
|
|
||||||
import java.util.UUID;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import org.keycloak.social.AuthCallback;
|
import org.keycloak.social.AuthCallback;
|
||||||
import org.keycloak.social.AuthRequest;
|
import org.keycloak.social.AuthRequest;
|
||||||
|
import org.keycloak.social.utils.SimpleHttp;
|
||||||
import org.keycloak.social.SocialProvider;
|
import org.keycloak.social.SocialProvider;
|
||||||
import org.keycloak.social.SocialProviderConfig;
|
import org.keycloak.social.SocialProviderConfig;
|
||||||
import org.keycloak.social.SocialProviderException;
|
import org.keycloak.social.SocialProviderException;
|
||||||
import org.keycloak.social.SocialUser;
|
import org.keycloak.social.SocialUser;
|
||||||
|
|
||||||
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
|
import java.util.UUID;
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -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 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
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -82,32 +75,22 @@ public class GoogleProvider implements SocialProvider {
|
||||||
throw new SocialProviderException("Invalid state");
|
throw new SocialProviderException("Invalid state");
|
||||||
}
|
}
|
||||||
|
|
||||||
GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(TRANSPORT, JSON_FACTORY,
|
JSONObject token = SimpleHttp.doPost(TOKEN_PATH).param("code", code).param("client_id", config.getKey())
|
||||||
config.getKey(), config.getSecret(), code, config.getCallbackUrl().toString())
|
.param("client_secret", config.getSecret())
|
||||||
.execute();
|
.param("redirect_uri", config.getCallbackUrl())
|
||||||
|
.param("grant_type", "authorization_code").asJson();
|
||||||
|
|
||||||
GoogleCredential credential = new GoogleCredential.Builder().setJsonFactory(JSON_FACTORY).setTransport(TRANSPORT)
|
String accessToken = token.getString("access_token");
|
||||||
.setClientSecrets(config.getKey(), config.getSecret()).build()
|
|
||||||
.setFromTokenResponse(tokenResponse);
|
|
||||||
|
|
||||||
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")) {
|
user.setUsername(profile.getString("email"));
|
||||||
throw new SocialProviderException((String) tokenInfo.get("error"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Userinfo userInfo = oauth2.userinfo().get().execute();
|
user.setFirstName(profile.optString("given_name"));
|
||||||
|
user.setLastName(profile.optString("family_name"));
|
||||||
SocialUser user = new SocialUser(userInfo.getId());
|
user.setEmail(profile.optString("email"));
|
||||||
|
|
||||||
// Use email as username for Google
|
|
||||||
user.setUsername(userInfo.getEmail());
|
|
||||||
|
|
||||||
user.setFirstName(userInfo.getGivenName());
|
|
||||||
user.setLastName(userInfo.getFamilyName());
|
|
||||||
user.setEmail(userInfo.getEmail());
|
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class DummySocial implements SocialProvider {
|
||||||
throw new SocialProviderException("Invalid state");
|
throw new SocialProviderException("Invalid state");
|
||||||
}
|
}
|
||||||
|
|
||||||
String username = callback.getQueryParam("access_token");
|
String username = callback.getQueryParam("username");
|
||||||
SocialUser user = new SocialUser(username);
|
SocialUser user = new SocialUser(username);
|
||||||
user.setEmail(username + "@dummy-social");
|
user.setEmail(username + "@dummy-social");
|
||||||
user.setUsername(username);
|
user.setUsername(username);
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.io.PrintWriter;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class DummySocialServlet extends HttpServlet {
|
public class DummySocialServlet extends HttpServlet {
|
||||||
|
|
||||||
|
@ -31,7 +32,6 @@ public class DummySocialServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
String accessToken = req.getParameter("username");
|
|
||||||
String state = null;
|
String state = null;
|
||||||
String redirectUri = 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);
|
resp.sendRedirect(redirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,18 @@ public class LoginUpdateProfilePage extends AbstractPage {
|
||||||
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
|
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() {
|
public boolean isCurrent() {
|
||||||
return driver.getTitle().equals("Update Account Information");
|
return driver.getTitle().equals("Update Account Information");
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
|
import org.keycloak.testsuite.pages.LoginUpdateProfilePage;
|
||||||
import org.keycloak.testsuite.pages.RegisterPage;
|
import org.keycloak.testsuite.pages.RegisterPage;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
|
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
|
||||||
|
@ -55,7 +56,7 @@ public class SocialLoginTest {
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
|
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
|
||||||
appRealm.setSocial(true);
|
appRealm.setSocial(true);
|
||||||
appRealm.setAutomaticRegistrationAfterSocialLogin(true);
|
appRealm.setUpdateProfileOnInitialSocialLogin(false);
|
||||||
|
|
||||||
HashMap<String, String> socialConfig = new HashMap<String, String>();
|
HashMap<String, String> socialConfig = new HashMap<String, String>();
|
||||||
socialConfig.put("dummy.key", "1234");
|
socialConfig.put("dummy.key", "1234");
|
||||||
|
@ -77,7 +78,7 @@ public class SocialLoginTest {
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
@WebResource
|
@WebResource
|
||||||
protected RegisterPage registerPage;
|
protected LoginUpdateProfilePage profilePage;
|
||||||
|
|
||||||
@WebResource
|
@WebResource
|
||||||
protected OAuthClient oauth;
|
protected OAuthClient oauth;
|
||||||
|
@ -106,11 +107,11 @@ public class SocialLoginTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerRequired() {
|
public void profileUpdateRequired() {
|
||||||
keycloakRule.configure(new KeycloakSetup() {
|
keycloakRule.configure(new KeycloakSetup() {
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
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("username")).sendKeys("dummy-user-reg");
|
||||||
driver.findElement(By.id("submit")).click();
|
driver.findElement(By.id("submit")).click();
|
||||||
|
|
||||||
registerPage.isCurrent();
|
profilePage.isCurrent();
|
||||||
|
|
||||||
Assert.assertEquals("", registerPage.getFirstName());
|
Assert.assertEquals("", profilePage.getFirstName());
|
||||||
Assert.assertEquals("", registerPage.getLastName());
|
Assert.assertEquals("", profilePage.getLastName());
|
||||||
Assert.assertEquals("dummy-user-reg@dummy-social", registerPage.getEmail());
|
Assert.assertEquals("dummy-user-reg@dummy-social", profilePage.getEmail());
|
||||||
Assert.assertEquals("dummy-user-reg", registerPage.getUsername());
|
|
||||||
|
|
||||||
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());
|
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
} finally {
|
} finally {
|
||||||
keycloakRule.configure(new KeycloakSetup() {
|
keycloakRule.configure(new KeycloakSetup() {
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
appRealm.setAutomaticRegistrationAfterSocialLogin(true);
|
appRealm.setUpdateProfileOnInitialSocialLogin(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue