EYCLOAK-12741 Add name and description edit functionality to Authentication and Execution Flows
This commit is contained in:
parent
2ddfc94495
commit
8d6f8d0465
11 changed files with 323 additions and 17 deletions
|
@ -30,6 +30,7 @@ public class AuthenticationExecutionInfoRepresentation implements Serializable {
|
|||
protected String requirement;
|
||||
protected String displayName;
|
||||
protected String alias;
|
||||
protected String description;
|
||||
protected List<String> requirementChoices;
|
||||
protected Boolean configurable;
|
||||
protected Boolean authenticationFlow;
|
||||
|
@ -63,6 +64,14 @@ public class AuthenticationExecutionInfoRepresentation implements Serializable {
|
|||
this.alias = alias;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getRequirement() {
|
||||
return requirement;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,11 @@ public interface AuthenticationManagementResource {
|
|||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
Response copy(@PathParam("flowAlias") String flowAlias, Map<String, String> data);
|
||||
|
||||
@Path("/flows/{id}")
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
void updateFlow(@PathParam("id") String id, AuthenticationFlowRepresentation flow);
|
||||
|
||||
@Path("/flows/{flowAlias}/executions/flow")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
|
|
|
@ -255,6 +255,7 @@ public class AuthenticationManagementResource {
|
|||
@PUT
|
||||
@NoCache
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response updateFlow(@PathParam("id") String id, AuthenticationFlowRepresentation flow) {
|
||||
auth.realm().requireManageRealm();
|
||||
|
||||
|
@ -264,10 +265,32 @@ public class AuthenticationManagementResource {
|
|||
return ErrorResponse.exists("Failed to update flow with empty alias name");
|
||||
}
|
||||
|
||||
//check if updating a correct flow
|
||||
AuthenticationFlowModel checkFlow = realm.getAuthenticationFlowById(id);
|
||||
if (checkFlow == null) {
|
||||
session.getTransactionManager().setRollbackOnly();
|
||||
throw new NotFoundException("Illegal execution");
|
||||
}
|
||||
|
||||
//if a different flow with the same name does already exist, throw an exception
|
||||
if (realm.getFlowByAlias(flow.getAlias()) != null && !checkFlow.getAlias().equals(flow.getAlias())) {
|
||||
return ErrorResponse.exists("Flow alias name already exists");
|
||||
}
|
||||
|
||||
//if the name changed
|
||||
if (!checkFlow.getAlias().equals(flow.getAlias())) {
|
||||
checkFlow.setAlias(flow.getAlias());
|
||||
}
|
||||
|
||||
//check if the description changed
|
||||
if (!checkFlow.getDescription().equals(flow.getDescription())) {
|
||||
checkFlow.setDescription(flow.getDescription());
|
||||
}
|
||||
|
||||
//update the flow
|
||||
flow.setId(existingFlow.getId());
|
||||
realm.updateAuthenticationFlow(RepresentationToModel.toModel(flow));
|
||||
adminEvent.operation(OperationType.UPDATE).resourcePath(session.getContext().getUri()).representation(flow).success();
|
||||
|
||||
return Response.accepted(flow).build();
|
||||
}
|
||||
|
||||
|
@ -533,6 +556,7 @@ public class AuthenticationManagementResource {
|
|||
rep.getRequirementChoices().add(AuthenticationExecutionModel.Requirement.DISABLED.name());
|
||||
}
|
||||
rep.setDisplayName(flowRef.getAlias());
|
||||
rep.setDescription(flowRef.getDescription());
|
||||
rep.setConfigurable(false);
|
||||
rep.setId(execution.getId());
|
||||
rep.setAuthenticationFlow(execution.isAuthenticatorFlow());
|
||||
|
@ -571,16 +595,16 @@ public class AuthenticationManagementResource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Update authentication executions of a flow
|
||||
*
|
||||
* Update authentication executions of a Flow
|
||||
* @param flowAlias Flow alias
|
||||
* @param rep
|
||||
* @param rep AuthenticationExecutionInfoRepresentation
|
||||
*/
|
||||
@Path("/flows/{flowAlias}/executions")
|
||||
@PUT
|
||||
@NoCache
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public void updateExecutions(@PathParam("flowAlias") String flowAlias, AuthenticationExecutionInfoRepresentation rep) {
|
||||
public Response updateExecutions(@PathParam("flowAlias") String flowAlias, AuthenticationExecutionInfoRepresentation rep) {
|
||||
auth.realm().requireManageRealm();
|
||||
|
||||
AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias);
|
||||
|
@ -599,7 +623,38 @@ public class AuthenticationManagementResource {
|
|||
model.setRequirement(AuthenticationExecutionModel.Requirement.valueOf(rep.getRequirement()));
|
||||
realm.updateAuthenticatorExecution(model);
|
||||
adminEvent.operation(OperationType.UPDATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(session.getContext().getUri()).representation(rep).success();
|
||||
return Response.accepted(flow).build();
|
||||
}
|
||||
|
||||
//executions can't have name and description updated
|
||||
if (rep.getAuthenticationFlow() == null) { return Response.accepted(flow).build();}
|
||||
|
||||
//check if updating a correct flow
|
||||
AuthenticationFlowModel checkFlow = realm.getAuthenticationFlowById(rep.getFlowId());
|
||||
if (checkFlow == null) {
|
||||
session.getTransactionManager().setRollbackOnly();
|
||||
throw new NotFoundException("Illegal execution");
|
||||
}
|
||||
|
||||
//if a different flow with the same name does already exist, throw an exception
|
||||
if (realm.getFlowByAlias(rep.getDisplayName()) != null && !checkFlow.getAlias().equals(rep.getDisplayName())) {
|
||||
return ErrorResponse.exists("Flow alias name already exists");
|
||||
}
|
||||
|
||||
//if the name changed
|
||||
if (!checkFlow.getAlias().equals(rep.getDisplayName())) {
|
||||
checkFlow.setAlias(rep.getDisplayName());
|
||||
}
|
||||
|
||||
//check if the description changed
|
||||
if (!checkFlow.getDescription().equals(rep.getDescription())) {
|
||||
checkFlow.setDescription(rep.getDescription());
|
||||
}
|
||||
|
||||
//update the flow
|
||||
realm.updateAuthenticationFlow(checkFlow);
|
||||
adminEvent.operation(OperationType.UPDATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(session.getContext().getUri()).representation(rep).success();
|
||||
return Response.accepted(flow).build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
|
|||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
||||
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||
import org.keycloak.testsuite.util.AssertAdminEvents;
|
||||
|
@ -44,8 +46,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||
|
@ -286,9 +286,9 @@ public class ExecutionTest extends AbstractAuthenticationTest {
|
|||
}
|
||||
|
||||
// Update execution with not-existent ID - SHOULD FAIL
|
||||
AuthenticationExecutionInfoRepresentation executionRep2 = new AuthenticationExecutionInfoRepresentation();
|
||||
executionRep2.setId("not-existent");
|
||||
try {
|
||||
AuthenticationExecutionInfoRepresentation executionRep2 = new AuthenticationExecutionInfoRepresentation();
|
||||
executionRep2.setId("not-existent");
|
||||
authMgmtResource.updateExecutions("new-client-flow", executionRep2);
|
||||
Assert.fail("Not expected to update not-existent execution");
|
||||
} catch (NotFoundException nfe) {
|
||||
|
|
|
@ -19,25 +19,25 @@ package org.keycloak.testsuite.admin.authentication;
|
|||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
||||
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
|
||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||
import org.keycloak.testsuite.util.AssertAdminEvents;
|
||||
|
||||
import javax.ws.rs.BadRequestException;
|
||||
import javax.ws.rs.ClientErrorException;
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.keycloak.testsuite.util.Matchers.*;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.keycloak.testsuite.util.Matchers.body;
|
||||
import static org.keycloak.testsuite.util.Matchers.statusCodeIs;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||
|
@ -253,6 +253,7 @@ public class FlowTest extends AbstractAuthenticationTest {
|
|||
copyOfBrowser = authMgmtResource.getFlow(copyOfBrowser.getId());
|
||||
Assert.assertNotNull(copyOfBrowser);
|
||||
compareFlows(browser, copyOfBrowser);
|
||||
authMgmtResource.deleteFlow(copyOfBrowser.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -275,4 +276,138 @@ public class FlowTest extends AbstractAuthenticationTest {
|
|||
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("parent"), params, ResourceType.AUTH_EXECUTION_FLOW);
|
||||
}
|
||||
|
||||
@Test
|
||||
//KEYCLOAK-12741
|
||||
//test editing of authentication flows
|
||||
public void editFlowTest() {
|
||||
List<AuthenticationFlowRepresentation> flows;
|
||||
|
||||
//copy an existing one first
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
params.put("newName", "Copy of browser");
|
||||
Response response = authMgmtResource.copy("browser", params);
|
||||
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authCopyFlowPath("browser"), params, ResourceType.AUTH_FLOW);
|
||||
try {
|
||||
Assert.assertEquals("Copy flow", 201, response.getStatus());
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
//load the newly copied flow
|
||||
flows = authMgmtResource.getFlows();
|
||||
AuthenticationFlowRepresentation testFlow = findFlowByAlias("Copy of browser", flows);
|
||||
//Set a new unique name. Should succeed
|
||||
testFlow.setAlias("Copy of browser2");
|
||||
authMgmtResource.updateFlow(testFlow.getId(), testFlow);
|
||||
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authEditFlowPath(testFlow.getId()), ResourceType.AUTH_FLOW);
|
||||
flows = authMgmtResource.getFlows();
|
||||
Assert.assertEquals("Copy of browser2", findFlowByAlias("Copy of browser2", flows).getAlias());
|
||||
|
||||
//Create new flow and edit the old one to have the new ones name
|
||||
AuthenticationFlowRepresentation newFlow = newFlow("New Flow", "Test description", "basic-flow", true, false);
|
||||
createFlow(newFlow);
|
||||
// check that new flow is returned in a children list
|
||||
flows = authMgmtResource.getFlows();
|
||||
AuthenticationFlowRepresentation found = findFlowByAlias("New Flow", flows);
|
||||
|
||||
Assert.assertNotNull("created flow visible in parent", found);
|
||||
compareFlows(newFlow, found);
|
||||
|
||||
//try to update old flow with alias that already exists
|
||||
testFlow.setAlias("New Flow");
|
||||
try {
|
||||
authMgmtResource.updateFlow(found.getId(), testFlow);
|
||||
} catch (ClientErrorException exception){
|
||||
//expoected
|
||||
}
|
||||
flows = authMgmtResource.getFlows();
|
||||
|
||||
//name should be the same for the old Flow
|
||||
Assert.assertEquals("Copy of browser2", findFlowByAlias("Copy of browser2", flows).getAlias());
|
||||
|
||||
//Only update the description
|
||||
found.setDescription("New description");
|
||||
authMgmtResource.updateFlow(found.getId(), found);
|
||||
flows = authMgmtResource.getFlows();
|
||||
|
||||
Assert.assertEquals("New description", findFlowByAlias("New Flow", flows).getDescription());
|
||||
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authEditFlowPath(found.getId()), ResourceType.AUTH_FLOW);
|
||||
|
||||
//Update name and description
|
||||
found.setAlias("New Flow2");
|
||||
found.setDescription("New description2");
|
||||
authMgmtResource.updateFlow(found.getId(), found);
|
||||
flows = authMgmtResource.getFlows();
|
||||
|
||||
Assert.assertEquals("New Flow2", findFlowByAlias("New Flow2", flows).getAlias());
|
||||
Assert.assertEquals("New description2", findFlowByAlias("New Flow2", flows).getDescription());
|
||||
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authEditFlowPath(found.getId()), ResourceType.AUTH_FLOW);
|
||||
Assert.assertNull(findFlowByAlias("New Flow", flows));
|
||||
|
||||
authMgmtResource.deleteFlow(testFlow.getId());
|
||||
authMgmtResource.deleteFlow(found.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void editExecutionFlowTest() {
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
List<AuthenticationExecutionInfoRepresentation> executionReps;
|
||||
//create new parent flow
|
||||
AuthenticationFlowRepresentation newFlow = newFlow("Parent-Flow", "This is a parent flow", "basic-flow", true, false);
|
||||
createFlow(newFlow);
|
||||
|
||||
//create a child sub flow
|
||||
params.put("alias", "Child-Flow");
|
||||
params.put("description", "This is a child flow");
|
||||
params.put("provider", "registration-page-form");
|
||||
params.put("type", "basic-flow");
|
||||
|
||||
authMgmtResource.addExecutionFlow("Parent-Flow", params);
|
||||
assertAdminEvents.assertEvent(REALM_NAME, OperationType.CREATE, AdminEventPaths.authAddExecutionFlowPath("Parent-Flow"), params, ResourceType.AUTH_EXECUTION_FLOW);
|
||||
|
||||
executionReps = authMgmtResource.getExecutions("Parent-Flow");
|
||||
|
||||
//create another with the same name of the previous one. Should fail to create
|
||||
params = new HashMap<>();
|
||||
params.put("alias", "Child-Flow");
|
||||
params.put("description", "This is another child flow");
|
||||
params.put("provider", "registration-page-form");
|
||||
params.put("type", "basic-flow");
|
||||
|
||||
try {
|
||||
authMgmtResource.addExecutionFlow("Parent-Flow", params);
|
||||
Assert.fail("addExecutionFlow the alias already exist");
|
||||
} catch (Exception expected) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
AuthenticationExecutionInfoRepresentation found = executionReps.get(0);
|
||||
found.setDisplayName("Parent-Flow");
|
||||
|
||||
try {
|
||||
authMgmtResource.updateExecutions("Parent-Flow", found);
|
||||
} catch (ClientErrorException exception){
|
||||
//expected
|
||||
}
|
||||
|
||||
//edit both name and description
|
||||
found.setDisplayName("Child-Flow2");
|
||||
found.setDescription("This is another child flow2");
|
||||
|
||||
authMgmtResource.updateExecutions("Parent-Flow", found);
|
||||
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("Parent-Flow"), ResourceType.AUTH_EXECUTION);
|
||||
executionReps = authMgmtResource.getExecutions("Parent-Flow");
|
||||
Assert.assertEquals("Child-Flow2", executionReps.get(0).getDisplayName());
|
||||
Assert.assertEquals("This is another child flow2", executionReps.get(0).getDescription());
|
||||
|
||||
//edit only description
|
||||
found.setDescription("This is another child flow3");
|
||||
authMgmtResource.updateExecutions("Parent-Flow", found);
|
||||
|
||||
assertAdminEvents.assertEvent(REALM_NAME, OperationType.UPDATE, AdminEventPaths.authUpdateExecutionPath("Parent-Flow"), ResourceType.AUTH_EXECUTION);
|
||||
executionReps = authMgmtResource.getExecutions("Parent-Flow");
|
||||
Assert.assertEquals("Child-Flow2", executionReps.get(0).getDisplayName());
|
||||
Assert.assertEquals("This is another child flow3", executionReps.get(0).getDescription());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -390,6 +390,11 @@ public class AdminEventPaths {
|
|||
return uri.toString();
|
||||
}
|
||||
|
||||
public static String authEditFlowPath(String flowId) {
|
||||
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "updateFlow")
|
||||
.build(flowId);
|
||||
return uri.toString();
|
||||
}
|
||||
public static String authAddExecutionFlowPath(String flowAlias) {
|
||||
URI uri = UriBuilder.fromUri(authMgmtBasePath()).path(AuthenticationManagementResource.class, "addExecutionFlow")
|
||||
.build(flowAlias);
|
||||
|
|
|
@ -1150,6 +1150,7 @@ cut=Cut
|
|||
paste=Paste
|
||||
create-group=Create group
|
||||
create-authenticator-execution=Create Authenticator Execution
|
||||
edit-flow=Edit Flow
|
||||
create-form-action-execution=Create Form Action Execution
|
||||
create-top-level-form=Create Top Level Form
|
||||
flow.alias.tooltip=Specifies display name for the flow.
|
||||
|
@ -1284,6 +1285,7 @@ started=Started
|
|||
logout-all-sessions=Log out all sessions
|
||||
logout=Logout
|
||||
new-name=New Name
|
||||
new-description=New Description
|
||||
ok=Ok
|
||||
attributes=Attributes
|
||||
role-mappings=Role Mappings
|
||||
|
|
|
@ -2229,9 +2229,9 @@ module.controller('CreateExecutionCtrl', function($scope, realm, parentFlow, for
|
|||
|
||||
|
||||
module.controller('AuthenticationFlowsCtrl', function($scope, $route, realm, flows, selectedFlow, LastFlowSelected, Dialog,
|
||||
AuthenticationFlows, AuthenticationFlowsCopy, AuthenticationFlowExecutions,
|
||||
AuthenticationFlows, AuthenticationFlowsCopy, AuthenticationFlowsUpdate, AuthenticationFlowExecutions,
|
||||
AuthenticationExecution, AuthenticationExecutionRaisePriority, AuthenticationExecutionLowerPriority,
|
||||
$modal, Notifications, CopyDialog, $location) {
|
||||
$modal, Notifications, CopyDialog, UpdateDialog, $location) {
|
||||
$scope.realm = realm;
|
||||
$scope.flows = flows;
|
||||
|
||||
|
@ -2342,6 +2342,18 @@ module.controller('AuthenticationFlowsCtrl', function($scope, $route, realm, flo
|
|||
|
||||
};
|
||||
|
||||
$scope.editFlow = function(flow) {
|
||||
var copy = angular.copy(flow);
|
||||
UpdateDialog.open('Update Authentication Flow', copy.alias, copy.description, function(name, desc) {
|
||||
copy.alias = name;
|
||||
copy.description = desc;
|
||||
AuthenticationFlowsUpdate.update({realm: realm.realm, flow: flow.id}, copy, function() {
|
||||
$location.url("/realms/" + realm.realm + '/authentication/flows/' + name);
|
||||
Notifications.success("Flow updated");
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
$scope.addFlow = function() {
|
||||
$location.url("/realms/" + realm.realm + '/authentication/flows/' + $scope.flow.id + '/create/flow/execution/' + $scope.flow.id);
|
||||
|
||||
|
@ -2379,6 +2391,22 @@ module.controller('AuthenticationFlowsCtrl', function($scope, $route, realm, flo
|
|||
|
||||
};
|
||||
|
||||
$scope.editExecutionFlow = function(execution) {
|
||||
var copy = angular.copy(execution);
|
||||
delete copy.empties;
|
||||
delete copy.levels;
|
||||
delete copy.preLevels;
|
||||
delete copy.postLevels;
|
||||
UpdateDialog.open('Update Execution Flow', copy.displayName, copy.description, function(name, desc) {
|
||||
copy.displayName = name;
|
||||
copy.description = desc;
|
||||
AuthenticationFlowExecutions.update({realm: realm.realm, alias: $scope.flow.alias}, copy, function() {
|
||||
Notifications.success("Execution Flow updated");
|
||||
setupForm();
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
$scope.removeExecution = function(execution) {
|
||||
console.log('removeExecution: ' + execution.id);
|
||||
var exeOrFlow = execution.authenticationFlow ? 'flow' : 'execution';
|
||||
|
|
|
@ -137,6 +137,35 @@ module.service('CopyDialog', function($modal) {
|
|||
return dialog;
|
||||
});
|
||||
|
||||
module.service('UpdateDialog', function($modal) {
|
||||
var dialog = {};
|
||||
dialog.open = function (title, name, desc, success) {
|
||||
var controller = function($scope, $modalInstance, title) {
|
||||
$scope.title = title;
|
||||
$scope.name = { value: name };
|
||||
$scope.description = { value: desc };
|
||||
$scope.ok = function () {
|
||||
console.log('ok with name: ' + $scope.name + 'and description: ' + $scope.description);
|
||||
$modalInstance.close();
|
||||
success($scope.name.value, $scope.description.value);
|
||||
};
|
||||
$scope.cancel = function () {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
}
|
||||
$modal.open({
|
||||
templateUrl: resourceUrl + '/templates/kc-edit.html',
|
||||
controller: controller,
|
||||
resolve: {
|
||||
title: function() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
return dialog;
|
||||
});
|
||||
|
||||
module.factory('Notifications', function($rootScope, $timeout) {
|
||||
// time (in ms) the notifications are shown
|
||||
var delay = 5000;
|
||||
|
@ -1745,6 +1774,19 @@ module.factory('AuthenticationFlowsCopy', function($resource) {
|
|||
alias : '@alias'
|
||||
});
|
||||
});
|
||||
|
||||
module.factory('AuthenticationFlowsUpdate', function($resource) {
|
||||
return $resource(authUrl + '/admin/realms/:realm/authentication/flows/:flow', {
|
||||
realm : '@realm',
|
||||
flow : '@flow'
|
||||
}, {
|
||||
update : {
|
||||
method : 'PUT'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
module.factory('AuthenticationConfigDescription', function($resource) {
|
||||
return $resource(authUrl + '/admin/realms/:realm/authentication/config-description/:provider', {
|
||||
realm : '@realm',
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<button class="btn btn-default" data-ng-click="createFlow()">{{:: 'new' | translate}}</button>
|
||||
<button class="btn btn-default" data-ng-click="copyFlow()">{{:: 'copy' | translate}}</button>
|
||||
<button class="btn btn-default" data-ng-hide="flow.builtIn" data-ng-click="deleteFlow()">{{:: 'delete' | translate}}</button>
|
||||
<button class="btn btn-default" data-ng-hide="flow.builtIn" data-ng-click="editFlow(flow)">{{:: 'edit-flow' | translate}}</button>
|
||||
<button class="btn btn-default" data-ng-hide="flow.builtIn" data-ng-click="addExecution()">{{:: 'add-execution' | translate}}</button>
|
||||
<button class="btn btn-default" data-ng-hide="flow.builtIn || flow.providerId === 'client-flow'" data-ng-click="addFlow()">{{:: 'add-flow' | translate}}</button>
|
||||
</div>
|
||||
|
@ -36,6 +37,7 @@
|
|||
<button data-ng-hide="flow.builtIn" data-ng-disabled="$first" class="btn btn-default btn-sm" data-ng-click="raisePriority(execution)"><i class="fa fa-angle-up"></i></button>
|
||||
<button data-ng-hide="flow.builtIn" data-ng-disabled="$last" class="btn btn-default btn-sm" data-ng-click="lowerPriority(execution)"><i class="fa fa-angle-down"></i></button>
|
||||
<span>{{execution.displayName|capitalize}}<span ng-if="execution.alias">({{execution.alias}})</span></span>
|
||||
<i data-ng-hide="!execution.authenticationFlow" class="fa fa-question-circle text-muted" tooltip-trigger="mouseover mouseout" tooltip="{{execution.description}}" tooltip-placement="right"> </i>
|
||||
</td>
|
||||
<td ng-repeat="lev in execution.postLevels"></td>
|
||||
<td ng-repeat="choice in execution.requirementChoices">
|
||||
|
@ -53,6 +55,7 @@
|
|||
<li data-ng-hide="flow.builtIn"><a href="" ng-click="removeExecution(execution)">{{:: 'delete' | translate}}</a></li>
|
||||
<li data-ng-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="addSubFlowExecution(execution)">{{:: 'add-execution' | translate}}</a></li>
|
||||
<li data-ng-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="addSubFlow(execution)">{{:: 'add-flow' | translate}}</a></li>
|
||||
<li data-ng-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="editExecutionFlow(execution)">{{:: 'edit-flow' | translate}}</a></li>
|
||||
<li data-ng-show="execution.configurable && execution.authenticationConfig == null"><a href="#/create/authentication/{{realm.realm}}/flows/{{flow.id}}/execution/{{execution.id}}/provider/{{execution.providerId}}">{{:: 'config' | translate}}</a></li>
|
||||
<li data-ng-show="execution.configurable && execution.authenticationConfig != null"><a href="#/realms/{{realm.realm}}/authentication/flows/{{flow.id}}/config/{{execution.providerId}}/{{execution.authenticationConfig}}">{{:: 'config' | translate}}</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<div class="modal-header">
|
||||
<button type="button" class="close" ng-click="cancel()">
|
||||
<span class="pficon pficon-close"></span>
|
||||
</button>
|
||||
<h4 class="modal-title">{{title}}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
<div>
|
||||
<label class="control-label" for="name">{{:: 'new-name' | translate}}</label>
|
||||
<input class="form-control" type="text" id="name" data-ng-model="name.value">
|
||||
</div>
|
||||
<div>
|
||||
<label class="control-label" for="name">{{:: 'new-description' | translate}}</label>
|
||||
<input class="form-control" type="text" id="description" data-ng-model="description.value">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="cancel()">{{:: 'cancel' | translate}}</button>
|
||||
<button type="button" class="btn btn-primary" ng-click="ok()">{{:: 'ok' | translate}}</button>
|
||||
</div>
|
Loading…
Reference in a new issue