This commit is contained in:
Bill Burke 2014-01-17 10:30:50 -05:00
commit d8ac7ab656
52 changed files with 706 additions and 375 deletions

View file

@ -82,8 +82,8 @@ module.config([ '$routeProvider', function($routeProvider) {
}, },
controller : 'RealmSocialCtrl' controller : 'RealmSocialCtrl'
}) })
.when('/realms/:realm/registration-settings', { .when('/realms/:realm/default-roles', {
templateUrl : 'partials/realm-registration.html', templateUrl : 'partials/realm-default-roles.html',
resolve : { resolve : {
realm : function(RealmLoader) { realm : function(RealmLoader) {
return RealmLoader(); return RealmLoader();
@ -95,7 +95,7 @@ module.config([ '$routeProvider', function($routeProvider) {
return RoleListLoader(); return RoleListLoader();
} }
}, },
controller : 'RealmRegistrationCtrl' controller : 'RealmDefaultRolesCtrl'
}) })
.when('/realms/:realm/required-credentials', { .when('/realms/:realm/required-credentials', {
templateUrl : 'partials/realm-credentials.html', templateUrl : 'partials/realm-credentials.html',

View file

@ -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; $scope.realm = realm;

View file

@ -6,8 +6,8 @@
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.realm}}">General</a></li> <li><a href="#/realms/{{realm.realm}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li> <li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
<li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.realm}}/registration-settings">Registration</a></li>
<li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li> <li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
<li class="active"><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li> <li class="active"><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li> <li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>

View file

@ -6,8 +6,8 @@
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.realm}}">General</a></li> <li><a href="#/realms/{{realm.realm}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li> <li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
<li class="active"><a href="#/realms/{{realm.realm}}/registration-settings">Registration</a></li>
<li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li> <li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li class="active"><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li> <li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>

View file

@ -6,8 +6,8 @@
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li class="active"><a href="#/realms/{{realm.realm}}">General</a></li> <li class="active"><a href="#/realms/{{realm.realm}}">General</a></li>
<li data-ng-show="social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li> <li data-ng-show="social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
<li data-ng-show="registrationAllowed"><a href="#/realms/{{realm.realm}}/registration-settings">Registration</a></li>
<li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li> <li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li> <li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>
@ -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>
@ -61,10 +61,6 @@
<label for="verifyEmail" class="control-label">Verify email</label> <label for="verifyEmail" class="control-label">Verify email</label>
<input ng-model="realm.verifyEmail" name="verifyEmail" id="verifyEmail" onoffswitch /> <input ng-model="realm.verifyEmail" name="verifyEmail" id="verifyEmail" onoffswitch />
</div> </div>
<div class="form-group clearfix block">
<label for="accountManagement" class="control-label two-lines">User account management</label>
<input ng-model="realm.accountManagement" name="accountManagement" id="accountManagement" onoffswitch />
</div>
<div class="form-group clearfix block"> <div class="form-group clearfix block">
<label for="requireSsl" class="control-label">Require SSL</label> <label for="requireSsl" class="control-label">Require SSL</label>
<input ng-model="realm.requireSsl" name="requireSsl" id="requireSsl" onoffswitch /> <input ng-model="realm.requireSsl" name="requireSsl" id="requireSsl" onoffswitch />

View file

@ -6,8 +6,8 @@
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.realm}}">General</a></li> <li><a href="#/realms/{{realm.realm}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li> <li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
<li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.realm}}/registration-settings">Registration</a></li>
<li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li> <li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li class="active"><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li> <li class="active"><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>

View file

@ -6,8 +6,8 @@
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.realm}}">General</a></li> <li><a href="#/realms/{{realm.realm}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li> <li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
<li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.realm}}/registration-settings">Registration</a></li>
<li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li> <li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li> <li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>

View file

@ -6,8 +6,8 @@
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.realm}}">General</a></li> <li><a href="#/realms/{{realm.realm}}">General</a></li>
<li class="active" data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li> <li class="active" data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
<li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.realm}}/registration-settings">Registration</a></li>
<li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li> <li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li> <li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>

View file

@ -6,8 +6,8 @@
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.realm}}">General</a></li> <li><a href="#/realms/{{realm.realm}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li> <li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
<li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.realm}}/registration-settings">Registration</a></li>
<li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li> <li><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li class="active"><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li> <li class="active"><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li> <li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>

View file

@ -6,8 +6,8 @@
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.realm}}">General</a></li> <li><a href="#/realms/{{realm.realm}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li> <li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
<li><a href="#/realms/{{realm.realm}}/registration-settings">Registration</a></li>
<li class="active"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li> <li class="active"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li> <li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>

View file

@ -6,8 +6,8 @@
<ul class="rcue-tabs"> <ul class="rcue-tabs">
<li><a href="#/realms/{{realm.realm}}">General</a></li> <li><a href="#/realms/{{realm.realm}}">General</a></li>
<li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li> <li data-ng-show="realm.social"><a href="#/realms/{{realm.realm}}/social-settings">Social</a></li>
<li data-ng-show="realm.registrationAllowed"><a href="#/realms/{{realm.realm}}/registration-settings">Registration</a></li>
<li class="active"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li> <li class="active"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/default-roles">Default Roles</a></li>
<li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li> <li><a href="#/realms/{{realm.realm}}/required-credentials">Credentials</a></li>
<li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li> <li><a href="#/realms/{{realm.realm}}/token-settings">Token</a></li>
<li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li> <li><a href="#/realms/{{realm.realm}}/keys-settings">Keys</a></li>

View file

@ -17,13 +17,12 @@ public class RealmRepresentation {
protected Integer accessCodeLifespan; protected Integer accessCodeLifespan;
protected Integer accessCodeLifespanUserAction; protected Integer accessCodeLifespanUserAction;
protected Boolean enabled; protected Boolean enabled;
protected Boolean accountManagement;
protected Boolean sslNotRequired; protected Boolean sslNotRequired;
protected Boolean registrationAllowed; protected Boolean registrationAllowed;
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;
@ -107,14 +106,6 @@ public class RealmRepresentation {
this.enabled = enabled; this.enabled = enabled;
} }
public Boolean getAccountManagement() {
return accountManagement;
}
public void setAccountManagement(Boolean accountManagement) {
this.accountManagement = accountManagement;
}
public Boolean isSslNotRequired() { public Boolean isSslNotRequired() {
return sslNotRequired; return sslNotRequired;
} }
@ -279,12 +270,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() {

View file

@ -4,11 +4,10 @@
"tokenLifespan": 3000, "tokenLifespan": 3000,
"accessCodeLifespan": 10, "accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 6000, "accessCodeLifespanUserAction": 6000,
"accountManagement": true,
"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" ],

View file

@ -0,0 +1,105 @@
{
"realm": "demo",
"enabled": true,
"tokenLifespan": 3000,
"accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 6000,
"sslNotRequired": true,
"registrationAllowed": false,
"social": 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" ],
"requiredApplicationCredentials": [ "password" ],
"requiredOAuthClientCredentials": [ "password" ],
"users" : [
{
"username" : "bburke@redhat.com",
"enabled": true,
"attributes" : {
"email" : "bburke@redhat.com"
},
"credentials" : [
{ "type" : "password",
"value" : "password" }
]
}
],
"roles": [
{
"name": "user",
"description": "User privileges"
},
{
"name": "admin",
"description": "Administrator privileges"
}
],
"roleMappings": [
{
"username": "bburke@redhat.com",
"roles": ["user"]
}
],
"scopeMappings": [
{
"username": "third-party",
"roles": ["user"]
},
{
"username": "customer-portal",
"roles": ["user"]
},
{
"username": "product-portal",
"roles": ["user"]
}
],
"applications": [
{
"name": "customer-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/customer-portal",
"credentials": [
{
"type": "password",
"value": "password"
}
]
},
{
"name": "product-portal",
"enabled": true,
"adminUrl": "http://localhost:8080/product-portal",
"credentials": [
{
"type": "password",
"value": "password"
}
]
}
],
"oauthClients": [
{
"name": "third-party",
"enabled": true,
"credentials": [
{
"type": "password",
"value": "password"
}
]
}
],
"applicationRoleMappings": {
"account": [
{
"username": "bburke@redhat.com",
"roles": ["manage-account"]
}
]
}
}

View file

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

View file

@ -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() {

View file

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

View file

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

View file

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

View file

@ -444,7 +444,19 @@ public class RealmAdapter implements RealmModel {
entity.setRealm(realm); entity.setRealm(realm);
em.persist(entity); em.persist(entity);
em.flush(); 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 @Override
@ -663,13 +675,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();
} }

View file

@ -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() {

View file

@ -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();
} }
@ -516,7 +516,19 @@ public class RealmAdapter implements RealmModel {
if (user != null) throw new IllegalStateException("User already exists"); if (user != null) throw new IllegalStateException("User already exists");
user = new User(username); user = new User(username);
getIdm().add(user); 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 @Override
@ -885,7 +897,7 @@ public class RealmAdapter implements RealmModel {
@Override @Override
public Set<SocialLinkModel> getSocialLinks(UserModel user) { public Set<SocialLinkModel> getSocialLinks(UserModel user) {
RelationshipQuery<SocialLinkRelationship> query = getRelationshipManager().createRelationshipQuery(SocialLinkRelationship.class); RelationshipQuery<SocialLinkRelationship> query = getRelationshipManager().createRelationshipQuery(SocialLinkRelationship.class);
query.setParameter(SocialLinkRelationship.USER, ((UserAdapter)user).getUser()); query.setParameter(SocialLinkRelationship.USER, ((UserAdapter) user).getUser());
List<SocialLinkRelationship> plSocialLinks = query.getResultList(); List<SocialLinkRelationship> plSocialLinks = query.getResultList();
Set<SocialLinkModel> results = new HashSet<SocialLinkModel>(); Set<SocialLinkModel> results = new HashSet<SocialLinkModel>();

View file

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

View file

@ -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() {

View file

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

View file

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

View file

@ -76,7 +76,6 @@ public class ApplianceBootstrap {
adminConsole.grantRole(adminUser, adminRole); adminConsole.grantRole(adminUser, adminRole);
manager.enableAccountManagement(realm);
ApplicationModel accountApp = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION); ApplicationModel accountApp = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
for (String r : accountApp.getDefaultRoles()) { for (String r : accountApp.getDefaultRoles()) {
accountApp.grantRole(adminUser, accountApp.getRole(r)); accountApp.grantRole(adminUser, accountApp.getRole(r));

View file

@ -78,6 +78,9 @@ public class RealmManager {
realm.setName(name); realm.setName(name);
realm.addRole(Constants.APPLICATION_ROLE); realm.addRole(Constants.APPLICATION_ROLE);
realm.addRole(Constants.IDENTITY_REQUESTER_ROLE); realm.addRole(Constants.IDENTITY_REQUESTER_ROLE);
setupAccountManagement(realm);
return realm; return realm;
} }
@ -102,8 +105,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)
@ -125,12 +128,6 @@ public class RealmManager {
realm.updateDefaultRoles(rep.getDefaultRoles().toArray(new String[rep.getDefaultRoles().size()])); 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) { if (rep.getSmtpServer() != null) {
realm.setSmtpConfig(new HashMap(rep.getSmtpServer())); 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); ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
if (application == null) { if (application == null) {
application = realm.addApplication(Constants.ACCOUNT_APPLICATION); application = realm.addApplication(Constants.ACCOUNT_APPLICATION);
application.setEnabled(true);
application.addDefaultRole(Constants.ACCOUNT_PROFILE_ROLE); application.addDefaultRole(Constants.ACCOUNT_PROFILE_ROLE);
application.addDefaultRole(Constants.ACCOUNT_MANAGE_ROLE); application.addDefaultRole(Constants.ACCOUNT_MANAGE_ROLE);
@ -160,14 +159,6 @@ public class RealmManager {
RoleModel applicationRole = realm.getRole(Constants.APPLICATION_ROLE); RoleModel applicationRole = realm.getRole(Constants.APPLICATION_ROLE);
realm.grantRole(application.getApplicationUser(), applicationRole); 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) { public RealmModel importRealm(RealmRepresentation rep, UserModel realmCreator) {
@ -180,7 +171,6 @@ public class RealmManager {
return realm; return realm;
} }
public void importRealm(RealmRepresentation rep, RealmModel newRealm) { public void importRealm(RealmRepresentation rep, RealmModel newRealm) {
newRealm.setName(rep.getRealm()); newRealm.setName(rep.getRealm());
if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled()); if (rep.isEnabled() != null) newRealm.setEnabled(rep.isEnabled());
@ -200,8 +190,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 {
@ -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 // Now that all possible users and applications are created (users, apps, and oauth clients), do role mappings and scope mappings
Map<String, ApplicationModel> appMap = newRealm.getApplicationNameMap(); Map<String, ApplicationModel> appMap = newRealm.getApplicationNameMap();
@ -475,7 +461,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());
@ -492,7 +478,6 @@ public class RealmManager {
} }
ApplicationModel accountManagementApplication = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION); ApplicationModel accountManagementApplication = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
rep.setAccountManagement(accountManagementApplication != null && accountManagementApplication.isEnabled());
List<String> defaultRoles = realm.getDefaultRoles(); List<String> defaultRoles = realm.getDefaultRoles();
if (!defaultRoles.isEmpty()) { if (!defaultRoles.isEmpty()) {

View file

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

View file

@ -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);
@ -354,18 +339,7 @@ public class TokenService {
realm.updateCredential(user, credentials); realm.updateCredential(user, credentials);
} }
for (String r : realm.getDefaultRoles()) { return processLogin(clientId, scopeParam, state, redirect, formData);
realm.grantRole(user, realm.getRole(r));
}
for (ApplicationModel application : realm.getApplications()) {
for (String r : application.getDefaultRoles()) {
application.grantRole(user, application.getRole(r));
}
}
return null;
} }
@Path("access/codes") @Path("access/codes")
@ -647,7 +621,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()) {

View file

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

View file

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

View file

@ -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));
@ -438,8 +438,8 @@ public class AdapterTest extends AbstractKeycloakTest {
RealmModel otherRealm = adapter.createRealm("other"); RealmModel otherRealm = adapter.createRealm("other");
otherRealm.addUser("bburke"); otherRealm.addUser("bburke");
Assert.assertEquals(1, otherRealm.getUsers().size()); Assert.assertEquals(2, otherRealm.getUsers().size());
Assert.assertEquals(1, otherRealm.searchForUser("u").size()); Assert.assertEquals(1, otherRealm.searchForUser("bu").size());
} }

View file

@ -68,7 +68,7 @@ public class ApplicationModelTest extends AbstractKeycloakServerTest {
public void persist() { public void persist() {
RealmModel persisted = manager.getRealm(realm.getId()); RealmModel persisted = manager.getRealm(realm.getId());
assertEquals(application, persisted.getApplications().get(0)); assertEquals(application, persisted.getApplicationNameMap().get("app-name"));
} }
@Test @Test

View file

@ -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);
@ -54,7 +54,7 @@ public class ImportTest extends AbstractKeycloakTest {
Assert.assertEquals(0, realm.getSocialLinks(user).size()); Assert.assertEquals(0, realm.getSocialLinks(user).size());
List<ApplicationModel> resources = realm.getApplications(); List<ApplicationModel> resources = realm.getApplications();
Assert.assertEquals(2, resources.size()); Assert.assertEquals(3, resources.size());
// Test scope relationship // Test scope relationship
ApplicationModel application = realm.getApplicationNameMap().get("Application"); ApplicationModel application = realm.getApplicationNameMap().get("Application");
@ -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");

View file

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

View file

@ -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" ],

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -54,12 +54,12 @@ public class ProfileTest {
user.setAttribute("key2", "value2"); user.setAttribute("key2", "value2");
ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION); 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"); UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
user2.setEnabled(true); user2.setEnabled(true);
for (String r : accountApp.getDefaultRoles()) {
accountApp.deleteRoleMapping(user2, accountApp.getRole(r));
}
UserCredentialModel creds = new UserCredentialModel(); UserCredentialModel creds = new UserCredentialModel();
creds.setType(CredentialRepresentation.PASSWORD); creds.setType(CredentialRepresentation.PASSWORD);
creds.setValue("password"); creds.setValue("password");

View file

@ -52,13 +52,14 @@ public class AccountTest {
@Override @Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
UserModel user = appRealm.getUser("test-user@localhost"); UserModel user = appRealm.getUser("test-user@localhost");
ApplicationModel accountApp = appRealm.getApplicationNameMap().get(org.keycloak.models.Constants.ACCOUNT_APPLICATION); 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"); UserModel user2 = appRealm.addUser("test-user-no-access@localhost");
user2.setEnabled(true); user2.setEnabled(true);
for (String r : accountApp.getDefaultRoles()) {
accountApp.deleteRoleMapping(user2, accountApp.getRole(r));
}
UserCredentialModel creds = new UserCredentialModel(); UserCredentialModel creds = new UserCredentialModel();
creds.setType(CredentialRepresentation.PASSWORD); creds.setType(CredentialRepresentation.PASSWORD);
creds.setValue("password"); creds.setValue("password");

View file

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

View file

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

View file

@ -7,7 +7,6 @@
"accessCodeLifespanUserAction": 600, "accessCodeLifespanUserAction": 600,
"sslNotRequired": true, "sslNotRequired": true,
"registrationAllowed": true, "registrationAllowed": true,
"accountManagement": true,
"resetPasswordAllowed": true, "resetPasswordAllowed": true,
"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",