Skip to content

Commit

Permalink
required actions storage/display
Browse files Browse the repository at this point in the history
  • Loading branch information
patriot1burke committed Jun 17, 2015
1 parent 3b78fa2 commit dddc518
Show file tree
Hide file tree
Showing 24 changed files with 345 additions and 31 deletions.
Expand Up @@ -77,6 +77,7 @@
<constraints nullable="false"/> <constraints nullable="false"/>
</column> </column>
<column name="ALIAS" type="VARCHAR(255)"/> <column name="ALIAS" type="VARCHAR(255)"/>
<column name="NAME" type="VARCHAR(255)"/>
<column name="REALM_ID" type="VARCHAR(36)"/> <column name="REALM_ID" type="VARCHAR(36)"/>
<column name="ENABLED" type="BOOLEAN" defaultValueBoolean="false"> <column name="ENABLED" type="BOOLEAN" defaultValueBoolean="false">
<constraints nullable="false"/> <constraints nullable="false"/>
Expand Down
Expand Up @@ -1611,13 +1611,28 @@ module.controller('AuthenticationFlowsCtrl', function($scope, realm, Authenticat
}); });


module.controller('RequiredActionsCtrl', function($scope, realm, RequiredActions, Notifications, Dialog, $location) { module.controller('RequiredActionsCtrl', function($scope, realm, RequiredActions, Notifications, Dialog, $location) {
console.log('RequiredActionsCtrl');
$scope.realm = realm; $scope.realm = realm;
$scope.requiredActions = [];
var setupRequiredActionsForm = function() {
console.log('setupRequiredActionsForm');
RequiredActions.query({id: realm.realm}, function(data) {
$scope.requiredActions = [];
for (var i = 0; i < data.length; i++) {
$scope.requiredActions.push(data[i]);
}
});
};


$scope.updateRequiredAction = function(action) {
RequiredActions.update({realm: realm.realm, alias: action.alias}, action, function() {
Notifications.success("Auth requirement updated");
setupForm();
setupRequiredActionsForm();
});
}


}); setupRequiredActionsForm();

module.controller('DefaultRequiredActionsCtrl', function($scope, realm, RequiredActions, Notifications, Dialog, $location) {
$scope.realm = realm;




}); });
Expand All @@ -1627,3 +1642,4 @@ module.controller('DefaultRequiredActionsCtrl', function($scope, realm, Required







Expand Up @@ -228,8 +228,8 @@ module.controller('UserDetailCtrl', function($scope, realm, user, User, UserFede
RequiredActions.query({id: realm.realm}, function(data) { RequiredActions.query({id: realm.realm}, function(data) {
$scope.userReqActionList = []; $scope.userReqActionList = [];
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
console.log("listed required action: " + data[i].text); console.log("listed required action: " + data[i].name);
item = { id: data[i].id, text: data[i].text }; item = data[i];
$scope.userReqActionList.push(item); $scope.userReqActionList.push(item);
} }


Expand Down
Expand Up @@ -63,6 +63,14 @@ module.factory('UserListLoader', function(Loader, User, $route, $q) {
}); });
}); });


module.factory('RequiredActionsListLoader', function(Loader, RequiredActions, $route, $q) {
return Loader.query(RequiredActions, function() {
return {
realm : $route.current.params.realm
}
});
});

