required actions storage/display
This commit is contained in:
parent
3b78fa2d5d
commit
dddc5181e7
24 changed files with 345 additions and 31 deletions
|
@ -77,6 +77,7 @@
|
|||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ALIAS" type="VARCHAR(255)"/>
|
||||
<column name="NAME" type="VARCHAR(255)"/>
|
||||
<column name="REALM_ID" type="VARCHAR(36)"/>
|
||||
<column name="ENABLED" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
|
|
|
@ -1611,13 +1611,28 @@ module.controller('AuthenticationFlowsCtrl', function($scope, realm, Authenticat
|
|||
});
|
||||
|
||||
module.controller('RequiredActionsCtrl', function($scope, realm, RequiredActions, Notifications, Dialog, $location) {
|
||||
console.log('RequiredActionsCtrl');
|
||||
$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]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.controller('DefaultRequiredActionsCtrl', function($scope, realm, RequiredActions, Notifications, Dialog, $location) {
|
||||
$scope.realm = realm;
|
||||
$scope.updateRequiredAction = function(action) {
|
||||
RequiredActions.update({realm: realm.realm, alias: action.alias}, action, function() {
|
||||
Notifications.success("Auth requirement updated");
|
||||
setupForm();
|
||||
setupRequiredActionsForm();
|
||||
});
|
||||
}
|
||||
|
||||
setupRequiredActionsForm();
|
||||
|
||||
|
||||
});
|
||||
|
@ -1627,3 +1642,4 @@ module.controller('DefaultRequiredActionsCtrl', function($scope, realm, Required
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -228,8 +228,8 @@ module.controller('UserDetailCtrl', function($scope, realm, user, User, UserFede
|
|||
RequiredActions.query({id: realm.realm}, function(data) {
|
||||
$scope.userReqActionList = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
console.log("listed required action: " + data[i].text);
|
||||
item = { id: data[i].id, text: data[i].text };
|
||||
console.log("listed required action: " + data[i].name);
|
||||
item = data[i];
|
||||
$scope.userReqActionList.push(item);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
return Loader.get(RealmSessionStats, function() {
|
||||
return {
|
||||
|
|
|
@ -187,8 +187,13 @@ module.factory('RealmAdminEvents', function($resource) {
|
|||
});
|
||||
|
||||
module.factory('RequiredActions', function($resource) {
|
||||
return $resource(authUrl + '/admin/realms/:id/required-actions', {
|
||||
id : '@realm'
|
||||
return $resource(authUrl + '/admin/realms/:id/authentication/required-actions/:alias', {
|
||||
realm : '@realm',
|
||||
alias : '@alias'
|
||||
}, {
|
||||
update : {
|
||||
method : 'PUT'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<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><h2>{{execution.referenceType}}</h2></td>
|
||||
<td ng-hide="execution.subFlow"></td>
|
||||
|
|
|
@ -2,6 +2,25 @@
|
|||
<h1>Authentication</h1>
|
||||
|
||||
<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>
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
|
||||
<div class="col-md-6">
|
||||
<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>
|
||||
</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>
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.keycloak.models.UserFederationProvider;
|
|||
import org.keycloak.models.UserFederationProviderFactory;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.models.utils.DefaultRequiredActions;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -28,10 +29,6 @@ public class MigrateTo1_3_0 {
|
|||
public void migrate(KeycloakSession session) {
|
||||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
if (realm.getAuthenticationFlows().size() == 0) {
|
||||
DefaultAuthenticationFlows.addFlows(realm);
|
||||
}
|
||||
|
||||
migrateLDAPProviders(session, realm);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.keycloak.migration.ModelVersion;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.models.utils.DefaultRequiredActions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -20,6 +21,7 @@ public class MigrateTo1_4_0 {
|
|||
for (RealmModel realm : realms) {
|
||||
if (realm.getAuthenticationFlows().size() == 0) {
|
||||
DefaultAuthenticationFlows.addFlows(realm);
|
||||
DefaultRequiredActions.addActions(realm);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -204,6 +204,7 @@ public interface RealmModel extends RoleContainerModel {
|
|||
void updateRequiredActionProvider(RequiredActionProviderModel model);
|
||||
void removeRequiredActionProvider(RequiredActionProviderModel model);
|
||||
RequiredActionProviderModel getRequiredActionProviderById(String id);
|
||||
RequiredActionProviderModel getRequiredActionProviderByAlias(String alias);
|
||||
|
||||
List<IdentityProviderModel> getIdentityProviders();
|
||||
IdentityProviderModel getIdentityProviderByAlias(String alias);
|
||||
|
|
|
@ -11,6 +11,7 @@ public class RequiredActionProviderModel {
|
|||
|
||||
private String id;
|
||||
private String alias;
|
||||
private String name;
|
||||
private String providerId;
|
||||
private boolean enabled;
|
||||
private boolean defaultAction;
|
||||
|
@ -33,6 +34,20 @@ public class RequiredActionProviderModel {
|
|||
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() {
|
||||
return enabled;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Map;
|
|||
public class RequiredActionProviderEntity {
|
||||
protected String id;
|
||||
protected String alias;
|
||||
protected String name;
|
||||
protected String providerId;
|
||||
protected boolean enabled;
|
||||
protected boolean defaultAction;
|
||||
|
@ -30,6 +31,14 @@ public class RequiredActionProviderEntity {
|
|||
this.alias = alias;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1449,6 +1449,7 @@ public class RealmAdapter implements RealmModel {
|
|||
RequiredActionProviderEntity auth = new RequiredActionProviderEntity();
|
||||
auth.setId(KeycloakModelUtils.generateId());
|
||||
auth.setAlias(model.getAlias());
|
||||
auth.setName(model.getName());
|
||||
auth.setProviderId(model.getProviderId());
|
||||
auth.setConfig(model.getConfig());
|
||||
auth.setEnabled(model.isEnabled());
|
||||
|
@ -1477,6 +1478,7 @@ public class RealmAdapter implements RealmModel {
|
|||
model.setId(entity.getId());
|
||||
model.setProviderId(entity.getProviderId());
|
||||
model.setAlias(entity.getAlias());
|
||||
model.setName(entity.getName());
|
||||
model.setEnabled(entity.isEnabled());
|
||||
model.setDefaultAction(entity.isDefaultAction());
|
||||
Map<String, String> config = new HashMap<>();
|
||||
|
@ -1492,6 +1494,7 @@ public class RealmAdapter implements RealmModel {
|
|||
entity.setAlias(model.getAlias());
|
||||
entity.setProviderId(model.getProviderId());
|
||||
entity.setEnabled(model.isEnabled());
|
||||
entity.setName(model.getName());
|
||||
entity.setDefaultAction(model.isDefaultAction());
|
||||
if (entity.getConfig() == null) {
|
||||
entity.setConfig(model.getConfig());
|
||||
|
@ -1521,6 +1524,15 @@ public class RealmAdapter implements RealmModel {
|
|||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) {
|
||||
for (RequiredActionProviderModel action : getRequiredActionProviders()) {
|
||||
if (action.getAlias().equals(alias)) return action;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1161,4 +1161,10 @@ public class RealmAdapter implements RealmModel {
|
|||
if (updated != null) return updated.getRequiredActionProviderById(id);
|
||||
return cached.getRequiredActionProviders().get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) {
|
||||
if (updated != null) return updated.getRequiredActionProviderByAlias(alias);
|
||||
return cached.getRequiredActionProvidersByAlias().get(alias);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ public class CachedRealm {
|
|||
private Map<String, AuthenticationFlowModel> authenticationFlows = new HashMap<>();
|
||||
private Map<String, AuthenticatorModel> authenticators = new HashMap<>();
|
||||
private Map<String, RequiredActionProviderModel> requiredActionProviders = new HashMap<>();
|
||||
private Map<String, RequiredActionProviderModel> requiredActionProvidersByAlias = new HashMap<>();
|
||||
private MultivaluedHashMap<String, AuthenticationExecutionModel> authenticationExecutions = new MultivaluedHashMap<>();
|
||||
private Map<String, AuthenticationExecutionModel> executionsById = new HashMap<>();
|
||||
|
||||
|
@ -204,6 +205,7 @@ public class CachedRealm {
|
|||
}
|
||||
for (RequiredActionProviderModel action : model.getRequiredActionProviders()) {
|
||||
requiredActionProviders.put(action.getId(), action);
|
||||
requiredActionProvidersByAlias.put(action.getAlias(), action);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -447,4 +449,8 @@ public class CachedRealm {
|
|||
public Map<String, RequiredActionProviderModel> getRequiredActionProviders() {
|
||||
return requiredActionProviders;
|
||||
}
|
||||
|
||||
public Map<String, RequiredActionProviderModel> getRequiredActionProvidersByAlias() {
|
||||
return requiredActionProvidersByAlias;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1732,6 +1732,7 @@ public class RealmAdapter implements RealmModel {
|
|||
RequiredActionProviderEntity auth = new RequiredActionProviderEntity();
|
||||
auth.setId(KeycloakModelUtils.generateId());
|
||||
auth.setAlias(model.getAlias());
|
||||
auth.setName(model.getName());
|
||||
auth.setRealm(realm);
|
||||
auth.setProviderId(model.getProviderId());
|
||||
auth.setConfig(model.getConfig());
|
||||
|
@ -1767,6 +1768,7 @@ public class RealmAdapter implements RealmModel {
|
|||
model.setAlias(entity.getAlias());
|
||||
model.setEnabled(entity.isEnabled());
|
||||
model.setDefaultAction(entity.isDefaultAction());
|
||||
model.setName(entity.getName());
|
||||
Map<String, String> config = new HashMap<>();
|
||||
if (entity.getConfig() != null) config.putAll(entity.getConfig());
|
||||
model.setConfig(config);
|
||||
|
@ -1781,6 +1783,7 @@ public class RealmAdapter implements RealmModel {
|
|||
entity.setProviderId(model.getProviderId());
|
||||
entity.setEnabled(model.isEnabled());
|
||||
entity.setDefaultAction(model.isDefaultAction());
|
||||
entity.setName(model.getName());
|
||||
if (entity.getConfig() == null) {
|
||||
entity.setConfig(model.getConfig());
|
||||
} else {
|
||||
|
@ -1799,4 +1802,12 @@ public class RealmAdapter implements RealmModel {
|
|||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) {
|
||||
for (RequiredActionProviderModel action : getRequiredActionProviders()) {
|
||||
if (action.getAlias().equals(alias)) return action;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -30,6 +30,9 @@ public class RequiredActionProviderEntity {
|
|||
@Column(name="ALIAS")
|
||||
protected String alias;
|
||||
|
||||
@Column(name="NAME")
|
||||
protected String name;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "REALM_ID")
|
||||
protected RealmEntity realm;
|
||||
|
@ -104,4 +107,12 @@ public class RequiredActionProviderEntity {
|
|||
public void setConfig(Map<String, String> config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1607,6 +1607,15 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
|||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) {
|
||||
for (RequiredActionProviderModel action : getRequiredActionProviders()) {
|
||||
if (action.getAlias().equals(alias)) return action;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.keycloak.jose.jws.JWSBuilder;
|
|||
import org.keycloak.login.LoginFormsProvider;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
|
@ -483,8 +484,9 @@ public class AuthenticationManager {
|
|||
};
|
||||
|
||||
// see if any required actions need triggering, i.e. an expired password
|
||||
for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(RequiredActionProvider.class)) {
|
||||
RequiredActionProvider provider = ((RequiredActionFactory)factory).create(session);
|
||||
for (RequiredActionProviderModel model : realm.getRequiredActionProviders()) {
|
||||
if (!model.isEnabled()) continue;
|
||||
RequiredActionProvider provider = session.getProvider(RequiredActionProvider.class, model.getProviderId());
|
||||
provider.evaluateTriggers(context);
|
||||
}
|
||||
|
||||
|
@ -495,7 +497,8 @@ public class AuthenticationManager {
|
|||
|
||||
Set<String> requiredActions = user.getRequiredActions();
|
||||
for (String action : requiredActions) {
|
||||
RequiredActionProvider actionProvider = session.getProvider(RequiredActionProvider.class, action);
|
||||
RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(action);
|
||||
RequiredActionProvider actionProvider = session.getProvider(RequiredActionProvider.class, model.getProviderId());
|
||||
Response challenge = actionProvider.invokeRequiredAction(context);
|
||||
if (challenge != null) {
|
||||
return challenge;
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.keycloak.models.UserFederationProviderModel;
|
|||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionProvider;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.models.utils.DefaultRequiredActions;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
|
@ -88,6 +89,7 @@ public class RealmManager {
|
|||
setupBrokerService(realm);
|
||||
setupAdminConsole(realm);
|
||||
setupAuthenticationFlows(realm);
|
||||
setupRequiredActions(realm);
|
||||
|
||||
return realm;
|
||||
}
|
||||
|
@ -96,6 +98,10 @@ public class RealmManager {
|
|||
if (realm.getAuthenticationFlows().size() == 0) DefaultAuthenticationFlows.addFlows(realm);
|
||||
}
|
||||
|
||||
protected void setupRequiredActions(RealmModel realm) {
|
||||
if (realm.getRequiredActionProviders().size() == 0) DefaultRequiredActions.addActions(realm);
|
||||
}
|
||||
|
||||
protected void setupAdminConsole(RealmModel realm) {
|
||||
ClientModel adminConsole = realm.getClientByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID);
|
||||
if (adminConsole == null) adminConsole = new ClientManager(this).createClient(realm, Constants.ADMIN_CONSOLE_CLIENT_ID);
|
||||
|
@ -261,6 +267,7 @@ public class RealmManager {
|
|||
RepresentationToModel.importRealm(session, rep, realm);
|
||||
|
||||
setupAuthenticationFlows(realm);
|
||||
setupRequiredActions(realm);
|
||||
|
||||
// Refresh periodic sync tasks for configured federationProviders
|
||||
List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
|
||||
|
|
|
@ -6,13 +6,18 @@ import org.jboss.resteasy.spi.NotFoundException;
|
|||
import org.keycloak.authentication.Authenticator;
|
||||
import org.keycloak.authentication.AuthenticatorFactory;
|
||||
import org.keycloak.authentication.AuthenticatorUtil;
|
||||
import org.keycloak.authentication.RequiredActionFactory;
|
||||
import org.keycloak.authentication.RequiredActionProvider;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.AuthenticatorModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
|
@ -20,8 +25,10 @@ import javax.ws.rs.PathParam;
|
|||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
|
||||
|
||||
|
@ -176,4 +183,118 @@ public class AuthenticationManagementResource {
|
|||
realm.updateAuthenticatorExecution(model);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RequiredActionProviderRepresentation {
|
||||
private String alias;
|
||||
private String name;
|
||||
private boolean enabled;
|
||||
private boolean defaultAction;
|
||||
private Map<String, String> config = new HashMap<String, String>();
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public void setAlias(String alias) {
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isDefaultAction() {
|
||||
return defaultAction;
|
||||
}
|
||||
|
||||
public void setDefaultAction(boolean defaultAction) {
|
||||
this.defaultAction = defaultAction;
|
||||
}
|
||||
|
||||
public Map<String, String> getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void setConfig(Map<String, String> config) {
|
||||
this.config = config;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Path("required-actions")
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<RequiredActionProviderRepresentation> getRequiredActions() {
|
||||
List<RequiredActionProviderRepresentation> list = new LinkedList<>();
|
||||
for (RequiredActionProviderModel model : realm.getRequiredActionProviders()) {
|
||||
RequiredActionProviderRepresentation rep = toRepresentation(model);
|
||||
list.add(rep);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static RequiredActionProviderRepresentation toRepresentation(RequiredActionProviderModel model) {
|
||||
RequiredActionProviderRepresentation rep = new RequiredActionProviderRepresentation();
|
||||
rep.setAlias(model.getAlias());
|
||||
rep.setName(model.getName());
|
||||
rep.setDefaultAction(model.isDefaultAction());
|
||||
rep.setEnabled(model.isEnabled());
|
||||
rep.setConfig(model.getConfig());
|
||||
return rep;
|
||||
}
|
||||
|
||||
@Path("required-actions/{alias}")
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public RequiredActionProviderRepresentation getRequiredAction(@PathParam("alias") String alias) {
|
||||
RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(alias);
|
||||
if (model == null) {
|
||||
throw new NotFoundException("Failed to find required action: " + alias);
|
||||
}
|
||||
return toRepresentation(model);
|
||||
}
|
||||
|
||||
|
||||
@Path("required-actions/{alias}")
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public void updateRequiredAction(@PathParam("alias") String alias, RequiredActionProviderRepresentation rep) {
|
||||
RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(alias);
|
||||
if (model == null) {
|
||||
throw new NotFoundException("Failed to find required action: " + alias);
|
||||
}
|
||||
RequiredActionProviderModel update = new RequiredActionProviderModel();
|
||||
update.setId(update.getId());
|
||||
update.setName(rep.getName());
|
||||
update.setAlias(rep.getAlias());
|
||||
update.setProviderId(model.getProviderId());
|
||||
update.setDefaultAction(rep.isDefaultAction());
|
||||
update.setEnabled(rep.isEnabled());
|
||||
update.setConfig(rep.getConfig());
|
||||
realm.updateRequiredActionProvider(update);
|
||||
}
|
||||
|
||||
@Path("required-actions/{alias}")
|
||||
@DELETE
|
||||
public void updateRequiredAction(@PathParam("alias") String alias) {
|
||||
RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(alias);
|
||||
if (model == null) {
|
||||
throw new NotFoundException("Failed to find required action: " + alias);
|
||||
}
|
||||
realm.removeRequiredActionProvider(model);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -565,18 +565,4 @@ public class RealmAdminResource {
|
|||
return new IdentityProvidersResource(realm, session, this.auth, adminEvent);
|
||||
}
|
||||
|
||||
@Path("required-actions")
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<Map<String, String>> getRequiredActions() {
|
||||
List<Map<String, String>> list = new LinkedList<>();
|
||||
for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(RequiredActionProvider.class)) {
|
||||
RequiredActionFactory actionFactory = (RequiredActionFactory)factory;
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("id", actionFactory.getId());
|
||||
data.put("text", actionFactory.getDisplayText());
|
||||
list.add(data);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue