required actions model
This commit is contained in:
parent
2a64f5e3ce
commit
3b78fa2d5d
26 changed files with 614 additions and 146 deletions
|
@ -7,12 +7,6 @@
|
||||||
<delete tableName="CLIENT_SESSION"/>
|
<delete tableName="CLIENT_SESSION"/>
|
||||||
<delete tableName="USER_SESSION_NOTE"/>
|
<delete tableName="USER_SESSION_NOTE"/>
|
||||||
<delete tableName="USER_SESSION"/>
|
<delete tableName="USER_SESSION"/>
|
||||||
<createTable tableName="DEFAULT_REQUIRED_ACTIONS">
|
|
||||||
<column name="REALM_ID" type="VARCHAR(36)">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
<column name="VALUE" type="VARCHAR(36)"/>
|
|
||||||
</createTable>
|
|
||||||
<addColumn tableName="CLIENT_SESSION">
|
<addColumn tableName="CLIENT_SESSION">
|
||||||
<column name="CURRENT_ACTION" type="VARCHAR(36)">
|
<column name="CURRENT_ACTION" type="VARCHAR(36)">
|
||||||
<constraints nullable="false"/>
|
<constraints nullable="false"/>
|
||||||
|
@ -78,9 +72,35 @@
|
||||||
<constraints nullable="false"/>
|
<constraints nullable="false"/>
|
||||||
</column>
|
</column>
|
||||||
</createTable>
|
</createTable>
|
||||||
|
<createTable tableName="REQUIRED_ACTION_PROVIDER">
|
||||||
|
<column name="ID" type="VARCHAR(36)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="ALIAS" type="VARCHAR(255)"/>
|
||||||
|
<column name="REALM_ID" type="VARCHAR(36)"/>
|
||||||
|
<column name="ENABLED" type="BOOLEAN" defaultValueBoolean="false">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="DEFAULT_ACTION" type="BOOLEAN" defaultValueBoolean="false">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="PROVIDER_ID" type="VARCHAR(255)"/>
|
||||||
|
</createTable>
|
||||||
|
<createTable tableName="REQUIRED_ACTION_CONFIG">
|
||||||
|
<column name="REQUIRED_ACTION_ID" type="VARCHAR(36)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="VALUE" type="CLOB"/>
|
||||||
|
<column name="NAME" type="VARCHAR(255)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
</createTable>
|
||||||
|
|
||||||
|
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_REQ_ACT_PRV_PK" tableName="REQUIRED_ACTION_PROVIDER"/>
|
||||||
|
<addPrimaryKey columnNames="REQUIRED_ACTION_ID, NAME" constraintName="CONSTRAINT_REQ_ACT_CFG_PK" tableName="REQUIRED_ACTION_CONFIG"/>
|
||||||
<addPrimaryKey columnNames="CLIENT_SESSION, NAME" constraintName="CONSTR_CL_USR_SES_NOTE" tableName="CLIENT_USER_SESSION_NOTE"/>
|
<addPrimaryKey columnNames="CLIENT_SESSION, NAME" constraintName="CONSTR_CL_USR_SES_NOTE" tableName="CLIENT_USER_SESSION_NOTE"/>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REQUIRED_ACTION_PROVIDER" constraintName="FK_REQ_ACT_REALM" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||||
<addForeignKeyConstraint baseColumnNames="CLIENT_SESSION" baseTableName="CLIENT_USER_SESSION_NOTE" constraintName="FK_CL_USR_SES_NOTE" referencedColumnNames="ID" referencedTableName="CLIENT_SESSION"/>
|
<addForeignKeyConstraint baseColumnNames="CLIENT_SESSION" baseTableName="CLIENT_USER_SESSION_NOTE" constraintName="FK_CL_USR_SES_NOTE" referencedColumnNames="ID" referencedTableName="CLIENT_SESSION"/>
|
||||||
<dropColumn tableName="CLIENT_SESSION" columnName="ACTION"/>
|
<dropColumn tableName="CLIENT_SESSION" columnName="ACTION"/>
|
||||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="DEFAULT_REQUIRED_ACTIONS" constraintName="FK_DEF_REQ_ACTS_REALM" referencedColumnNames="ID" referencedTableName="REALM"/>
|
|
||||||
</changeSet>
|
</changeSet>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
<class>org.keycloak.models.jpa.entities.AuthenticationFlowEntity</class>
|
<class>org.keycloak.models.jpa.entities.AuthenticationFlowEntity</class>
|
||||||
<class>org.keycloak.models.jpa.entities.AuthenticationExecutionEntity</class>
|
<class>org.keycloak.models.jpa.entities.AuthenticationExecutionEntity</class>
|
||||||
<class>org.keycloak.models.jpa.entities.AuthenticatorEntity</class>
|
<class>org.keycloak.models.jpa.entities.AuthenticatorEntity</class>
|
||||||
|
<class>org.keycloak.models.jpa.entities.RequiredActionProviderEntity</class>
|
||||||
|
|
||||||
<!-- JpaUserSessionProvider -->
|
<!-- JpaUserSessionProvider -->
|
||||||
<class>org.keycloak.models.sessions.jpa.entities.ClientSessionEntity</class>
|
<class>org.keycloak.models.sessions.jpa.entities.ClientSessionEntity</class>
|
||||||
|
|
|
@ -1045,7 +1045,7 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||||
},
|
},
|
||||||
controller : 'ProtocolListCtrl'
|
controller : 'ProtocolListCtrl'
|
||||||
})
|
})
|
||||||
.when('/realms/:realm/authentication', {
|
.when('/realms/:realm/authentication/flows', {
|
||||||
templateUrl : resourceUrl + '/partials/authentication-flows.html',
|
templateUrl : resourceUrl + '/partials/authentication-flows.html',
|
||||||
resolve : {
|
resolve : {
|
||||||
realm : function(RealmLoader) {
|
realm : function(RealmLoader) {
|
||||||
|
@ -1054,7 +1054,15 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||||
},
|
},
|
||||||
controller : 'AuthenticationFlowsCtrl'
|
controller : 'AuthenticationFlowsCtrl'
|
||||||
})
|
})
|
||||||
|
.when('/realms/:realm/authentication/required-actions', {
|
||||||
|
templateUrl : resourceUrl + '/partials/required-actions.html',
|
||||||
|
resolve : {
|
||||||
|
realm : function(RealmLoader) {
|
||||||
|
return RealmLoader();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller : 'RequiredActionsCtrl'
|
||||||
|
})
|
||||||
.when('/server-info', {
|
.when('/server-info', {
|
||||||
templateUrl : resourceUrl + '/partials/server-info.html'
|
templateUrl : resourceUrl + '/partials/server-info.html'
|
||||||
})
|
})
|
||||||
|
@ -1502,6 +1510,15 @@ module.directive('kcTabsRealm', function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.directive('kcTabsAuthentication', function () {
|
||||||
|
return {
|
||||||
|
scope: true,
|
||||||
|
restrict: 'E',
|
||||||
|
replace: true,
|
||||||
|
templateUrl: resourceUrl + '/templates/kc-tabs-authentication.html'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
module.directive('kcTabsUser', function () {
|
module.directive('kcTabsUser', function () {
|
||||||
return {
|
return {
|
||||||
scope: true,
|
scope: true,
|
||||||
|
|
|
@ -1610,6 +1610,19 @@ module.controller('AuthenticationFlowsCtrl', function($scope, realm, Authenticat
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.controller('RequiredActionsCtrl', function($scope, realm, RequiredActions, Notifications, Dialog, $location) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.controller('DefaultRequiredActionsCtrl', function($scope, realm, RequiredActions, Notifications, Dialog, $location) {
|
||||||
|
$scope.realm = realm;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1074,7 +1074,7 @@ module.factory('IdentityProviderMapper', function($resource) {
|
||||||
});
|
});
|
||||||
|
|
||||||
module.factory('AuthenticationExecutions', function($resource) {
|
module.factory('AuthenticationExecutions', function($resource) {
|
||||||
return $resource(authUrl + '/admin/realms/:realm/authentication-flows/flow/:alias/executions', {
|
return $resource(authUrl + '/admin/realms/:realm/authentication/flow/:alias/executions', {
|
||||||
realm : '@realm',
|
realm : '@realm',
|
||||||
alias : '@alias'
|
alias : '@alias'
|
||||||
}, {
|
}, {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
<h1><strong>Authentication Flows</strong> {{realm.realm|capitalize}}</h1>
|
<h1>Authentication</h1>
|
||||||
|
|
||||||
|
<kc-tabs-authentication></kc-tabs-authentication>
|
||||||
|
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
|
<h1>Authentication</h1>
|
||||||
|
|
||||||
|
<kc-tabs-authentication></kc-tabs-authentication>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kc-menu></kc-menu>
|
|
@ -16,7 +16,7 @@
|
||||||
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'roles' || path[2] == 'default-roles' || (path[1] == 'role' && path[3] != 'clients')) && 'active'"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
|
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'roles' || path[2] == 'default-roles' || (path[1] == 'role' && path[3] != 'clients')) && 'active'"><a href="#/realms/{{realm.realm}}/roles">Roles</a></li>
|
||||||
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'identity-provider-settings' || path[2] == 'identity-provider-mappers') && 'active'"><a href="#/realms/{{realm.realm}}/identity-provider-settings">Identity Providers</a></li>
|
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'identity-provider-settings' || path[2] == 'identity-provider-mappers') && 'active'"><a href="#/realms/{{realm.realm}}/identity-provider-settings">Identity Providers</a></li>
|
||||||
<li data-ng-show="access.viewRealm" data-ng-class="(path[1] == 'user-federation' || path[2] == 'user-federation') && 'active'"><a href="#/realms/{{realm.realm}}/user-federation">User Federation</a></li>
|
<li data-ng-show="access.viewRealm" data-ng-class="(path[1] == 'user-federation' || path[2] == 'user-federation') && 'active'"><a href="#/realms/{{realm.realm}}/user-federation">User Federation</a></li>
|
||||||
<li data-ng-show="access.viewRealm" data-ng-class="(path[1] == 'authentication' || path[2] == 'authentication') && 'active'"><a href="#/realms/{{realm.realm}}/authentication">Authentication</a></li>
|
<li data-ng-show="access.viewRealm" data-ng-class="(path[1] == 'authentication' || path[2] == 'authentication') && 'active'"><a href="#/realms/{{realm.realm}}/authentication/flows">Authentication</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<li ng-class="{active: path[3] == 'flows'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/authentication/flows">Authenticators</a></li>
|
||||||
|
<li ng-class="{active: path[3] == 'required-actions'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/authentication/required-actions">Required Actions</a></li>
|
||||||
|
</ul>
|
|
@ -156,13 +156,6 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
|
|
||||||
void updateDefaultRoles(String[] defaultRoles);
|
void updateDefaultRoles(String[] defaultRoles);
|
||||||
|
|
||||||
Set<String> getDefaultRequiredActions();
|
|
||||||
|
|
||||||
void addDefaultRequiredAction(String action);
|
|
||||||
void removeDefaultRequiredAction(String action);
|
|
||||||
|
|
||||||
void setDefaultRequiredActions(Set<String> action);
|
|
||||||
|
|
||||||
// Key is clientId
|
// Key is clientId
|
||||||
Map<String, ClientModel> getClientNameMap();
|
Map<String, ClientModel> getClientNameMap();
|
||||||
|
|
||||||
|
@ -206,6 +199,12 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
void removeAuthenticator(AuthenticatorModel model);
|
void removeAuthenticator(AuthenticatorModel model);
|
||||||
AuthenticatorModel getAuthenticatorById(String id);
|
AuthenticatorModel getAuthenticatorById(String id);
|
||||||
|
|
||||||
|
List<RequiredActionProviderModel> getRequiredActionProviders();
|
||||||
|
RequiredActionProviderModel addRequiredActionProvider(RequiredActionProviderModel model);
|
||||||
|
void updateRequiredActionProvider(RequiredActionProviderModel model);
|
||||||
|
void removeRequiredActionProvider(RequiredActionProviderModel model);
|
||||||
|
RequiredActionProviderModel getRequiredActionProviderById(String id);
|
||||||
|
|
||||||
List<IdentityProviderModel> getIdentityProviders();
|
List<IdentityProviderModel> getIdentityProviders();
|
||||||
IdentityProviderModel getIdentityProviderByAlias(String alias);
|
IdentityProviderModel getIdentityProviderByAlias(String alias);
|
||||||
void addIdentityProvider(IdentityProviderModel identityProvider);
|
void addIdentityProvider(IdentityProviderModel identityProvider);
|
||||||
|
|
67
model/api/src/main/java/org/keycloak/models/RequiredActionProviderModel.java
Executable file
67
model/api/src/main/java/org/keycloak/models/RequiredActionProviderModel.java
Executable file
|
@ -0,0 +1,67 @@
|
||||||
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class RequiredActionProviderModel {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String alias;
|
||||||
|
private String providerId;
|
||||||
|
private boolean enabled;
|
||||||
|
private boolean defaultAction;
|
||||||
|
private Map<String, String> config = new HashMap<String, String>();
|
||||||
|
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlias(String alias) {
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 String getProviderId() {
|
||||||
|
return providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderId(String providerId) {
|
||||||
|
this.providerId = providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(Map<String, String> config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
}
|
|
@ -78,7 +78,7 @@ public class RealmEntity extends AbstractIdentifiableEntity {
|
||||||
private List<IdentityProviderMapperEntity> identityProviderMappers = new ArrayList<IdentityProviderMapperEntity>();
|
private List<IdentityProviderMapperEntity> identityProviderMappers = new ArrayList<IdentityProviderMapperEntity>();
|
||||||
private List<AuthenticationFlowEntity> authenticationFlows = new ArrayList<>();
|
private List<AuthenticationFlowEntity> authenticationFlows = new ArrayList<>();
|
||||||
private List<AuthenticatorEntity> authenticators = new ArrayList<>();
|
private List<AuthenticatorEntity> authenticators = new ArrayList<>();
|
||||||
private List<String> defaultRequiredActions = new ArrayList<>();
|
private List<RequiredActionProviderEntity> requiredActionProviders = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -504,12 +504,12 @@ public class RealmEntity extends AbstractIdentifiableEntity {
|
||||||
this.authenticators = authenticators;
|
this.authenticators = authenticators;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getDefaultRequiredActions() {
|
public List<RequiredActionProviderEntity> getRequiredActionProviders() {
|
||||||
return defaultRequiredActions;
|
return requiredActionProviders;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultRequiredActions(List<String> defaultRequiredActions) {
|
public void setRequiredActionProviders(List<RequiredActionProviderEntity> requiredActionProviders) {
|
||||||
this.defaultRequiredActions = defaultRequiredActions;
|
this.requiredActionProviders = requiredActionProviders;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package org.keycloak.models.entities;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class RequiredActionProviderEntity {
|
||||||
|
protected String id;
|
||||||
|
protected String alias;
|
||||||
|
protected String providerId;
|
||||||
|
protected boolean enabled;
|
||||||
|
protected boolean defaultAction;
|
||||||
|
private Map<String, String> config;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlias(String alias) {
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefaultAction() {
|
||||||
|
return defaultAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultAction(boolean defaultAction) {
|
||||||
|
this.defaultAction = defaultAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProviderId() {
|
||||||
|
return providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderId(String providerId) {
|
||||||
|
this.providerId = providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(Map<String, String> config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.ProtocolMapperModel;
|
import org.keycloak.models.ProtocolMapperModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserFederationProviderModel;
|
import org.keycloak.models.UserFederationProviderModel;
|
||||||
|
@ -285,8 +286,10 @@ public class FileUserProvider implements UserProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addDefaultRequiredActions) {
|
if (addDefaultRequiredActions) {
|
||||||
for (String r : realm.getDefaultRequiredActions()) {
|
for (RequiredActionProviderModel r : realm.getRequiredActionProviders()) {
|
||||||
userModel.addRequiredAction(r);
|
if (r.isEnabled() && r.isDefaultAction()) {
|
||||||
|
userModel.addRequiredAction(r.getAlias());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserFederationMapperEventImpl;
|
import org.keycloak.models.UserFederationMapperEventImpl;
|
||||||
|
@ -41,6 +42,7 @@ import org.keycloak.models.entities.AuthenticatorEntity;
|
||||||
import org.keycloak.models.entities.ClientEntity;
|
import org.keycloak.models.entities.ClientEntity;
|
||||||
import org.keycloak.models.entities.IdentityProviderMapperEntity;
|
import org.keycloak.models.entities.IdentityProviderMapperEntity;
|
||||||
import org.keycloak.models.entities.RealmEntity;
|
import org.keycloak.models.entities.RealmEntity;
|
||||||
|
import org.keycloak.models.entities.RequiredActionProviderEntity;
|
||||||
import org.keycloak.models.entities.RequiredCredentialEntity;
|
import org.keycloak.models.entities.RequiredCredentialEntity;
|
||||||
import org.keycloak.models.entities.RoleEntity;
|
import org.keycloak.models.entities.RoleEntity;
|
||||||
import org.keycloak.models.entities.UserFederationMapperEntity;
|
import org.keycloak.models.entities.UserFederationMapperEntity;
|
||||||
|
@ -1442,6 +1444,84 @@ public class RealmAdapter implements RealmModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequiredActionProviderModel addRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
|
RequiredActionProviderEntity auth = new RequiredActionProviderEntity();
|
||||||
|
auth.setId(KeycloakModelUtils.generateId());
|
||||||
|
auth.setAlias(model.getAlias());
|
||||||
|
auth.setProviderId(model.getProviderId());
|
||||||
|
auth.setConfig(model.getConfig());
|
||||||
|
auth.setEnabled(model.isEnabled());
|
||||||
|
auth.setDefaultAction(model.isDefaultAction());
|
||||||
|
realm.getRequiredActionProviders().add(auth);
|
||||||
|
model.setId(auth.getId());
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
|
RequiredActionProviderEntity entity = getRequiredActionProviderEntity(model.getId());
|
||||||
|
if (entity == null) return;
|
||||||
|
realm.getRequiredActionProviders().remove(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequiredActionProviderModel getRequiredActionProviderById(String id) {
|
||||||
|
RequiredActionProviderEntity entity = getRequiredActionProviderEntity(id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
return entityToModel(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequiredActionProviderModel entityToModel(RequiredActionProviderEntity entity) {
|
||||||
|
RequiredActionProviderModel model = new RequiredActionProviderModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setProviderId(entity.getProviderId());
|
||||||
|
model.setAlias(entity.getAlias());
|
||||||
|
model.setEnabled(entity.isEnabled());
|
||||||
|
model.setDefaultAction(entity.isDefaultAction());
|
||||||
|
Map<String, String> config = new HashMap<>();
|
||||||
|
if (entity.getConfig() != null) config.putAll(entity.getConfig());
|
||||||
|
model.setConfig(config);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
|
RequiredActionProviderEntity entity = getRequiredActionProviderEntity(model.getId());
|
||||||
|
if (entity == null) return;
|
||||||
|
entity.setAlias(model.getAlias());
|
||||||
|
entity.setProviderId(model.getProviderId());
|
||||||
|
entity.setEnabled(model.isEnabled());
|
||||||
|
entity.setDefaultAction(model.isDefaultAction());
|
||||||
|
if (entity.getConfig() == null) {
|
||||||
|
entity.setConfig(model.getConfig());
|
||||||
|
} else {
|
||||||
|
entity.getConfig().clear();
|
||||||
|
entity.getConfig().putAll(model.getConfig());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RequiredActionProviderModel> getRequiredActionProviders() {
|
||||||
|
List<RequiredActionProviderModel> actions = new LinkedList<>();
|
||||||
|
for (RequiredActionProviderEntity entity : realm.getRequiredActionProviders()) {
|
||||||
|
actions.add(entityToModel(entity));
|
||||||
|
}
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequiredActionProviderEntity getRequiredActionProviderEntity(String id) {
|
||||||
|
RequiredActionProviderEntity entity = null;
|
||||||
|
for (RequiredActionProviderEntity auth : realm.getRequiredActionProviders()) {
|
||||||
|
if (auth.getId().equals(id)) {
|
||||||
|
entity = auth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UserFederationMapperModel> getUserFederationMappers() {
|
public Set<UserFederationMapperModel> getUserFederationMappers() {
|
||||||
|
@ -1563,36 +1643,4 @@ public class RealmAdapter implements RealmModel {
|
||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public Set<String> getDefaultRequiredActions() {
|
|
||||||
Set<String> result = new HashSet<String>();
|
|
||||||
if (realm.getDefaultRequiredActions() != null) {
|
|
||||||
result.addAll(realm.getDefaultRequiredActions());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addDefaultRequiredAction(String action) {
|
|
||||||
Set<String> actions = getDefaultRequiredActions();
|
|
||||||
actions.add(action);
|
|
||||||
setDefaultRequiredActions(actions);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeDefaultRequiredAction(String action) {
|
|
||||||
Set<String> actions = getDefaultRequiredActions();
|
|
||||||
actions.remove(action);
|
|
||||||
setDefaultRequiredActions(actions);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDefaultRequiredActions(Set<String> action) {
|
|
||||||
List<String> result = new ArrayList<String>();
|
|
||||||
result.addAll(action);
|
|
||||||
realm.setDefaultRequiredActions(result);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.keycloak.models.IdentityProviderMapperModel;
|
||||||
import org.keycloak.models.IdentityProviderModel;
|
import org.keycloak.models.IdentityProviderModel;
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserFederationMapperModel;
|
import org.keycloak.models.UserFederationMapperModel;
|
||||||
|
@ -1128,28 +1129,36 @@ public class RealmAdapter implements RealmModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getDefaultRequiredActions() {
|
public List<RequiredActionProviderModel> getRequiredActionProviders() {
|
||||||
return cached.getDefaultRequiredActions();
|
if (updated != null) return updated.getRequiredActionProviders();
|
||||||
|
List<RequiredActionProviderModel> models = new ArrayList<>();
|
||||||
|
models.addAll(cached.getRequiredActionProviders().values());
|
||||||
|
return models;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addDefaultRequiredAction(String action) {
|
public RequiredActionProviderModel addRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
getDelegateForUpdate();
|
getDelegateForUpdate();
|
||||||
updated.addDefaultRequiredAction(action);
|
return updated.addRequiredActionProvider(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
|
getDelegateForUpdate();
|
||||||
|
updated.updateRequiredActionProvider(model);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeDefaultRequiredAction(String action) {
|
public void removeRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
getDelegateForUpdate();
|
getDelegateForUpdate();
|
||||||
updated.removeDefaultRequiredAction(action);
|
updated.removeRequiredActionProvider(model);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDefaultRequiredActions(Set<String> action) {
|
public RequiredActionProviderModel getRequiredActionProviderById(String id) {
|
||||||
getDelegateForUpdate();
|
if (updated != null) return updated.getRequiredActionProviderById(id);
|
||||||
updated.setDefaultRequiredActions(action);
|
return cached.getRequiredActionProviders().get(id);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.keycloak.models.IdentityProviderModel;
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RealmProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserFederationMapperModel;
|
import org.keycloak.models.UserFederationMapperModel;
|
||||||
|
@ -81,6 +82,7 @@ public class CachedRealm {
|
||||||
private Map<String, String> smtpConfig = new HashMap<String, String>();
|
private Map<String, String> smtpConfig = new HashMap<String, String>();
|
||||||
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 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<>();
|
||||||
|
|
||||||
|
@ -98,7 +100,6 @@ public class CachedRealm {
|
||||||
private Set<String> supportedLocales = new HashSet<String>();
|
private Set<String> supportedLocales = new HashSet<String>();
|
||||||
private String defaultLocale;
|
private String defaultLocale;
|
||||||
private MultivaluedHashMap<String, IdentityProviderMapperModel> identityProviderMappers = new MultivaluedHashMap<>();
|
private MultivaluedHashMap<String, IdentityProviderMapperModel> identityProviderMappers = new MultivaluedHashMap<>();
|
||||||
private Set<String> defaultRequiredActions = new HashSet<>();
|
|
||||||
|
|
||||||
public CachedRealm() {
|
public CachedRealm() {
|
||||||
}
|
}
|
||||||
|
@ -201,7 +202,9 @@ public class CachedRealm {
|
||||||
for (AuthenticatorModel authenticator : model.getAuthenticators()) {
|
for (AuthenticatorModel authenticator : model.getAuthenticators()) {
|
||||||
authenticators.put(authenticator.getId(), authenticator);
|
authenticators.put(authenticator.getId(), authenticator);
|
||||||
}
|
}
|
||||||
this.defaultRequiredActions.addAll(model.getDefaultRequiredActions());
|
for (RequiredActionProviderModel action : model.getRequiredActionProviders()) {
|
||||||
|
requiredActionProviders.put(action.getId(), action);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,7 +444,7 @@ public class CachedRealm {
|
||||||
return executionsById;
|
return executionsById;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getDefaultRequiredActions() {
|
public Map<String, RequiredActionProviderModel> getRequiredActionProviders() {
|
||||||
return defaultRequiredActions;
|
return requiredActionProviders;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.keycloak.models.FederatedIdentityModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ProtocolMapperModel;
|
import org.keycloak.models.ProtocolMapperModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserFederationProviderModel;
|
import org.keycloak.models.UserFederationProviderModel;
|
||||||
|
@ -68,9 +69,9 @@ public class JpaUserProvider implements UserProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (addDefaultRequiredActions) {
|
for (RequiredActionProviderModel r : realm.getRequiredActionProviders()) {
|
||||||
for (String r : realm.getDefaultRequiredActions()) {
|
if (r.isEnabled() && r.isDefaultAction()) {
|
||||||
userModel.addRequiredAction(r);
|
userModel.addRequiredAction(r.getAlias());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserFederationMapperEventImpl;
|
import org.keycloak.models.UserFederationMapperEventImpl;
|
||||||
|
@ -25,6 +26,7 @@ import org.keycloak.models.jpa.entities.IdentityProviderEntity;
|
||||||
import org.keycloak.models.jpa.entities.IdentityProviderMapperEntity;
|
import org.keycloak.models.jpa.entities.IdentityProviderMapperEntity;
|
||||||
import org.keycloak.models.jpa.entities.RealmAttributeEntity;
|
import org.keycloak.models.jpa.entities.RealmAttributeEntity;
|
||||||
import org.keycloak.models.jpa.entities.RealmEntity;
|
import org.keycloak.models.jpa.entities.RealmEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.RequiredActionProviderEntity;
|
||||||
import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
|
import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
|
||||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||||
import org.keycloak.models.jpa.entities.UserFederationMapperEntity;
|
import org.keycloak.models.jpa.entities.UserFederationMapperEntity;
|
||||||
|
@ -1726,29 +1728,75 @@ public class RealmAdapter implements RealmModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getDefaultRequiredActions() {
|
public RequiredActionProviderModel addRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
Set<String> result = new HashSet<String>();
|
RequiredActionProviderEntity auth = new RequiredActionProviderEntity();
|
||||||
result.addAll(realm.getDefaultRequiredActions());
|
auth.setId(KeycloakModelUtils.generateId());
|
||||||
return result;
|
auth.setAlias(model.getAlias());
|
||||||
}
|
auth.setRealm(realm);
|
||||||
|
auth.setProviderId(model.getProviderId());
|
||||||
|
auth.setConfig(model.getConfig());
|
||||||
|
auth.setEnabled(model.isEnabled());
|
||||||
@Override
|
auth.setDefaultAction(model.isDefaultAction());
|
||||||
public void setDefaultRequiredActions(Set<String> actions) {
|
realm.getRequiredActionProviders().add(auth);
|
||||||
realm.setDefaultRequiredActions(actions);
|
em.persist(auth);
|
||||||
|
em.flush();
|
||||||
|
model.setId(auth.getId());
|
||||||
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addDefaultRequiredAction(String action) {
|
public void removeRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
realm.getDefaultRequiredActions().add(action);
|
RequiredActionProviderEntity entity = em.find(RequiredActionProviderEntity.class, model.getId());
|
||||||
|
if (entity == null) return;
|
||||||
|
em.remove(entity);
|
||||||
|
em.flush();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeDefaultRequiredAction(String action) {
|
public RequiredActionProviderModel getRequiredActionProviderById(String id) {
|
||||||
realm.getDefaultRequiredActions().remove(action);
|
RequiredActionProviderEntity entity = em.find(RequiredActionProviderEntity.class, id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
return entityToModel(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RequiredActionProviderModel entityToModel(RequiredActionProviderEntity entity) {
|
||||||
|
RequiredActionProviderModel model = new RequiredActionProviderModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setProviderId(entity.getProviderId());
|
||||||
|
model.setAlias(entity.getAlias());
|
||||||
|
model.setEnabled(entity.isEnabled());
|
||||||
|
model.setDefaultAction(entity.isDefaultAction());
|
||||||
|
Map<String, String> config = new HashMap<>();
|
||||||
|
if (entity.getConfig() != null) config.putAll(entity.getConfig());
|
||||||
|
model.setConfig(config);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
|
RequiredActionProviderEntity entity = em.find(RequiredActionProviderEntity.class, model.getId());
|
||||||
|
if (entity == null) return;
|
||||||
|
entity.setAlias(model.getAlias());
|
||||||
|
entity.setProviderId(model.getProviderId());
|
||||||
|
entity.setEnabled(model.isEnabled());
|
||||||
|
entity.setDefaultAction(model.isDefaultAction());
|
||||||
|
if (entity.getConfig() == null) {
|
||||||
|
entity.setConfig(model.getConfig());
|
||||||
|
} else {
|
||||||
|
entity.getConfig().clear();
|
||||||
|
entity.getConfig().putAll(model.getConfig());
|
||||||
|
}
|
||||||
|
em.flush();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RequiredActionProviderModel> getRequiredActionProviders() {
|
||||||
|
List<RequiredActionProviderModel> actions = new LinkedList<>();
|
||||||
|
for (RequiredActionProviderEntity entity : realm.getRequiredActionProviders()) {
|
||||||
|
actions.add(entityToModel(entity));
|
||||||
|
}
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -113,12 +113,6 @@ public class RealmEntity {
|
||||||
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
@OneToMany(fetch = FetchType.LAZY, cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
||||||
Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
|
Collection<RoleEntity> roles = new ArrayList<RoleEntity>();
|
||||||
|
|
||||||
@ElementCollection
|
|
||||||
@Column(name="VALUE")
|
|
||||||
@CollectionTable(name = "DEFAULT_REQUIRED_ACTIONS", joinColumns={ @JoinColumn(name="REALM_ID") })
|
|
||||||
protected Set<String> defaultRequiredActions = new HashSet<String>();
|
|
||||||
|
|
||||||
|
|
||||||
@ElementCollection
|
@ElementCollection
|
||||||
@MapKeyColumn(name="NAME")
|
@MapKeyColumn(name="NAME")
|
||||||
@Column(name="VALUE")
|
@Column(name="VALUE")
|
||||||
|
@ -163,6 +157,9 @@ public class RealmEntity {
|
||||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
||||||
Collection<AuthenticatorEntity> authenticators = new ArrayList<>();
|
Collection<AuthenticatorEntity> authenticators = new ArrayList<>();
|
||||||
|
|
||||||
|
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
||||||
|
Collection<RequiredActionProviderEntity> requiredActionProviders = new ArrayList<>();
|
||||||
|
|
||||||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "realm")
|
||||||
Collection<AuthenticationFlowEntity> authenticationFlows = new ArrayList<>();
|
Collection<AuthenticationFlowEntity> authenticationFlows = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -567,6 +564,14 @@ public class RealmEntity {
|
||||||
this.authenticators = authenticators;
|
this.authenticators = authenticators;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<RequiredActionProviderEntity> getRequiredActionProviders() {
|
||||||
|
return requiredActionProviders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequiredActionProviders(Collection<RequiredActionProviderEntity> requiredActionProviders) {
|
||||||
|
this.requiredActionProviders = requiredActionProviders;
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<AuthenticationFlowEntity> getAuthenticationFlows() {
|
public Collection<AuthenticationFlowEntity> getAuthenticationFlows() {
|
||||||
return authenticationFlows;
|
return authenticationFlows;
|
||||||
}
|
}
|
||||||
|
@ -575,12 +580,5 @@ public class RealmEntity {
|
||||||
this.authenticationFlows = authenticationFlows;
|
this.authenticationFlows = authenticationFlows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getDefaultRequiredActions() {
|
|
||||||
return defaultRequiredActions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultRequiredActions(Set<String> defaultRequiredActions) {
|
|
||||||
this.defaultRequiredActions = defaultRequiredActions;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
package org.keycloak.models.jpa.entities;
|
||||||
|
|
||||||
|
import javax.persistence.CollectionTable;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.MapKeyColumn;
|
||||||
|
import javax.persistence.NamedQueries;
|
||||||
|
import javax.persistence.NamedQuery;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
@Table(name="REQUIRED_ACTION_PROVIDER")
|
||||||
|
@Entity
|
||||||
|
@NamedQueries({
|
||||||
|
@NamedQuery(name="deleteRequiredActionProviderByRealm", query="delete from RequiredActionProviderEntity action where action.realm = :realm"),})
|
||||||
|
public class RequiredActionProviderEntity {
|
||||||
|
@Id
|
||||||
|
@Column(name="ID", length = 36)
|
||||||
|
protected String id;
|
||||||
|
|
||||||
|
@Column(name="ALIAS")
|
||||||
|
protected String alias;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "REALM_ID")
|
||||||
|
protected RealmEntity realm;
|
||||||
|
|
||||||
|
@Column(name="PROVIDER_ID")
|
||||||
|
protected String providerId;
|
||||||
|
|
||||||
|
@Column(name="ENABLED")
|
||||||
|
protected boolean enabled;
|
||||||
|
|
||||||
|
@Column(name="DEFAULT_ACTION")
|
||||||
|
protected boolean defaultAction;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@MapKeyColumn(name="NAME")
|
||||||
|
@Column(name="VALUE")
|
||||||
|
@CollectionTable(name="REQUIRED_ACTION_CONFIG", joinColumns={ @JoinColumn(name="REQUIRED_ACTION_ID") })
|
||||||
|
private Map<String, String> config;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlias(String alias) {
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 String getProviderId() {
|
||||||
|
return providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProviderId(String providerId) {
|
||||||
|
this.providerId = providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RealmEntity getRealm() {
|
||||||
|
return realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRealm(RealmEntity realm) {
|
||||||
|
this.realm = realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(Map<String, String> config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import org.keycloak.models.FederatedIdentityModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ProtocolMapperModel;
|
import org.keycloak.models.ProtocolMapperModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserFederationProviderModel;
|
import org.keycloak.models.UserFederationProviderModel;
|
||||||
|
@ -258,8 +259,10 @@ public class MongoUserProvider implements UserProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addDefaultRequiredActions) {
|
if (addDefaultRequiredActions) {
|
||||||
for (String r : realm.getDefaultRequiredActions()) {
|
for (RequiredActionProviderModel r : realm.getRequiredActionProviders()) {
|
||||||
userModel.addRequiredAction(r);
|
if (r.isEnabled() && r.isDefaultAction()) {
|
||||||
|
userModel.addRequiredAction(r.getAlias());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.models.PasswordPolicy;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RealmProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserFederationMapperEventImpl;
|
import org.keycloak.models.UserFederationMapperEventImpl;
|
||||||
|
@ -27,6 +28,7 @@ import org.keycloak.models.entities.AuthenticationFlowEntity;
|
||||||
import org.keycloak.models.entities.AuthenticatorEntity;
|
import org.keycloak.models.entities.AuthenticatorEntity;
|
||||||
import org.keycloak.models.entities.IdentityProviderEntity;
|
import org.keycloak.models.entities.IdentityProviderEntity;
|
||||||
import org.keycloak.models.entities.IdentityProviderMapperEntity;
|
import org.keycloak.models.entities.IdentityProviderMapperEntity;
|
||||||
|
import org.keycloak.models.entities.RequiredActionProviderEntity;
|
||||||
import org.keycloak.models.entities.RequiredCredentialEntity;
|
import org.keycloak.models.entities.RequiredCredentialEntity;
|
||||||
import org.keycloak.models.entities.UserFederationMapperEntity;
|
import org.keycloak.models.entities.UserFederationMapperEntity;
|
||||||
import org.keycloak.models.entities.UserFederationProviderEntity;
|
import org.keycloak.models.entities.UserFederationProviderEntity;
|
||||||
|
@ -1525,6 +1527,88 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
updateMongoEntity();
|
updateMongoEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequiredActionProviderModel addRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
|
RequiredActionProviderEntity auth = new RequiredActionProviderEntity();
|
||||||
|
auth.setId(KeycloakModelUtils.generateId());
|
||||||
|
auth.setAlias(model.getAlias());
|
||||||
|
auth.setProviderId(model.getProviderId());
|
||||||
|
auth.setConfig(model.getConfig());
|
||||||
|
auth.setEnabled(model.isEnabled());
|
||||||
|
auth.setDefaultAction(model.isDefaultAction());
|
||||||
|
realm.getRequiredActionProviders().add(auth);
|
||||||
|
model.setId(auth.getId());
|
||||||
|
updateMongoEntity();
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
|
RequiredActionProviderEntity entity = getRequiredActionProviderEntity(model.getId());
|
||||||
|
if (entity == null) return;
|
||||||
|
getMongoEntity().getRequiredActionProviders().remove(entity);
|
||||||
|
updateMongoEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequiredActionProviderModel getRequiredActionProviderById(String id) {
|
||||||
|
RequiredActionProviderEntity entity = getRequiredActionProviderEntity(id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
return entityToModel(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequiredActionProviderModel entityToModel(RequiredActionProviderEntity entity) {
|
||||||
|
RequiredActionProviderModel model = new RequiredActionProviderModel();
|
||||||
|
model.setId(entity.getId());
|
||||||
|
model.setProviderId(entity.getProviderId());
|
||||||
|
model.setAlias(entity.getAlias());
|
||||||
|
model.setEnabled(entity.isEnabled());
|
||||||
|
model.setDefaultAction(entity.isDefaultAction());
|
||||||
|
Map<String, String> config = new HashMap<>();
|
||||||
|
if (entity.getConfig() != null) config.putAll(entity.getConfig());
|
||||||
|
model.setConfig(config);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
|
RequiredActionProviderEntity entity = getRequiredActionProviderEntity(model.getId());
|
||||||
|
if (entity == null) return;
|
||||||
|
entity.setAlias(model.getAlias());
|
||||||
|
entity.setProviderId(model.getProviderId());
|
||||||
|
entity.setEnabled(model.isEnabled());
|
||||||
|
entity.setDefaultAction(model.isDefaultAction());
|
||||||
|
if (entity.getConfig() == null) {
|
||||||
|
entity.setConfig(model.getConfig());
|
||||||
|
} else {
|
||||||
|
entity.getConfig().clear();
|
||||||
|
entity.getConfig().putAll(model.getConfig());
|
||||||
|
}
|
||||||
|
updateMongoEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<RequiredActionProviderModel> getRequiredActionProviders() {
|
||||||
|
List<RequiredActionProviderModel> actions = new LinkedList<>();
|
||||||
|
for (RequiredActionProviderEntity entity : realm.getRequiredActionProviders()) {
|
||||||
|
actions.add(entityToModel(entity));
|
||||||
|
}
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequiredActionProviderEntity getRequiredActionProviderEntity(String id) {
|
||||||
|
RequiredActionProviderEntity entity = null;
|
||||||
|
for (RequiredActionProviderEntity auth : getMongoEntity().getRequiredActionProviders()) {
|
||||||
|
if (auth.getId().equals(id)) {
|
||||||
|
entity = auth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<UserFederationMapperModel> getUserFederationMappers() {
|
public Set<UserFederationMapperModel> getUserFederationMappers() {
|
||||||
|
@ -1648,32 +1732,4 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
mapper.setConfig(config);
|
mapper.setConfig(config);
|
||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getDefaultRequiredActions() {
|
|
||||||
Set<String> result = new HashSet<String>();
|
|
||||||
result.addAll(realm.getDefaultRequiredActions());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDefaultRequiredActions(Set<String> actions) {
|
|
||||||
List<String> result = new ArrayList<String>();
|
|
||||||
result.addAll(actions);
|
|
||||||
getMongoEntity().setDefaultRequiredActions(result);
|
|
||||||
updateMongoEntity();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addDefaultRequiredAction(String action) {
|
|
||||||
getMongoStore().pushItemToList(getMongoEntity(), "defaultRequiredActions", action, true, invocationContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeDefaultRequiredAction(String action) {
|
|
||||||
getMongoStore().pullItemFromList(getMongoEntity(), "defaultRequiredActions", action, invocationContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public interface AuthenticatorFactory extends ProviderFactory<Authenticator>, Co
|
||||||
String getDisplayType();
|
String getDisplayType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General authenticator type, i.e. totp, password, cert
|
* General authenticator type, i.e. totp, password, cert.
|
||||||
*
|
*
|
||||||
* @return null if not a referencable type
|
* @return null if not a referencable type
|
||||||
*/
|
*/
|
||||||
|
@ -26,8 +26,7 @@ public interface AuthenticatorFactory extends ProviderFactory<Authenticator>, Co
|
||||||
boolean isConfigurable();
|
boolean isConfigurable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What requirement settings are allowed. For example, KERBEROS can only be required because of the way its challenges
|
* What requirement settings are allowed.
|
||||||
* work.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,17 +26,17 @@ import java.util.List;
|
||||||
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
|
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pedro Igor
|
* @author Bill Burke
|
||||||
*/
|
*/
|
||||||
public class AuthenticationFlowResource {
|
public class AuthenticationManagementResource {
|
||||||
|
|
||||||
private final RealmModel realm;
|
private final RealmModel realm;
|
||||||
private final KeycloakSession session;
|
private final KeycloakSession session;
|
||||||
private RealmAuth auth;
|
private RealmAuth auth;
|
||||||
private AdminEventBuilder adminEvent;
|
private AdminEventBuilder adminEvent;
|
||||||
private static Logger logger = Logger.getLogger(AuthenticationFlowResource.class);
|
private static Logger logger = Logger.getLogger(AuthenticationManagementResource.class);
|
||||||
|
|
||||||
public AuthenticationFlowResource(RealmModel realm, KeycloakSession session, RealmAuth auth, AdminEventBuilder adminEvent) {
|
public AuthenticationManagementResource(RealmModel realm, KeycloakSession session, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
|
@ -176,5 +176,4 @@ public class AuthenticationFlowResource {
|
||||||
realm.updateAuthenticatorExecution(model);
|
realm.updateAuthenticatorExecution(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -56,7 +56,6 @@ import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -239,9 +238,9 @@ public class RealmAdminResource {
|
||||||
return fed;
|
return fed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Path("authentication-flows")
|
@Path("authentication")
|
||||||
public AuthenticationFlowResource flows() {
|
public AuthenticationManagementResource flows() {
|
||||||
AuthenticationFlowResource resource = new AuthenticationFlowResource(realm, session, auth, adminEvent);
|
AuthenticationManagementResource resource = new AuthenticationManagementResource(realm, session, auth, adminEvent);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
||||||
//resourceContext.initResource(resource);
|
//resourceContext.initResource(resource);
|
||||||
return resource;
|
return resource;
|
||||||
|
|
Loading…
Reference in a new issue