module.factory('RealmSessionStatsLoader', function(Loader, RealmSessionStats, $route, $q) { module.factory('RealmSessionStatsLoader', function(Loader, RealmSessionStats, $route, $q) {
return Loader.get(RealmSessionStats, function() { return Loader.get(RealmSessionStats, function() {
return { return {
Expand Down
Expand Up @@ -187,8 +187,13 @@ module.factory('RealmAdminEvents', function($resource) {
}); });


module.factory('RequiredActions', function($resource) { module.factory('RequiredActions', function($resource) {
return $resource(authUrl + '/admin/realms/:id/required-actions', { return $resource(authUrl + '/admin/realms/:id/authentication/required-actions/:alias', {
id : '@realm' realm : '@realm',
alias : '@alias'
}, {
update : {
method : 'PUT'
}
}); });
}); });


Expand Down
Expand Up @@ -27,7 +27,7 @@ <h1>Authentication</h1>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="execution in executions"> <tr ng-repeat="execution in executions" data-ng-show="executions.length > 0">
<td ng-show="execution.subFlow"></td> <td ng-show="execution.subFlow"></td>
<td><h2>{{execution.referenceType}}</h2></td> <td><h2>{{execution.referenceType}}</h2></td>
<td ng-hide="execution.subFlow"></td> <td ng-hide="execution.subFlow"></td>
Expand Down
Expand Up @@ -2,6 +2,25 @@
<h1>Authentication</h1> <h1>Authentication</h1>


<kc-tabs-authentication></kc-tabs-authentication> <kc-tabs-authentication></kc-tabs-authentication>
<table class="table table-striped table-bordered">
<thead>
<tr data-ng-hide="requiredActions.length == 0">
<th>Required Action</th>
<th>Enabled</th>
<th>Default Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="requiredAction in requiredActions" data-ng-show="requiredActions.length > 0">
<td>{{requiredAction.name}}</td>
<td>{{requiredAction.enabled}}</td>
<td>{{requiredAction.defaultAction}}</td>
</tr>
<tr data-ng-show="requiredActions.length == 0">
<td>No required actions configured</td>
</tr>
</tbody>
</table>


</div> </div>


Expand Down
Expand Up @@ -80,7 +80,7 @@ <h1 data-ng-show="create">Add User</h1>


<div class="col-md-6"> <div class="col-md-6">
<select ui-select2 id="reqActions" ng-model="user.requiredActions" data-placeholder="Select an action..." multiple> <select ui-select2 id="reqActions" ng-model="user.requiredActions" data-placeholder="Select an action..." multiple>
<option ng-repeat="action in userReqActionList" value="{{action.id}}">{{action.text}}</option> <option ng-repeat="action in userReqActionList" value="{{action.alias}}">{{action.name}}</option>
</select> </select>
</div> </div>
<kc-tooltip>Require an action when the user logs in. 'Verify email' sends an email to the user to verify their email address. 'Update profile' requires user to enter in new personal information. 'Update password' requires user to enter in a new password. 'Configure TOTP' requires setup of a mobile password generator.</kc-tooltip> <kc-tooltip>Require an action when the user logs in. 'Verify email' sends an email to the user to verify their email address. 'Update profile' requires user to enter in new personal information. 'Update password' requires user to enter in a new password. 'Configure TOTP' requires setup of a mobile password generator.</kc-tooltip>
Expand Down
Expand Up @@ -10,6 +10,7 @@
import org.keycloak.models.UserFederationProviderFactory; import org.keycloak.models.UserFederationProviderFactory;
import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.models.utils.DefaultRequiredActions;


import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
Expand All @@ -28,10 +29,6 @@ public class MigrateTo1_3_0 {
public void migrate(KeycloakSession session) { public void migrate(KeycloakSession session) {
List<RealmModel> realms = session.realms().getRealms(); List<RealmModel> realms = session.realms().getRealms();
for (RealmModel realm : realms) { for (RealmModel realm : realms) {
if (realm.getAuthenticationFlows().size() == 0) {
DefaultAuthenticationFlows.addFlows(realm);
}

migrateLDAPProviders(session, realm); migrateLDAPProviders(session, realm);
} }


Expand Down
Expand Up @@ -4,6 +4,7 @@
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.models.utils.DefaultRequiredActions;


import java.util.List; import java.util.List;


Expand All @@ -20,6 +21,7 @@ public void migrate(KeycloakSession session) {
for (RealmModel realm : realms) { for (RealmModel realm : realms) {
if (realm.getAuthenticationFlows().size() == 0) { if (realm.getAuthenticationFlows().size() == 0) {
DefaultAuthenticationFlows.addFlows(realm); DefaultAuthenticationFlows.addFlows(realm);
DefaultRequiredActions.addActions(realm);
} }


} }
Expand Down
Expand Up @@ -204,6 +204,7 @@ interface UserFederationMapperEvent extends ProviderEvent {
void updateRequiredActionProvider(RequiredActionProviderModel model); void updateRequiredActionProvider(RequiredActionProviderModel model);
void removeRequiredActionProvider(RequiredActionProviderModel model); void removeRequiredActionProvider(RequiredActionProviderModel model);
RequiredActionProviderModel getRequiredActionProviderById(String id); RequiredActionProviderModel getRequiredActionProviderById(String id);
RequiredActionProviderModel getRequiredActionProviderByAlias(String alias);


List<IdentityProviderModel> getIdentityProviders(); List<IdentityProviderModel> getIdentityProviders();
IdentityProviderModel getIdentityProviderByAlias(String alias); IdentityProviderModel getIdentityProviderByAlias(String alias);
Expand Down
Expand Up @@ -11,6 +11,7 @@ public class RequiredActionProviderModel {


private String id; private String id;
private String alias; private String alias;
private String name;
private String providerId; private String providerId;
private boolean enabled; private boolean enabled;
private boolean defaultAction; private boolean defaultAction;
Expand All @@ -33,6 +34,20 @@ public void setAlias(String alias) {
this.alias = alias; this.alias = alias;
} }


/**
* Used for display purposes. Probably should clean this code up and make alias and name the same, but
* the old code references an Enum and the admin console creates a "friendly" name for each enum.
*
* @return
*/
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public boolean isEnabled() { public boolean isEnabled() {
return enabled; return enabled;
} }
Expand Down
Expand Up @@ -9,6 +9,7 @@
public class RequiredActionProviderEntity { public class RequiredActionProviderEntity {
protected String id; protected String id;
protected String alias; protected String alias;
protected String name;
protected String providerId; protected String providerId;
protected boolean enabled; protected boolean enabled;
protected boolean defaultAction; protected boolean defaultAction;
Expand All @@ -30,6 +31,14 @@ public void setAlias(String alias) {
this.alias = alias; this.alias = alias;
} }


public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public boolean isEnabled() { public boolean isEnabled() {
return enabled; return enabled;
} }
Expand Down
@@ -0,0 +1,69 @@
package org.keycloak.models.utils;

import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.AuthenticatorModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredActionProviderModel;
import org.keycloak.models.UserModel;

/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class DefaultRequiredActions {
public static void addActions(RealmModel realm) {
if (realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.VERIFY_EMAIL.name()) == null) {
RequiredActionProviderModel verifyEmail = new RequiredActionProviderModel();
verifyEmail.setEnabled(true);
verifyEmail.setAlias(UserModel.RequiredAction.VERIFY_EMAIL.name());
verifyEmail.setName("Verify Email");
verifyEmail.setProviderId(UserModel.RequiredAction.VERIFY_EMAIL.name());
verifyEmail.setDefaultAction(false);
realm.addRequiredActionProvider(verifyEmail);

}

if (realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.UPDATE_PROFILE.name()) == null) {
RequiredActionProviderModel updateProfile = new RequiredActionProviderModel();
updateProfile.setEnabled(true);
updateProfile.setAlias(UserModel.RequiredAction.UPDATE_PROFILE.name());
updateProfile.setName("Update Profile");
updateProfile.setProviderId(UserModel.RequiredAction.UPDATE_PROFILE.name());
updateProfile.setDefaultAction(false);
realm.addRequiredActionProvider(updateProfile);
}

if (realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.CONFIGURE_TOTP.name()) == null) {
RequiredActionProviderModel totp = new RequiredActionProviderModel();
totp.setEnabled(true);
totp.setAlias(UserModel.RequiredAction.CONFIGURE_TOTP.name());
totp.setName("Configure Totp");
totp.setProviderId(UserModel.RequiredAction.CONFIGURE_TOTP.name());
totp.setDefaultAction(false);
realm.addRequiredActionProvider(totp);
}

if (realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.UPDATE_PASSWORD.name()) == null) {
RequiredActionProviderModel updatePassword = new RequiredActionProviderModel();
updatePassword.setEnabled(true);
updatePassword.setAlias(UserModel.RequiredAction.UPDATE_PASSWORD.name());
updatePassword.setName("Update Password");
updatePassword.setProviderId(UserModel.RequiredAction.UPDATE_PASSWORD.name());
updatePassword.setDefaultAction(false);
realm.addRequiredActionProvider(updatePassword);
}

if (realm.getRequiredActionProviderByAlias("terms_and_conditions") == null) {
RequiredActionProviderModel termsAndConditions = new RequiredActionProviderModel();
termsAndConditions.setEnabled(false);
termsAndConditions.setAlias("terms_and_conditions");
termsAndConditions.setName("Terms and Conditions");
termsAndConditions.setProviderId("terms_and_conditions");
termsAndConditions.setDefaultAction(false);
realm.addRequiredActionProvider(termsAndConditions);
}


}
}
Expand Up @@ -1449,6 +1449,7 @@ public RequiredActionProviderModel addRequiredActionProvider(RequiredActionProvi
RequiredActionProviderEntity auth = new RequiredActionProviderEntity(); RequiredActionProviderEntity auth = new RequiredActionProviderEntity();
auth.setId(KeycloakModelUtils.generateId()); auth.setId(KeycloakModelUtils.generateId());
auth.setAlias(model.getAlias()); auth.setAlias(model.getAlias());
auth.setName(model.getName());
auth.setProviderId(model.getProviderId()); auth.setProviderId(model.getProviderId());
auth.setConfig(model.getConfig()); auth.setConfig(model.getConfig());
auth.setEnabled(model.isEnabled()); auth.setEnabled(model.isEnabled());
Expand Down Expand Up @@ -1477,6 +1478,7 @@ public RequiredActionProviderModel entityToModel(RequiredActionProviderEntity en
model.setId(entity.getId()); model.setId(entity.getId());
model.setProviderId(entity.getProviderId()); model.setProviderId(entity.getProviderId());
model.setAlias(entity.getAlias()); model.setAlias(entity.getAlias());
model.setName(entity.getName());
model.setEnabled(entity.isEnabled()); model.setEnabled(entity.isEnabled());
model.setDefaultAction(entity.isDefaultAction()); model.setDefaultAction(entity.isDefaultAction());
Map<String, String> config = new HashMap<>(); Map<String, String> config = new HashMap<>();
Expand All @@ -1492,6 +1494,7 @@ public void updateRequiredActionProvider(RequiredActionProviderModel model) {
entity.setAlias(model.getAlias()); entity.setAlias(model.getAlias());
entity.setProviderId(model.getProviderId()); entity.setProviderId(model.getProviderId());
entity.setEnabled(model.isEnabled()); entity.setEnabled(model.isEnabled());
entity.setName(model.getName());
entity.setDefaultAction(model.isDefaultAction()); entity.setDefaultAction(model.isDefaultAction());
if (entity.getConfig() == null) { if (entity.getConfig() == null) {
entity.setConfig(model.getConfig()); entity.setConfig(model.getConfig());
Expand Down Expand Up @@ -1521,6 +1524,15 @@ public RequiredActionProviderEntity getRequiredActionProviderEntity(String id) {
return entity; return entity;
} }


@Override
public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) {
for (RequiredActionProviderModel action : getRequiredActionProviders()) {
if (action.getAlias().equals(alias)) return action;
}
return null;
}






@Override @Override
Expand Down
Expand Up @@ -1161,4 +1161,10 @@ public RequiredActionProviderModel getRequiredActionProviderById(String id) {
if (updated != null) return updated.getRequiredActionProviderById(id); if (updated != null) return updated.getRequiredActionProviderById(id);
return cached.getRequiredActionProviders().get(id); return cached.getRequiredActionProviders().get(id);
} }

@Override
public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) {
if (updated != null) return updated.getRequiredActionProviderByAlias(alias);
return cached.getRequiredActionProvidersByAlias().get(alias);
}
} }
Expand Up @@ -83,6 +83,7 @@ public class CachedRealm {
private Map<String, AuthenticationFlowModel> authenticationFlows = new HashMap<>(); private Map<String, AuthenticationFlowModel> authenticationFlows = new HashMap<>();
private Map<String, AuthenticatorModel> authenticators = new HashMap<>(); private Map<String, AuthenticatorModel> authenticators = new HashMap<>();
private Map<String, RequiredActionProviderModel> requiredActionProviders = new HashMap<>(); private Map<String, RequiredActionProviderModel> requiredActionProviders = new HashMap<>();
private Map<String, RequiredActionProviderModel> requiredActionProvidersByAlias = new HashMap<>();
private MultivaluedHashMap<String, AuthenticationExecutionModel> authenticationExecutions = new MultivaluedHashMap<>(); private MultivaluedHashMap<String, AuthenticationExecutionModel> authenticationExecutions = new MultivaluedHashMap<>();
private Map<String, AuthenticationExecutionModel> executionsById = new HashMap<>(); private Map<String, AuthenticationExecutionModel> executionsById = new HashMap<>();


Expand Down Expand Up @@ -204,6 +205,7 @@ public CachedRealm(RealmCache cache, RealmProvider delegate, RealmModel model) {
} }
for (RequiredActionProviderModel action : model.getRequiredActionProviders()) { for (RequiredActionProviderModel action : model.getRequiredActionProviders()) {
requiredActionProviders.put(action.getId(), action); requiredActionProviders.put(action.getId(), action);
requiredActionProvidersByAlias.put(action.getAlias(), action);
} }


} }
Expand Down Expand Up @@ -447,4 +449,8 @@ public Map<String, AuthenticationExecutionModel> getExecutionsById() {
public Map<String, RequiredActionProviderModel> getRequiredActionProviders() { public Map<String, RequiredActionProviderModel> getRequiredActionProviders() {
return requiredActionProviders; return requiredActionProviders;
} }

public Map<String, RequiredActionProviderModel> getRequiredActionProvidersByAlias() {
return requiredActionProvidersByAlias;
}
} }

0 comments on commit dddc518

Please sign in to comment.