2045 lines
77 KiB
JavaScript
Executable File
2045 lines
77 KiB
JavaScript
Executable File
module.controller('UserRoleMappingCtrl', function($scope, $http, $route, realm, user, client, Client, Notifications, RealmRoleMapping,
|
|
ClientRoleMapping, AvailableRealmRoleMapping, AvailableClientRoleMapping,
|
|
CompositeRealmRoleMapping, CompositeClientRoleMapping, $translate) {
|
|
$scope.realm = realm;
|
|
$scope.user = user;
|
|
$scope.selectedRealmRoles = [];
|
|
$scope.selectedRealmMappings = [];
|
|
$scope.realmMappings = [];
|
|
$scope.client = client;
|
|
$scope.clientRoles = [];
|
|
$scope.clientComposite = [];
|
|
$scope.selectedClientRoles = [];
|
|
$scope.selectedClientMappings = [];
|
|
$scope.clientMappings = [];
|
|
$scope.dummymodel = [];
|
|
$scope.selectedClient = null;
|
|
|
|
|
|
$scope.realmMappings = RealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.realmRoles = AvailableRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
|
|
$scope.addRealmRole = function() {
|
|
$scope.realmRolesToAdd = JSON.parse('[' + $scope.selectedRealmRoles + ']');
|
|
$scope.selectedRealmRoles = [];
|
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.id + '/role-mappings/realm',
|
|
$scope.realmRolesToAdd).then(function() {
|
|
$scope.realmMappings = RealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.realmRoles = AvailableRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.selectedRealmMappings = [];
|
|
$scope.selectRealmRoles = [];
|
|
if ($scope.selectedClient) {
|
|
console.log('load available');
|
|
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.selectedClientRoles = [];
|
|
$scope.selectedClientMappings = [];
|
|
}
|
|
Notifications.success($translate.instant('user.roles.add.success'));
|
|
|
|
});
|
|
};
|
|
|
|
$scope.deleteRealmRole = function() {
|
|
$scope.realmRolesToRemove = JSON.parse('[' + $scope.selectedRealmMappings + ']');
|
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.id + '/role-mappings/realm',
|
|
{data : $scope.realmRolesToRemove, headers : {"content-type" : "application/json"}}).then(function() {
|
|
$scope.realmMappings = RealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.realmRoles = AvailableRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.selectedRealmMappings = [];
|
|
$scope.selectRealmRoles = [];
|
|
if ($scope.selectedClient) {
|
|
console.log('load available');
|
|
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.selectedClientRoles = [];
|
|
$scope.selectedClientMappings = [];
|
|
}
|
|
Notifications.success($translate.instant('user.roles.remove.success'));
|
|
});
|
|
};
|
|
|
|
$scope.addClientRole = function() {
|
|
$scope.clientRolesToAdd = JSON.parse('[' + $scope.selectedClientRoles + ']');
|
|
$http.post(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.id + '/role-mappings/clients/' + $scope.selectedClient.id,
|
|
$scope.clientRolesToAdd).then(function() {
|
|
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.selectedClientRoles = [];
|
|
$scope.selectedClientMappings = [];
|
|
$scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.realmRoles = AvailableRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
Notifications.success($translate.instant('user.roles.add.success'));
|
|
});
|
|
};
|
|
|
|
$scope.deleteClientRole = function() {
|
|
$scope.clientRolesToRemove = JSON.parse('[' + $scope.selectedClientMappings + ']');
|
|
$http.delete(authUrl + '/admin/realms/' + realm.realm + '/users/' + user.id + '/role-mappings/clients/' + $scope.selectedClient.id,
|
|
{data : $scope.clientRolesToRemove, headers : {"content-type" : "application/json"}}).then(function() {
|
|
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.selectedClientRoles = [];
|
|
$scope.selectedClientMappings = [];
|
|
$scope.realmComposite = CompositeRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
$scope.realmRoles = AvailableRealmRoleMapping.query({realm : realm.realm, userId : user.id});
|
|
Notifications.success($translate.instant('user.roles.remove.success'));
|
|
});
|
|
};
|
|
|
|
$scope.changeClient = function(client) {
|
|
console.log("selected client: ", client);
|
|
if (!client || !client.id) {
|
|
$scope.selectedClient = null;
|
|
return;
|
|
} else {
|
|
$scope.selectedClient = client;
|
|
}
|
|
if ($scope.selectedClient) {
|
|
console.log('load available');
|
|
$scope.clientComposite = CompositeClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientRoles = AvailableClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
$scope.clientMappings = ClientRoleMapping.query({realm : realm.realm, userId : user.id, client : $scope.selectedClient.id});
|
|
} else {
|
|
$scope.clientRoles = null;
|
|
$scope.clientMappings = null;
|
|
$scope.clientComposite = null;
|
|
}
|
|
$scope.selectedClientRoles = [];
|
|
$scope.selectedClientMappings = [];
|
|
};
|
|
|
|
clientSelectControl($scope, $route.current.params.realm, Client);
|
|
});
|
|
|
|
module.controller('UserSessionsCtrl', function($scope, realm, user, sessions, UserSessions, UserLogout, UserSessionLogout, Notifications, $translate) {
|
|
$scope.realm = realm;
|
|
$scope.user = user;
|
|
$scope.sessions = sessions;
|
|
|
|
$scope.logoutAll = function() {
|
|
UserLogout.save({realm : realm.realm, user: user.id}, function () {
|
|
Notifications.success($translate.instant('user.logout.all.success'));
|
|
UserSessions.query({realm: realm.realm, user: user.id}, function(updated) {
|
|
$scope.sessions = updated;
|
|
})
|
|
});
|
|
};
|
|
|
|
$scope.logoutSession = function(sessionId) {
|
|
console.log('here in logoutSession');
|
|
UserSessionLogout.delete({realm : realm.realm, session: sessionId}, function() {
|
|
UserSessions.query({realm: realm.realm, user: user.id}, function(updated) {
|
|
$scope.sessions = updated;
|
|
Notifications.success($translate.instant('user.logout.session.success'));
|
|
})
|
|
});
|
|
}
|
|
});
|
|
|
|
module.controller('UserFederatedIdentityCtrl', function($scope, $location, realm, user, federatedIdentities, UserFederatedIdentity, Notifications, Dialog, $translate) {
|
|
$scope.realm = realm;
|
|
$scope.user = user;
|
|
$scope.federatedIdentities = federatedIdentities;
|
|
|
|
$scope.hasAnyProvidersToCreate = function() {
|
|
return realm.identityProviders.length - $scope.federatedIdentities.length > 0;
|
|
}
|
|
|
|
$scope.removeProviderLink = function(providerLink) {
|
|
|
|
console.log("Removing provider link: " + providerLink.identityProvider);
|
|
|
|
Dialog.confirmWithButtonText(
|
|
$translate.instant('user.fedid.link.remove.confirm.title', {name: providerLink.identityProvider}),
|
|
$translate.instant('user.fedid.link.remove.confirm.message', {name: providerLink.identityProvider}),
|
|
$translate.instant('dialogs.delete.confirm'),
|
|
function() {
|
|
UserFederatedIdentity.remove({ realm: realm.realm, user: user.id, provider: providerLink.identityProvider }, function() {
|
|
Notifications.success($translate.instant('user.fedid.link.remove.success'));
|
|
var indexToRemove = $scope.federatedIdentities.indexOf(providerLink);
|
|
$scope.federatedIdentities.splice(indexToRemove, 1);
|
|
});
|
|
}
|
|
);
|
|
}
|
|
});
|
|
|
|
module.controller('UserFederatedIdentityAddCtrl', function($scope, $location, realm, user, federatedIdentities, UserFederatedIdentity, Notifications, $translate) {
|
|
$scope.realm = realm;
|
|
$scope.user = user;
|
|
$scope.federatedIdentity = {};
|
|
|
|
var getAvailableProvidersToCreate = function() {
|
|
var realmProviders = [];
|
|
for (var i=0 ; i<realm.identityProviders.length ; i++) {
|
|
var providerAlias = realm.identityProviders[i].alias;
|
|
realmProviders.push(providerAlias);
|
|
};
|
|
|
|
for (var i=0 ; i<federatedIdentities.length ; i++) {
|
|
var providerAlias = federatedIdentities[i].identityProvider;
|
|
var index = realmProviders.indexOf(providerAlias);
|
|
realmProviders.splice(index, 1);
|
|
}
|
|
|
|
return realmProviders;
|
|
}
|
|
$scope.availableProvidersToCreate = getAvailableProvidersToCreate();
|
|
|
|
$scope.save = function() {
|
|
UserFederatedIdentity.save({
|
|
realm : realm.realm,
|
|
user: user.id,
|
|
provider: $scope.federatedIdentity.identityProvider
|
|
}, $scope.federatedIdentity, function(data, headers) {
|
|
$location.url("/realms/" + realm.realm + '/users/' + $scope.user.id + '/federated-identity');
|
|
Notifications.success($translate.instant('user.fedid.link.add.success'));
|
|
});
|
|
};
|
|
|
|
$scope.cancel = function() {
|
|
$location.url("/realms/" + realm.realm + '/users/' + $scope.user.id + '/federated-identity');
|
|
};
|
|
|
|
});
|
|
|
|
module.controller('UserConsentsCtrl', function($scope, realm, user, userConsents, UserConsents, Notifications, $translate) {
|
|
$scope.realm = realm;
|
|
$scope.user = user;
|
|
$scope.userConsents = userConsents;
|
|
|
|
$scope.revokeConsent = function(clientId) {
|
|
UserConsents.delete({realm : realm.realm, user: user.id, client: clientId }, function () {
|
|
UserConsents.query({realm: realm.realm, user: user.id}, function(updated) {
|
|
$scope.userConsents = updated;
|
|
})
|
|
Notifications.success($translate.instant('user.consent.revoke.success'));
|
|
}, function() {
|
|
Notifications.error($translate.instant('user.consent.revoke.error'));
|
|
});
|
|
console.log("Revoke consent " + clientId);
|
|
}
|
|
});
|
|
|
|
module.controller('UserOfflineSessionsCtrl', function($scope, $location, realm, user, client, offlineSessions) {
|
|
$scope.realm = realm;
|
|
$scope.user = user;
|
|
$scope.client = client;
|
|
$scope.offlineSessions = offlineSessions;
|
|
|
|
$scope.cancel = function() {
|
|
$location.url("/realms/" + realm.realm + '/users/' + user.id + '/consents');
|
|
};
|
|
});
|
|
|
|
|
|
module.controller('UserListCtrl', function($scope, realm, User, UserSearchState, UserImpersonation, BruteForce, Notifications, $route, Dialog, $translate) {
|
|
|
|
$scope.init = function() {
|
|
$scope.realm = realm;
|
|
|
|
UserSearchState.query.realm = realm.realm;
|
|
$scope.query = UserSearchState.query;
|
|
$scope.query.briefRepresentation = 'true';
|
|
|
|
if (!UserSearchState.isFirstSearch) $scope.searchQuery();
|
|
};
|
|
|
|
$scope.impersonate = function(userId) {
|
|
UserImpersonation.save({realm : realm.realm, user: userId}, function (data) {
|
|
if (data.sameRealm) {
|
|
window.location = data.redirect;
|
|
} else {
|
|
window.open(data.redirect, "_blank");
|
|
}
|
|
});
|
|
};
|
|
|
|
$scope.unlockUsers = function() {
|
|
BruteForce.delete({realm: realm.realm}, function(data) {
|
|
Notifications.success($translate.instant('user.unlock.success'));
|
|
});
|
|
}
|
|
|
|
|
|
$scope.firstPage = function() {
|
|
$scope.query.first = 0;
|
|
$scope.searchQuery();
|
|
}
|
|
|
|
$scope.previousPage = function() {
|
|
$scope.query.first -= parseInt($scope.query.max);
|
|
if ($scope.query.first < 0) {
|
|
$scope.query.first = 0;
|
|
}
|
|
$scope.searchQuery();
|
|
}
|
|
|
|
$scope.nextPage = function() {
|
|
$scope.query.first += parseInt($scope.query.max);
|
|
$scope.searchQuery();
|
|
}
|
|
|
|
$scope.searchQuery = function() {
|
|
console.log("query.search: " + $scope.query.search);
|
|
$scope.searchLoaded = false;
|
|
|
|
$scope.users = User.query($scope.query, function() {
|
|
$scope.searchLoaded = true;
|
|
$scope.lastSearch = $scope.query.search;
|
|
UserSearchState.isFirstSearch = false;
|
|
});
|
|
};
|
|
|
|
$scope.removeUser = function(user) {
|
|
Dialog.confirmWithButtonText(
|
|
$translate.instant('user.remove.confirm.title', {name: user.id}),
|
|
$translate.instant('user.remove.confirm.message', {name: user.id}),
|
|
$translate.instant('dialogs.delete.confirm'),
|
|
function() {
|
|
user.$remove({
|
|
realm : realm.realm,
|
|
userId : user.id
|
|
}, function() {
|
|
$route.reload();
|
|
|
|
if ($scope.users.length === 1 && $scope.query.first > 0) {
|
|
$scope.previousPage();
|
|
}
|
|
|
|
Notifications.success($translate.instant('user.remove.success'));
|
|
}, function() {
|
|
Notifications.error($translate.instant('user.remove.error'));
|
|
});
|
|
}
|
|
);
|
|
};
|
|
});
|
|
|
|
|
|
module.controller('UserTabCtrl', function($scope, $location, Dialog, Notifications, Current) {
|
|
$scope.removeUser = function() {
|
|
Dialog.confirmDelete($scope.user.id, 'user', function() {
|
|
$scope.user.$remove({
|
|
realm : Current.realm.realm,
|
|
userId : $scope.user.id
|
|
}, function() {
|
|
$location.url("/realms/" + Current.realm.realm + "/users");
|
|
Notifications.success($translate.instant('user.remove.success'));
|
|
}, function() {
|
|
Notifications.error($translate.instant('user.remove.error'));
|
|
});
|
|
});
|
|
};
|
|
});
|
|
|
|
function loadUserStorageLink(realm, user, console, Components, UserStorageOperations, $scope, $location) {
|
|
if(user.federationLink) {
|
|
console.log("federationLink is not null. It is " + user.federationLink);
|
|
|
|
if ($scope.access.viewRealm) {
|
|
Components.get({realm: realm.realm, componentId: user.federationLink}, function (link) {
|
|
$scope.federationLinkName = link.name;
|
|
$scope.federationLink = "#/realms/" + realm.realm + "/user-storage/providers/" + link.providerId + "/" + link.id;
|
|
});
|
|
} else {
|
|
// KEYCLOAK-4328
|
|
UserStorageOperations.simpleName.get({realm: realm.realm, componentId: user.federationLink}, function (link) {
|
|
$scope.federationLinkName = link.name;
|
|
$scope.federationLink = $location.absUrl();
|
|
})
|
|
}
|
|
|
|
} else {
|
|
console.log("federationLink is null");
|
|
}
|
|
|
|
if(user.origin) {
|
|
if ($scope.access.viewRealm) {
|
|
Components.get({realm: realm.realm, componentId: user.origin}, function (link) {
|
|
$scope.originName = link.name;
|
|
$scope.originLink = "#/realms/" + realm.realm + "/user-storage/providers/" + link.providerId + "/" + link.id;
|
|
})
|
|
}
|
|
else {
|
|
// KEYCLOAK-4328
|
|
UserStorageOperations.simpleName.get({realm: realm.realm, componentId: user.origin}, function (link) {
|
|
$scope.originName = link.name;
|
|
$scope.originLink = $location.absUrl();
|
|
})
|
|
}
|
|
} else {
|
|
console.log("origin is null");
|
|
}
|
|
};
|
|
|
|
module.controller('UserDetailCtrl', function($scope, realm, user, BruteForceUser, User,
|
|
Components,
|
|
UserImpersonation, RequiredActions,
|
|
UserStorageOperations,
|
|
$location, $http, Dialog, Notifications, $translate, Groups) {
|
|
$scope.realm = realm;
|
|
$scope.create = !user.id;
|
|
$scope.editUsername = $scope.create || $scope.realm.editUsernameAllowed;
|
|
$scope.emailAsUsername = $scope.realm.registrationEmailAsUsername;
|
|
$scope.groupSearch = { selectedGroup : null };
|
|
|
|
if ($scope.create) {
|
|
$scope.user = { enabled: true, attributes: {}, groups: [] }
|
|
} else {
|
|
if (!user.attributes) {
|
|
user.attributes = {}
|
|
}
|
|
convertAttributeValuesToString(user);
|
|
|
|
|
|
$scope.user = angular.copy(user);
|
|
$scope.impersonate = function() {
|
|
UserImpersonation.save({realm : realm.realm, user: $scope.user.id}, function (data) {
|
|
if (data.sameRealm) {
|
|
window.location = data.redirect;
|
|
} else {
|
|
window.open(data.redirect, "_blank");
|
|
}
|
|
});
|
|
};
|
|
|
|
loadUserStorageLink(realm, user, console, Components, UserStorageOperations, $scope, $location);
|
|
|
|
console.log('realm brute force? ' + realm.bruteForceProtected)
|
|
$scope.temporarilyDisabled = false;
|
|
var isDisabled = function () {
|
|
BruteForceUser.get({realm: realm.realm, userId: user.id}, function(data) {
|
|
console.log('here in isDisabled ' + data.disabled);
|
|
$scope.temporarilyDisabled = data.disabled;
|
|
});
|
|
};
|
|
|
|
console.log("check if disabled");
|
|
isDisabled();
|
|
|
|
$scope.unlockUser = function() {
|
|
BruteForceUser.delete({realm: realm.realm, userId: user.id}, function(data) {
|
|
isDisabled();
|
|
});
|
|
}
|
|
}
|
|
|
|
$scope.changed = false; // $scope.create;
|
|
if (user.requiredActions) {
|
|
for (var i = 0; i < user.requiredActions.length; i++) {
|
|
console.log("user require action: " + user.requiredActions[i]);
|
|
}
|
|
}
|
|
// ID - Name map for required actions. IDs are enum names.
|
|
RequiredActions.query({realm: realm.realm}, function(data) {
|
|
$scope.userReqActionList = [];
|
|
for (var i = 0; i < data.length; i++) {
|
|
console.log("listed required action: " + data[i].name);
|
|
if (data[i].enabled) {
|
|
var item = data[i];
|
|
$scope.userReqActionList.push(item);
|
|
}
|
|
}
|
|
console.log("---------------------");
|
|
console.log("ng-model: user.requiredActions=" + JSON.stringify($scope.user.requiredActions));
|
|
console.log("---------------------");
|
|
console.log("ng-repeat: userReqActionList=" + JSON.stringify($scope.userReqActionList));
|
|
console.log("---------------------");
|
|
});
|
|
$scope.$watch('user', function() {
|
|
if (!angular.equals($scope.user, user)) {
|
|
$scope.changed = true;
|
|
}
|
|
}, true);
|
|
|
|
$scope.save = function() {
|
|
convertAttributeValuesToLists();
|
|
|
|
if ($scope.create) {
|
|
pushSelectedGroupsToUser();
|
|
|
|
User.save({
|
|
realm: realm.realm
|
|
}, $scope.user, function (data, headers) {
|
|
$scope.changed = false;
|
|
convertAttributeValuesToString($scope.user);
|
|
user = angular.copy($scope.user);
|
|
var l = headers().location;
|
|
|
|
console.debug("Location == " + l);
|
|
|
|
var id = l.substring(l.lastIndexOf("/") + 1);
|
|
|
|
|
|
$location.url("/realms/" + realm.realm + "/users/" + id);
|
|
Notifications.success($translate.instant('user.create.success'));
|
|
});
|
|
} else {
|
|
User.update({
|
|
realm: realm.realm,
|
|
userId: $scope.user.id
|
|
}, $scope.user, function () {
|
|
$scope.changed = false;
|
|
convertAttributeValuesToString($scope.user);
|
|
user = angular.copy($scope.user);
|
|
Notifications.success($translate.instant('user.edit.success'));
|
|
});
|
|
}
|
|
};
|
|
|
|
function convertAttributeValuesToLists() {
|
|
var attrs = $scope.user.attributes;
|
|
for (var attribute in attrs) {
|
|
if (typeof attrs[attribute] === "string") {
|
|
var attrVals = attrs[attribute].split("##");
|
|
attrs[attribute] = attrVals;
|
|
}
|
|
}
|
|
}
|
|
|
|
function convertAttributeValuesToString(user) {
|
|
var attrs = user.attributes;
|
|
for (var attribute in attrs) {
|
|
if (typeof attrs[attribute] === "object") {
|
|
var attrVals = attrs[attribute].join("##");
|
|
attrs[attribute] = attrVals;
|
|
}
|
|
}
|
|
}
|
|
|
|
function pushSelectedGroupsToUser() {
|
|
var groups = $scope.user.groups;
|
|
if ($scope.selectedGroups) {
|
|
for (i = 0; i < $scope.selectedGroups.length; i++) {
|
|
var groupPath = $scope.selectedGroups[i].path;
|
|
if (!groups.includes(groupPath)) {
|
|
groups.push(groupPath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function bfs(tree, collection) {
|
|
if (!tree["subGroups"] || tree["subGroups"].length === 0) return;
|
|
for (var i=0; i < tree["subGroups"].length; i++) {
|
|
var child = tree["subGroups"][i]
|
|
collection.push(child);
|
|
bfs(child, collection);
|
|
}
|
|
return;
|
|
}
|
|
|
|
function flattenGroups(groups) {
|
|
var flattenedGroups = [];
|
|
if (!groups || groups.length === 0) return groups;
|
|
for (var i=0; i < groups.length; i++) {
|
|
flattenedGroups.push(groups[i]);
|
|
bfs(groups[i], flattenedGroups);
|
|
}
|
|
|
|
return flattenedGroups;
|
|
}
|
|
|
|
/**
|
|
* Only keep groups that :
|
|
* - include the search term in their path
|
|
* - are not already selected
|
|
*/
|
|
function filterSearchedGroups(groups, term, selectedGroups) {
|
|
if (!groups || groups.length === 0) return groups;
|
|
if (!selectedGroups) selectedGroups = [];
|
|
|
|
return groups.filter(group => group.path?.includes(term) && !selectedGroups.some(selGroup => selGroup.id === group.id));
|
|
}
|
|
|
|
$scope.reset = function() {
|
|
$scope.user = angular.copy(user);
|
|
$scope.changed = false;
|
|
};
|
|
|
|
$scope.cancel = function() {
|
|
$location.url("/realms/" + realm.realm + "/users");
|
|
};
|
|
|
|
$scope.addAttribute = function() {
|
|
$scope.user.attributes[$scope.newAttribute.key] = $scope.newAttribute.value;
|
|
delete $scope.newAttribute;
|
|
}
|
|
|
|
$scope.removeAttribute = function(key) {
|
|
delete $scope.user.attributes[key];
|
|
}
|
|
|
|
$scope.groupsUiSelect = {
|
|
minimumInputLength: 1,
|
|
delay: 500,
|
|
allowClear: true,
|
|
query: function (query) {
|
|
var data = {results: []};
|
|
if ('' == query.term.trim()) {
|
|
query.callback(data);
|
|
return;
|
|
}
|
|
$scope.query = {
|
|
realm: realm.realm,
|
|
search: query.term.trim(),
|
|
max : 20,
|
|
first : 0
|
|
};
|
|
Groups.query($scope.query, function(response) {
|
|
data.results = filterSearchedGroups(flattenGroups(response), query.term.trim(), $scope.selectedGroups);
|
|
query.callback(data);
|
|
});
|
|
},
|
|
formatResult: function(object, container, query) {
|
|
object.text = object.path;
|
|
return object.path;
|
|
}
|
|
};
|
|
|
|
$scope.removeGroup = function(list, group) {
|
|
for (i = 0; i < angular.copy(list).length; i++) {
|
|
if (group.id == list[i].id) {
|
|
list.splice(i, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
$scope.selectGroup = function(group) {
|
|
if (!group || !group.id) {
|
|
return;
|
|
}
|
|
|
|
$scope.groupSearch.selectedGroup = group;
|
|
|
|
if (!$scope.selectedGroups) {
|
|
$scope.selectedGroups = [];
|
|
}
|
|
|
|
for (i = 0; i < $scope.selectedGroups.length; i++) {
|
|
if ($scope.selectedGroups[i].id == group.id) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
$scope.selectedGroups.push(group);
|
|
$scope.groupSearch.selectedGroup = null;
|
|
}
|
|
|
|
$scope.clearGroupSelection = function() {
|
|
$scope.groupSearch.selectedGroup = null;
|
|
$('#groups').val(null).trigger('change.select2');
|
|
}
|
|
});
|
|
|
|
module.controller('UserCredentialsCtrl', function($scope, realm, user, $route, $location, RequiredActions, User, UserExecuteActionsEmail,
|
|
UserCredentials, Notifications, Dialog, TimeUnit2, Components, UserStorageOperations, $modal, $translate) {
|
|
console.log('UserCredentialsCtrl');
|
|
|
|
$scope.hasPassword = false;
|
|
|
|
loadCredentials();
|
|
|
|
loadUserStorageLink(realm, user, console, Components, UserStorageOperations, $scope, $location);
|
|
|
|
$scope.getUserStorageProviderName = function() {
|
|
return user.federationLink ? $scope.federationLinkName : $scope.originName;
|
|
}
|
|
|
|
$scope.getUserStorageProviderLink = function() {
|
|
return user.federationLink ? $scope.federationLink : $scope.originLink;
|
|
}
|
|
|
|
$scope.updateCredentialLabel = function(credential) {
|
|
UserCredentials.updateCredentialLabel({ realm: realm.realm, userId: user.id, credentialId: credential.id }, {
|
|
'id': credential.id,
|
|
'userLabel': credential.userLabel ? credential.userLabel : "",
|
|
// We JSONify the credential data
|
|
'credentialData': JSON.stringify(credential.credentialData)
|
|
}, function() {
|
|
Notifications.success($translate.instant('user.credential.update.success'));
|
|
}, function(err) {
|
|
Notifications.error($translate.instant('user.credential.update.error'));
|
|
console.log(err);
|
|
});
|
|
}
|
|
|
|
$scope.deleteCredential = function(credential) {
|
|
Dialog.confirmWithButtonText(
|
|
$translate.instant('user.credential.remove.confirm.title', {name: credential.id}),
|
|
$translate.instant('user.credential.remove.confirm.message', {name: credential.id}),
|
|
$translate.instant('dialogs.delete.confirm'),
|
|
function() {
|
|
UserCredentials.deleteCredential({ realm: realm.realm, userId: user.id, credentialId: credential.id }, null, function() {
|
|
Notifications.success($translate.instant('user.credential.remove.success'));
|
|
$route.reload();
|
|
}, function(err) {
|
|
Notifications.error($translate.instant('user.credential.remove.error'));
|
|
console.log(err);
|
|
})
|
|
}
|
|
);
|
|
}
|
|
|
|
$scope.moveUp = function(credentials, index) {
|
|
// Safety first
|
|
if (index == 0) {
|
|
return;
|
|
} else if (index == 1) {
|
|
UserCredentials.moveToFirst(
|
|
{
|
|
realm: realm.realm,
|
|
userId: user.id,
|
|
credentialId: credentials[index].id
|
|
},
|
|
function () {
|
|
$route.reload();
|
|
},
|
|
function (err) {
|
|
Notifications.error($translate.instant('user.credential.move-top.error'));
|
|
console.log(err);
|
|
});
|
|
|
|
} else {
|
|
UserCredentials.moveCredentialAfter(
|
|
{
|
|
realm: realm.realm,
|
|
userId: user.id,
|
|
credentialId: credentials[index].id,
|
|
newPreviousCredentialId: credentials[index - 2].id
|
|
},
|
|
function () {
|
|
$route.reload();
|
|
},
|
|
function (err) {
|
|
Notifications.error($translate.instant('user.credential.move-up.error'));
|
|
console.log(err);
|
|
});
|
|
}
|
|
}
|
|
|
|
$scope.moveDown = function(credentials, index) {
|
|
// Safety first
|
|
if (index == credentials.length - 1) {
|
|
return;
|
|
}
|
|
UserCredentials.moveCredentialAfter(
|
|
{
|
|
realm: realm.realm,
|
|
userId: user.id,
|
|
credentialId: credentials[index].id,
|
|
newPreviousCredentialId: credentials[index + 1].id
|
|
},
|
|
function() {
|
|
$route.reload();
|
|
},
|
|
function(err) {
|
|
Notifications.error($translate.instant('user.credential.move-down.error'));
|
|
console.log(err);
|
|
});
|
|
}
|
|
|
|
$scope.showData = function(credentialData) {
|
|
$modal.open({
|
|
templateUrl: resourceUrl + '/partials/modal/user-credential-data.html',
|
|
controller: 'UserCredentialsDataModalCtrl',
|
|
resolve: {
|
|
credentialData: function () {
|
|
return credentialData;
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
$scope.realm = realm;
|
|
$scope.user = angular.copy(user);
|
|
$scope.temporaryPassword = true;
|
|
|
|
$scope.isTotp = false;
|
|
if(!!user.totp){
|
|
$scope.isTotp = user.totp;
|
|
}
|
|
// ID - Name map for required actions. IDs are enum names.
|
|
RequiredActions.query({realm: realm.realm}, function(data) {
|
|
$scope.userReqActionList = [];
|
|
for (var i = 0; i < data.length; i++) {
|
|
console.log("listed required action: " + data[i].name);
|
|
if (data[i].enabled) {
|
|
var item = data[i];
|
|
$scope.userReqActionList.push(item);
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
function loadCredentials() {
|
|
UserCredentials.getCredentials({ realm: realm.realm, userId: user.id }, null, function(credentials) {
|
|
$scope.credentials = credentials.map(function(c) {
|
|
// We de-JSONify the credential data
|
|
if (c.credentialData) {
|
|
c.credentialData = JSON.parse(c.credentialData);
|
|
}
|
|
if (c.type == 'password') {
|
|
$scope.hasPassword = true;
|
|
}
|
|
return c;
|
|
});
|
|
}, function(err) {
|
|
Notifications.error($translate.instant('user.credential.fetch.error'));
|
|
console.log(err);
|
|
});
|
|
|
|
UserCredentials.getConfiguredUserStorageCredentialTypes({ realm: realm.realm, userId: user.id }, null, function(userStorageCredentialTypes) {
|
|
$scope.userStorageCredentialTypes = userStorageCredentialTypes;
|
|
$scope.hasPassword = $scope.hasPassword || userStorageCredentialTypes.lastIndexOf("password") > -1;
|
|
}, function(err) {
|
|
Notifications.error($translate.instant('user.credential.storage.fetch.error'));
|
|
console.log(err);
|
|
});
|
|
}
|
|
|
|
$scope.resetPassword = function() {
|
|
// hit enter without entering both fields - ignore
|
|
if (!$scope.passwordAndConfirmPasswordEntered()) return;
|
|
|
|
if ($scope.pwdChange) {
|
|
if ($scope.password != $scope.confirmPassword) {
|
|
Notifications.error($translate.instant('user.password.error.not-matching'));
|
|
return;
|
|
}
|
|
}
|
|
|
|
var msgTitle = ($scope.hasPassword ? $translate.instant('user.password.reset.confirm.title') : $translate.instant('user.password.set.confirm.title'));
|
|
var msg = ($scope.hasPassword ? $translate.instant('user.password.reset.confirm.message') : $translate.instant('user.password.set.confirm.message'));
|
|
var msgSuccess = ($scope.hasPassword ? $translate.instant('user.password.reset.success') : $translate.instant('user.password.set.success'));
|
|
|
|
Dialog.confirm(msgTitle, msg, function() {
|
|
UserCredentials.resetPassword({ realm: realm.realm, userId: user.id }, { type : "password", value : $scope.password, temporary: $scope.temporaryPassword }, function() {
|
|
Notifications.success(msgSuccess);
|
|
$scope.password = null;
|
|
$scope.confirmPassword = null;
|
|
$route.reload();
|
|
});
|
|
}, function() {
|
|
$scope.password = null;
|
|
$scope.confirmPassword = null;
|
|
});
|
|
};
|
|
|
|
$scope.passwordAndConfirmPasswordEntered = function() {
|
|
return $scope.password && $scope.confirmPassword;
|
|
}
|
|
|
|
$scope.disableCredentialTypes = function() {
|
|
Dialog.confirm(
|
|
$translate.instant('user.credential.disable.confirm.title'),
|
|
$translate.instant('user.credential.disable.confirm.message'),
|
|
function() {
|
|
UserCredentials.disableCredentialTypes({ realm: realm.realm, userId: user.id }, $scope.disableableCredentialTypes, function() {
|
|
$route.reload();
|
|
Notifications.success($translate.instant('user.credential.disable.confirm.success'));
|
|
}, function() {
|
|
Notifications.error($translate.instant('user.credential.disable.confirm.error'));
|
|
});
|
|
});
|
|
};
|
|
|
|
$scope.emailActions = [];
|
|
$scope.emailActionsTimeout = TimeUnit2.asUnit(realm.actionTokenGeneratedByAdminLifespan);
|
|
$scope.disableableCredentialTypes = [];
|
|
|
|
$scope.sendExecuteActionsEmail = function() {
|
|
if ($scope.changed) {
|
|
Dialog.message($translate.instant('user.actions-email.send.pending-changes.title'),
|
|
$translate.instant('user.actions-email.send.pending-changes.message'));
|
|
return;
|
|
}
|
|
Dialog.confirm(
|
|
$translate.instant('user.actions-email.send.confirm.title'),
|
|
$translate.instant('user.actions-email.send.confirm.message'),
|
|
function() {
|
|
UserExecuteActionsEmail.update({ realm: realm.realm, userId: user.id, lifespan: $scope.emailActionsTimeout.toSeconds() }, $scope.emailActions, function() {
|
|
Notifications.success($translate.instant('user.actions-email.send.confirm.success'));
|
|
}, function() {
|
|
Notifications.error($translate.instant('user.actions-email.send.confirm.error'));
|
|
});
|
|
});
|
|
};
|
|
|
|
|
|
|
|
$scope.$watch('user', function() {
|
|
if (!angular.equals($scope.user, user)) {
|
|
$scope.userChange = true;
|
|
} else {
|
|
$scope.userChange = false;
|
|
}
|
|
}, true);
|
|
|
|
$scope.$watch('password', function() {
|
|
if (!!$scope.password){
|
|
$scope.pwdChange = true;
|
|
} else {
|
|
$scope.pwdChange = false;
|
|
}
|
|
}, true);
|
|
|
|
$scope.reset = function() {
|
|
$scope.password = "";
|
|
$scope.confirmPassword = "";
|
|
|
|
$scope.user = angular.copy(user);
|
|
|
|
$scope.isTotp = false;
|
|
if(!!user.totp){
|
|
$scope.isTotp = user.totp;
|
|
}
|
|
|
|
$scope.pwdChange = false;
|
|
$scope.userChange = false;
|
|
};
|
|
});
|
|
|
|
module.controller('UserCredentialsDataModalCtrl', function($scope, credentialData) {
|
|
$scope.credentialData = credentialData;
|
|
|
|
$scope.keys = function(object) {
|
|
return object ? Object.keys(object) : [];
|
|
}
|
|
});
|
|
|
|
module.controller('UserFederationCtrl', function($scope, $location, $route, realm, serverInfo, Components, Notifications, Dialog, $translate) {
|
|
console.log('UserFederationCtrl ++++****');
|
|
$scope.realm = realm;
|
|
$scope.providers = serverInfo.componentTypes['org.keycloak.storage.UserStorageProvider'];
|
|
$scope.instancesLoaded = false;
|
|
|
|
if (!$scope.providers) $scope.providers = [];
|
|
|
|
$scope.addProvider = function(provider) {
|
|
console.log('Add provider: ' + provider.id);
|
|
$location.url("/create/user-storage/" + realm.realm + "/providers/" + provider.id);
|
|
};
|
|
|
|
$scope.getInstanceLink = function(instance) {
|
|
return "/realms/" + realm.realm + "/user-storage/providers/" + instance.providerId + "/" + instance.id;
|
|
}
|
|
|
|
$scope.getInstanceName = function(instance) {
|
|
return instance.name;
|
|
}
|
|
$scope.getInstanceProvider = function(instance) {
|
|
return instance.providerId;
|
|
}
|
|
|
|
$scope.isProviderEnabled = function(instance) {
|
|
return !instance.config['enabled'] || instance.config['enabled'][0] == 'true';
|
|
}
|
|
|
|
$scope.getInstancePriority = function(instance) {
|
|
if (!instance.config['priority']) {
|
|
console.log('getInstancePriority is undefined');
|
|
return -1;
|
|
}
|
|
return +instance.config['priority'][0];
|
|
}
|
|
|
|
Components.query({realm: realm.realm,
|
|
parent: realm.id,
|
|
type: 'org.keycloak.storage.UserStorageProvider'
|
|
}, function(data) {
|
|
$scope.instances = data;
|
|
$scope.instancesLoaded = true;
|
|
});
|
|
|
|
$scope.removeInstance = function(instance) {
|
|
Dialog.confirmWithButtonText(
|
|
$translate.instant('user.storage.remove.confirm.title', {name: instance.name}),
|
|
$translate.instant('user.storage.remove.confirm.message', {name: instance.name}),
|
|
$translate.instant('dialogs.delete.confirm'),
|
|
function() {
|
|
Components.remove({
|
|
realm : realm.realm,
|
|
componentId : instance.id
|
|
}, function() {
|
|
$route.reload();
|
|
Notifications.success($translate.instant('user.storage.remove.success'));
|
|
});
|
|
}
|
|
);
|
|
};
|
|
});
|
|
|
|
module.controller('GenericUserStorageCtrl', function($scope, $location, Notifications, $route, Dialog, realm,
|
|
serverInfo, instance, providerId, Components, UserStorageOperations, $translate) {
|
|
console.log('GenericUserStorageCtrl');
|
|
console.log('providerId: ' + providerId);
|
|
$scope.create = !instance.providerId;
|
|
console.log('create: ' + $scope.create);
|
|
var providers = serverInfo.componentTypes['org.keycloak.storage.UserStorageProvider'];
|
|
console.log('providers length ' + providers.length);
|
|
var providerFactory = null;
|
|
for (var i = 0; i < providers.length; i++) {
|
|
var p = providers[i];
|
|
console.log('provider: ' + p.id);
|
|
if (p.id == providerId) {
|
|
$scope.providerFactory = p;
|
|
providerFactory = p;
|
|
break;
|
|
}
|
|
|
|
}
|
|
$scope.showSync = false;
|
|
$scope.changed = false;
|
|
|
|
console.log("providerFactory: " + providerFactory.id);
|
|
|
|
function initUserStorageSettings() {
|
|
if ($scope.create) {
|
|
$scope.changed = true;
|
|
instance.name = providerFactory.id;
|
|
instance.providerId = providerFactory.id;
|
|
instance.providerType = 'org.keycloak.storage.UserStorageProvider';
|
|
instance.parentId = realm.id;
|
|
instance.config = {
|
|
|
|
};
|
|
instance.config['priority'] = ["0"];
|
|
instance.config['enabled'] = ["true"];
|
|
|
|
$scope.fullSyncEnabled = false;
|
|
$scope.changedSyncEnabled = false;
|
|
if (providerFactory.metadata.synchronizable) {
|
|
instance.config['fullSyncPeriod'] = ['-1'];
|
|
instance.config['changedSyncPeriod'] = ['-1'];
|
|
|
|
}
|
|
instance.config['cachePolicy'] = ['DEFAULT'];
|
|
instance.config['evictionDay'] = [''];
|
|
instance.config['evictionHour'] = [''];
|
|
instance.config['evictionMinute'] = [''];
|
|
instance.config['maxLifespan'] = [''];
|
|
if (providerFactory.properties) {
|
|
|
|
for (var i = 0; i < providerFactory.properties.length; i++) {
|
|
var configProperty = providerFactory.properties[i];
|
|
if (configProperty.defaultValue) {
|
|
instance.config[configProperty.name] = [configProperty.defaultValue];
|
|
} else {
|
|
instance.config[configProperty.name] = [''];
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
} else {
|
|
$scope.changed = false;
|
|
$scope.fullSyncEnabled = (instance.config['fullSyncPeriod'] && instance.config['fullSyncPeriod'][0] > 0);
|
|
$scope.changedSyncEnabled = (instance.config['changedSyncPeriod'] && instance.config['changedSyncPeriod'][0]> 0);
|
|
if (providerFactory.metadata.synchronizable) {
|
|
if (!instance.config['fullSyncPeriod']) {
|
|
console.log('setting to -1');
|
|
instance.config['fullSyncPeriod'] = ['-1'];
|
|
|
|
}
|
|
if (!instance.config['changedSyncPeriod']) {
|
|
console.log('setting to -1');
|
|
instance.config['changedSyncPeriod'] = ['-1'];
|
|
|
|
}
|
|
}
|
|
if (!instance.config['enabled']) {
|
|
instance.config['enabled'] = ['true'];
|
|
}
|
|
if (!instance.config['cachePolicy']) {
|
|
instance.config['cachePolicy'] = ['DEFAULT'];
|
|
|
|
}
|
|
if (!instance.config['evictionDay']) {
|
|
instance.config['evictionDay'] = [''];
|
|
|
|
}
|
|
if (!instance.config['evictionHour']) {
|
|
instance.config['evictionHour'] = [''];
|
|
|
|
}
|
|
if (!instance.config['evictionMinute']) {
|
|
instance.config['evictionMinute'] = [''];
|
|
|
|
}
|
|
if (!instance.config['maxLifespan']) {
|
|
instance.config['maxLifespan'] = [''];
|
|
|
|
}
|
|
if (!instance.config['priority']) {
|
|
instance.config['priority'] = ['0'];
|
|
}
|
|
|
|
if (providerFactory.properties) {
|
|
for (var i = 0; i < providerFactory.properties.length; i++) {
|
|
var configProperty = providerFactory.properties[i];
|
|
if (!instance.config[configProperty.name]) {
|
|
instance.config[configProperty.name] = [''];
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
if (providerFactory.metadata.synchronizable) {
|
|
if (instance.config && instance.config['importEnabled']) {
|
|
$scope.showSync = instance.config['importEnabled'][0] == 'true';
|
|
} else {
|
|
$scope.showSync = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
initUserStorageSettings();
|
|
$scope.instance = angular.copy(instance);
|
|
$scope.realm = realm;
|
|
|
|
$scope.$watch('instance', function() {
|
|
if (!angular.equals($scope.instance, instance)) {
|
|
$scope.changed = true;
|
|
}
|
|
|
|
}, true);
|
|
|
|
$scope.$watch('fullSyncEnabled', function(newVal, oldVal) {
|
|
if (oldVal == newVal) {
|
|
return;
|
|
}
|
|
|
|
$scope.instance.config['fullSyncPeriod'][0] = $scope.fullSyncEnabled ? "604800" : "-1";
|
|
$scope.changed = true;
|
|
});
|
|
|
|
$scope.$watch('changedSyncEnabled', function(newVal, oldVal) {
|
|
if (oldVal == newVal) {
|
|
return;
|
|
}
|
|
|
|
$scope.instance.config['changedSyncPeriod'][0] = $scope.changedSyncEnabled ? "86400" : "-1";
|
|
$scope.changed = true;
|
|
});
|
|
|
|
|
|
$scope.save = function() {
|
|
console.log('save provider');
|
|
$scope.changed = false;
|
|
if ($scope.create) {
|
|
console.log('saving new provider');
|
|
Components.save({realm: realm.realm}, $scope.instance, function (data, headers) {
|
|
var l = headers().location;
|
|
var id = l.substring(l.lastIndexOf("/") + 1);
|
|
|
|
$location.url("/realms/" + realm.realm + "/user-storage/providers/" + $scope.instance.providerId + "/" + id);
|
|
Notifications.success($translate.instant('user.storage.create.success'));
|
|
});
|
|
} else {
|
|
console.log('update existing provider');
|
|
Components.update({realm: realm.realm,
|
|
componentId: instance.id
|
|
},
|
|
$scope.instance, function () {
|
|
$route.reload();
|
|
Notifications.success($translate.instant('user.storage.edit.success'));
|
|
});
|
|
}
|
|
};
|
|
|
|
$scope.reset = function() {
|
|
//initUserStorageSettings();
|
|
//$scope.instance = angular.copy(instance);
|
|
$route.reload();
|
|
};
|
|
|
|
$scope.cancel = function() {
|
|
console.log('cancel');
|
|
if ($scope.create) {
|
|
$location.url("/realms/" + realm.realm + "/user-federation");
|
|
} else {
|
|
$route.reload();
|
|
}
|
|
};
|
|
|
|
$scope.triggerFullSync = function() {
|
|
console.log('GenericCtrl: triggerFullSync');
|
|
triggerSync('triggerFullSync');
|
|
}
|
|
|
|
$scope.triggerChangedUsersSync = function() {
|
|
console.log('GenericCtrl: triggerChangedUsersSync');
|
|
triggerSync('triggerChangedUsersSync');
|
|
}
|
|
|
|
function triggerSync(action) {
|
|
UserStorageOperations.sync.save({ action: action, realm: $scope.realm.realm, componentId: $scope.instance.id }, {}, function(syncResult) {
|
|
$route.reload();
|
|
Notifications.success($translate.instant('user.storage.sync.success',{status: syncResult.status}));
|
|
}, function() {
|
|
$route.reload();
|
|
Notifications.error($translate.instant('user.storage.sync.error'));
|
|
});
|
|
}
|
|
$scope.removeImportedUsers = function() {
|
|
UserStorageOperations.removeImportedUsers.save({ realm: $scope.realm.realm, componentId: $scope.instance.id }, {}, function(syncResult) {
|
|
$route.reload();
|
|
Notifications.success($translate.instant('user.storage.remove-users.success'));
|
|
}, function() {
|
|
$route.reload();
|
|
Notifications.error($translate.instant('user.storage.remove-users.error'));
|
|
});
|
|
};
|
|
$scope.unlinkUsers = function() {
|
|
UserStorageOperations.unlinkUsers.save({ realm: $scope.realm.realm, componentId: $scope.instance.id }, {}, function(syncResult) {
|
|
$route.reload();
|
|
Notifications.success($translate.instant('user.storage.unlink.success'));
|
|
}, function() {
|
|
$route.reload();
|
|
Notifications.error($translate.instant('user.storage.unlink.error'));
|
|
});
|
|
};
|
|
|
|
});
|
|
|
|
|
|
function removeGroupMember(groups, member) {
|
|
for (var j = 0; j < groups.length; j++) {
|
|
//console.log('checking: ' + groups[j].path);
|
|
if (member.path == groups[j].path) {
|
|
groups.splice(j, 1);
|
|
break;
|
|
}
|
|
if (groups[j].subGroups && groups[j].subGroups.length > 0) {
|
|
//console.log('going into subgroups');
|
|
removeGroupMember(groups[j].subGroups, member);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.controller('UserGroupMembershipCtrl', function($scope, $q, realm, user, UserGroupMembership, UserGroupMembershipCount, UserGroupMapping, Notifications, Groups, GroupsCount, ComponentUtils, $translate) {
|
|
$scope.realm = realm;
|
|
$scope.user = user;
|
|
$scope.groupList = [];
|
|
$scope.allGroupMemberships = [];
|
|
$scope.groupMemberships = [];
|
|
$scope.tree = [];
|
|
$scope.membershipTree = [];
|
|
|
|
$scope.searchCriteria = '';
|
|
$scope.searchCriteriaMembership = '';
|
|
$scope.currentPage = 1;
|
|
$scope.currentMembershipPage = 1;
|
|
$scope.currentPageInput = $scope.currentPage;
|
|
$scope.currentMembershipPageInput = $scope.currentMembershipPage;
|
|
$scope.pageSize = 20;
|
|
$scope.numberOfPages = 1;
|
|
$scope.numberOfMembershipPages = 1;
|
|
|
|
var refreshCompleteUserGroupMembership = function() {
|
|
var queryParams = {
|
|
realm : realm.realm,
|
|
userId: user.id
|
|
};
|
|
|
|
var promiseGetCompleteUserGroupMembership = $q.defer();
|
|
UserGroupMembership.query(queryParams, function(entry) {
|
|
promiseGetCompleteUserGroupMembership.resolve(entry);
|
|
}, function() {
|
|
promiseGetCompleteUserGroupMembership.reject($translate.instant('user.groups.fetch.all.error', {params: queryParams}));
|
|
});
|
|
promiseGetCompleteUserGroupMembership.promise.then(function(groups) {
|
|
for (var i = 0; i < groups.length; i++) {
|
|
$scope.allGroupMemberships.push(groups[i]);
|
|
$scope.getGroupClass(groups[i]);
|
|
}
|
|
}, function (failed) {
|
|
Notifications.error(failed);
|
|
});
|
|
return promiseGetCompleteUserGroupMembership.promise;
|
|
};
|
|
|
|
var refreshUserGroupMembership = function (search) {
|
|
$scope.currentMembershipPageInput = $scope.currentMembershipPage;
|
|
var first = ($scope.currentMembershipPage * $scope.pageSize) - $scope.pageSize;
|
|
var queryParams = {
|
|
realm : realm.realm,
|
|
userId: user.id,
|
|
first : first,
|
|
max : $scope.pageSize
|
|
};
|
|
|
|
var countParams = {
|
|
realm : realm.realm,
|
|
userId: user.id
|
|
};
|
|
|
|
var isSearch = function() {
|
|
return angular.isDefined(search) && search !== '';
|
|
};
|
|
|
|
if (isSearch()) {
|
|
queryParams.search = search;
|
|
countParams.search = search;
|
|
}
|
|
|
|
var promiseGetUserGroupMembership = $q.defer();
|
|
UserGroupMembership.query(queryParams, function(entry) {
|
|
promiseGetUserGroupMembership.resolve(entry);
|
|
}, function() {
|
|
promiseGetUserGroupMembership.reject($translate.instant('user.groups.fetch.error', {params: queryParams}));
|
|
});
|
|
|
|
var promiseMembershipCount = $q.defer();
|
|
|
|
promiseGetUserGroupMembership.promise.then(function(groups) {
|
|
$scope.groupMemberships = groups;
|
|
UserGroupMembershipCount.query(countParams, function(entry) {
|
|
promiseMembershipCount.resolve(entry);
|
|
}, function() {
|
|
promiseMembershipCount.reject($translate.instant('user.groups.fetch.error', {params: countParams}));
|
|
});
|
|
promiseMembershipCount.promise.then(function(membershipEntry) {
|
|
if(angular.isDefined(membershipEntry.count) && membershipEntry.count > $scope.pageSize) {
|
|
$scope.numberOfMembershipPages = Math.ceil(membershipEntry.count/$scope.pageSize);
|
|
} else {
|
|
$scope.numberOfMembershipPages = 1;
|
|
}
|
|
if (parseInt($scope.currentMembershipPage, 10) > $scope.numberOfMembershipPages) {
|
|
$scope.currentMembershipPage = $scope.numberOfMembershipPages;
|
|
}
|
|
}, function (failed) {
|
|
Notifications.error(failed);
|
|
});
|
|
}, function (failed) {
|
|
Notifications.error(failed);
|
|
});
|
|
|
|
return promiseMembershipCount.promise;
|
|
};
|
|
|
|
var refreshAvailableGroups = function (search) {
|
|
$scope.currentPageInput = $scope.currentPage;
|
|
var first = ($scope.currentPage * $scope.pageSize) - $scope.pageSize;
|
|
var queryParams = {
|
|
realm : realm.realm,
|
|
first : first,
|
|
max : $scope.pageSize
|
|
};
|
|
|
|
var countParams = {
|
|
realm : realm.realm,
|
|
top : 'true'
|
|
};
|
|
|
|
if(angular.isDefined(search) && search !== '') {
|
|
queryParams.search = search;
|
|
countParams.search = search;
|
|
}
|
|
|
|
var promiseGetGroups = $q.defer();
|
|
Groups.query(queryParams, function(entry) {
|
|
promiseGetGroups.resolve(entry);
|
|
}, function() {
|
|
promiseGetGroups.reject($translate.instant('user.groups.fetch.error', {params: queryParams}));
|
|
});
|
|
|
|
var promiseCount = $q.defer();
|
|
|
|
promiseGetGroups.promise.then(function(groups) {
|
|
$scope.groupList = ComponentUtils.sortGroups('name', groups);
|
|
GroupsCount.query(countParams, function(entry) {
|
|
promiseCount.resolve(entry);
|
|
}, function() {
|
|
promiseCount.reject($translate.instant('user.groups.fetch.error', {params: countParams}));
|
|
});
|
|
promiseCount.promise.then(function(entry) {
|
|
if(angular.isDefined(entry.count) && entry.count > $scope.pageSize) {
|
|
$scope.numberOfPages = Math.ceil(entry.count/$scope.pageSize);
|
|
} else {
|
|
$scope.numberOfPages = 1;
|
|
}
|
|
}, function (failed) {
|
|
Notifications.error(failed);
|
|
});
|
|
}, function (failed) {
|
|
Notifications.error(failed);
|
|
});
|
|
|
|
return promiseCount.promise;
|
|
};
|
|
|
|
$scope.clearSearchMembership = function() {
|
|
$scope.searchCriteriaMembership = '';
|
|
if (parseInt($scope.currentMembershipPage, 10) === 1) {
|
|
refreshUserGroupMembership();
|
|
} else {
|
|
$scope.currentMembershipPage = 1;
|
|
}
|
|
};
|
|
|
|
$scope.searchGroupMembership = function() {
|
|
if (parseInt($scope.currentMembershipPage, 10) === 1) {
|
|
refreshUserGroupMembership($scope.searchCriteriaMembership);
|
|
} else {
|
|
$scope.currentMembershipPage = 1;
|
|
}
|
|
};
|
|
|
|
refreshUserGroupMembership().then(function() {
|
|
refreshAvailableGroups();
|
|
refreshCompleteUserGroupMembership();
|
|
});
|
|
|
|
$scope.$watch('currentPage', function(newValue, oldValue) {
|
|
if(parseInt(newValue, 10) !== parseInt(oldValue, 10)) {
|
|
refreshAvailableGroups($scope.searchCriteria);
|
|
}
|
|
});
|
|
|
|
$scope.$watch('currentMembershipPage', function(newValue, oldValue) {
|
|
if(parseInt(newValue, 10) !== parseInt(oldValue, 10)) {
|
|
refreshUserGroupMembership($scope.searchCriteriaMembership);
|
|
}
|
|
});
|
|
|
|
$scope.clearSearch = function() {
|
|
$scope.searchCriteria = '';
|
|
if (parseInt($scope.currentPage, 10) === 1) {
|
|
refreshAvailableGroups();
|
|
} else {
|
|
$scope.currentPage = 1;
|
|
}
|
|
};
|
|
|
|
$scope.searchGroup = function() {
|
|
if (parseInt($scope.currentPage, 10) === 1) {
|
|
refreshAvailableGroups($scope.searchCriteria);
|
|
} else {
|
|
$scope.currentPage = 1;
|
|
}
|
|
};
|
|
|
|
$scope.joinGroup = function() {
|
|
if (!$scope.tree.currentNode) {
|
|
Notifications.error($translate.instant('user.groups.join.error.no-group-selected'));
|
|
return;
|
|
}
|
|
if (isMember($scope.tree.currentNode)) {
|
|
Notifications.error($translate.instant('user.groups.join.error.already-added'));
|
|
return;
|
|
}
|
|
UserGroupMapping.update({realm: realm.realm, userId: user.id, groupId: $scope.tree.currentNode.id}, function() {
|
|
$scope.allGroupMemberships.push($scope.tree.currentNode);
|
|
refreshUserGroupMembership($scope.searchCriteriaMembership);
|
|
Notifications.success($translate.instant('user.groups.join.success'));
|
|
});
|
|
|
|
};
|
|
|
|
$scope.leaveGroup = function() {
|
|
if (!$scope.membershipTree.currentNode) {
|
|
Notifications.error($translate.instant('user.groups.leave.error.no-group-selected'));
|
|
return;
|
|
}
|
|
UserGroupMapping.remove({realm: realm.realm, userId: user.id, groupId: $scope.membershipTree.currentNode.id}, function () {
|
|
removeGroupMember($scope.allGroupMemberships, $scope.membershipTree.currentNode);
|
|
refreshUserGroupMembership($scope.searchCriteriaMembership);
|
|
Notifications.success($translate.instant('user.groups.leave.success'));
|
|
});
|
|
|
|
};
|
|
|
|
var isLeaf = function(node) {
|
|
return node.id !== 'realm' && (!node.subGroups || node.subGroups.length === 0);
|
|
};
|
|
|
|
var isMember = function(node) {
|
|
for (var i = 0; i < $scope.allGroupMemberships.length; i++) {
|
|
var member = $scope.allGroupMemberships[i];
|
|
if (node.id === member.id) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
$scope.getGroupClass = function(node) {
|
|
if (node.id == "realm") {
|
|
return 'pficon pficon-users';
|
|
}
|
|
if (isMember(node)) {
|
|
return 'normal deactivate';
|
|
}
|
|
if (isLeaf(node)) {
|
|
return 'normal';
|
|
}
|
|
if (node.subGroups.length && node.collapsed) return 'collapsed';
|
|
if (node.subGroups.length && !node.collapsed) return 'expanded';
|
|
return 'collapsed';
|
|
|
|
}
|
|
|
|
$scope.getSelectedClass = function(node) {
|
|
if (node.selected) {
|
|
if (isMember(node)) {
|
|
return "deactivate_selected";
|
|
} else {
|
|
return 'selected';
|
|
}
|
|
} else if ($scope.cutNode && $scope.cutNode.id === node.id) {
|
|
return 'cut';
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
});
|
|
|
|
module.controller('LDAPUserStorageCtrl', function($scope, $location, Notifications, $route, Dialog, realm,
|
|
serverInfo, instance, Components, UserStorageOperations,
|
|
RealmLDAPConnectionTester, $http) {
|
|
console.log('LDAPUserStorageCtrl');
|
|
var providerId = 'ldap';
|
|
console.log('providerId: ' + providerId);
|
|
$scope.create = !instance.providerId;
|
|
console.log('create: ' + $scope.create);
|
|
var providers = serverInfo.componentTypes['org.keycloak.storage.UserStorageProvider'];
|
|
console.log('providers length ' + providers.length);
|
|
var providerFactory = null;
|
|
for (var i = 0; i < providers.length; i++) {
|
|
var p = providers[i];
|
|
console.log('provider: ' + p.id);
|
|
if (p.id == providerId) {
|
|
$scope.providerFactory = p;
|
|
providerFactory = p;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
$scope.provider = instance;
|
|
$scope.showSync = false;
|
|
|
|
if (serverInfo.profileInfo.name == 'community') {
|
|
$scope.ldapVendors = [
|
|
{"id": "ad", "name": "Active Directory"},
|
|
{"id": "rhds", "name": "Red Hat Directory Server"},
|
|
{"id": "tivoli", "name": "Tivoli"},
|
|
{"id": "edirectory", "name": "Novell eDirectory"},
|
|
{"id": "other", "name": "Other"}
|
|
];
|
|
} else {
|
|
$scope.ldapVendors = [
|
|
{"id": "ad", "name": "Active Directory"},
|
|
{"id": "rhds", "name": "Red Hat Directory Server"}
|
|
];
|
|
}
|
|
|
|
$scope.authTypes = [
|
|
{ "id": "none", "name": "none" },
|
|
{ "id": "simple", "name": "simple" }
|
|
];
|
|
|
|
$scope.searchScopes = [
|
|
{ "id": "1", "name": "One Level" },
|
|
{ "id": "2", "name": "Subtree" }
|
|
];
|
|
|
|
$scope.useTruststoreOptions = [
|
|
{ "id": "always", "name": "Always" },
|
|
{ "id": "ldapsOnly", "name": "Only for ldaps" },
|
|
{ "id": "never", "name": "Never" }
|
|
];
|
|
|
|
var DEFAULT_BATCH_SIZE = "1000";
|
|
|
|
|
|
console.log("providerFactory: " + providerFactory.id);
|
|
|
|
$scope.changed = false;
|
|
function initUserStorageSettings() {
|
|
if ($scope.create) {
|
|
$scope.changed = true;
|
|
instance.name = 'ldap';
|
|
instance.providerId = 'ldap';
|
|
instance.providerType = 'org.keycloak.storage.UserStorageProvider';
|
|
instance.parentId = realm.id;
|
|
instance.config = {
|
|
|
|
};
|
|
instance.config['enabled'] = ["true"];
|
|
instance.config['priority'] = ["0"];
|
|
|
|
$scope.fullSyncEnabled = false;
|
|
$scope.changedSyncEnabled = false;
|
|
instance.config['fullSyncPeriod'] = ['-1'];
|
|
instance.config['changedSyncPeriod'] = ['-1'];
|
|
instance.config['cachePolicy'] = ['DEFAULT'];
|
|
instance.config['evictionDay'] = [''];
|
|
instance.config['evictionHour'] = [''];
|
|
instance.config['evictionMinute'] = [''];
|
|
instance.config['maxLifespan'] = [''];
|
|
instance.config['batchSizeForSync'] = [DEFAULT_BATCH_SIZE];
|
|
//instance.config['importEnabled'] = ['true'];
|
|
|
|
if (providerFactory.properties) {
|
|
|
|
for (var i = 0; i < providerFactory.properties.length; i++) {
|
|
var configProperty = providerFactory.properties[i];
|
|
if (configProperty.defaultValue) {
|
|
instance.config[configProperty.name] = [configProperty.defaultValue];
|
|
} else {
|
|
instance.config[configProperty.name] = [''];
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
} else {
|
|
$scope.changed = false;
|
|
$scope.fullSyncEnabled = (instance.config['fullSyncPeriod'] && instance.config['fullSyncPeriod'][0] > 0);
|
|
$scope.changedSyncEnabled = (instance.config['changedSyncPeriod'] && instance.config['changedSyncPeriod'][0]> 0);
|
|
if (!instance.config['fullSyncPeriod']) {
|
|
console.log('setting to -1');
|
|
instance.config['fullSyncPeriod'] = ['-1'];
|
|
|
|
}
|
|
if (!instance.config['enabled']) {
|
|
instance.config['enabled'] = ['true'];
|
|
}
|
|
if (!instance.config['changedSyncPeriod']) {
|
|
console.log('setting to -1');
|
|
instance.config['changedSyncPeriod'] = ['-1'];
|
|
|
|
}
|
|
if (!instance.config['cachePolicy']) {
|
|
instance.config['cachePolicy'] = ['DEFAULT'];
|
|
|
|
}
|
|
if (!instance.config['evictionDay']) {
|
|
instance.config['evictionDay'] = [''];
|
|
|
|
}
|
|
if (!instance.config['evictionHour']) {
|
|
instance.config['evictionHour'] = [''];
|
|
|
|
}
|
|
if (!instance.config['evictionMinute']) {
|
|
instance.config['evictionMinute'] = [''];
|
|
|
|
}
|
|
if (!instance.config['maxLifespan']) {
|
|
instance.config['maxLifespan'] = [''];
|
|
|
|
}
|
|
if (!instance.config['priority']) {
|
|
instance.config['priority'] = ['0'];
|
|
}
|
|
if (!instance.config['importEnabled']) {
|
|
instance.config['importEnabled'] = ['true'];
|
|
}
|
|
|
|
if (providerFactory.properties) {
|
|
|
|
for (var i = 0; i < providerFactory.properties.length; i++) {
|
|
var configProperty = providerFactory.properties[i];
|
|
if (!instance.config[configProperty.name]) {
|
|
if (configProperty.defaultValue) {
|
|
instance.config[configProperty.name] = [configProperty.defaultValue];
|
|
} else {
|
|
instance.config[configProperty.name] = [''];
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
for (var i=0 ; i<$scope.ldapVendors.length ; i++) {
|
|
if ($scope.ldapVendors[i].id === instance.config['vendor'][0]) {
|
|
$scope.vendorName = $scope.ldapVendors[i].name;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
}
|
|
if (instance.config && instance.config['importEnabled']) {
|
|
$scope.showSync = instance.config['importEnabled'][0] == 'true';
|
|
} else {
|
|
$scope.showSync = true;
|
|
}
|
|
|
|
$scope.lastVendor = instance.config['vendor'][0];
|
|
}
|
|
|
|
initUserStorageSettings();
|
|
$scope.instance = angular.copy(instance);
|
|
$scope.realm = realm;
|
|
|
|
$scope.$watch('instance', function() {
|
|
if (!angular.equals($scope.instance, instance)) {
|
|
$scope.changed = true;
|
|
}
|
|
|
|
if (!angular.equals($scope.instance.config['vendor'][0], $scope.lastVendor)) {
|
|
console.log("LDAP vendor changed. Previous=" + $scope.lastVendor + " New=" + $scope.instance.config['vendor'][0]);
|
|
$scope.lastVendor = $scope.instance.config['vendor'][0];
|
|
|
|
if ($scope.lastVendor === "ad") {
|
|
$scope.instance.config['usernameLDAPAttribute'][0] = "cn";
|
|
$scope.instance.config['userObjectClasses'][0] = "person, organizationalPerson, user";
|
|
} else {
|
|
$scope.instance.config['usernameLDAPAttribute'][0] = "uid";
|
|
$scope.instance.config['userObjectClasses'][0] = "inetOrgPerson, organizationalPerson";
|
|
}
|
|
|
|
$scope.instance.config['rdnLDAPAttribute'][0] = $scope.instance.config['usernameLDAPAttribute'][0];
|
|
|
|
var vendorToUUID = {
|
|
rhds: "nsuniqueid",
|
|
tivoli: "uniqueidentifier",
|
|
edirectory: "guid",
|
|
ad: "objectGUID",
|
|
other: "entryUUID"
|
|
};
|
|
$scope.instance.config['uuidLDAPAttribute'][0] = vendorToUUID[$scope.lastVendor];
|
|
}
|
|
|
|
|
|
}, true);
|
|
|
|
$scope.$watch('fullSyncEnabled', function(newVal, oldVal) {
|
|
if (oldVal == newVal) {
|
|
return;
|
|
}
|
|
|
|
$scope.instance.config['fullSyncPeriod'][0] = $scope.fullSyncEnabled ? "604800" : "-1";
|
|
$scope.changed = true;
|
|
});
|
|
|
|
$scope.$watch('changedSyncEnabled', function(newVal, oldVal) {
|
|
if (oldVal == newVal) {
|
|
return;
|
|
}
|
|
|
|
$scope.instance.config['changedSyncPeriod'][0] = $scope.changedSyncEnabled ? "86400" : "-1";
|
|
$scope.changed = true;
|
|
});
|
|
|
|
|
|
$scope.save = function() {
|
|
$scope.changed = false;
|
|
if (!$scope.instance.config['batchSizeForSync'] || !parseInt($scope.instance.config['batchSizeForSync'][0])) {
|
|
$scope.instance.config['batchSizeForSync'] = [ DEFAULT_BATCH_SIZE ];
|
|
} else {
|
|
$scope.instance.config['batchSizeForSync'][0] = parseInt($scope.instance.config.batchSizeForSync).toString();
|
|
}
|
|
|
|
if ($scope.create) {
|
|
Components.save({realm: realm.realm}, $scope.instance, function (data, headers) {
|
|
var l = headers().location;
|
|
var id = l.substring(l.lastIndexOf("/") + 1);
|
|
|
|
$location.url("/realms/" + realm.realm + "/user-storage/providers/" + $scope.instance.providerId + "/" + id);
|
|
Notifications.success("The provider has been created.");
|
|
});
|
|
} else {
|
|
Components.update({realm: realm.realm,
|
|
componentId: instance.id
|
|
},
|
|
$scope.instance, function () {
|
|
$route.reload();
|
|
Notifications.success("The provider has been updated.");
|
|
});
|
|
}
|
|
};
|
|
|
|
$scope.reset = function() {
|
|
$route.reload();
|
|
};
|
|
|
|
$scope.cancel = function() {
|
|
if ($scope.create) {
|
|
$location.url("/realms/" + realm.realm + "/user-federation");
|
|
} else {
|
|
$route.reload();
|
|
}
|
|
};
|
|
|
|
$scope.triggerFullSync = function() {
|
|
console.log('GenericCtrl: triggerFullSync');
|
|
triggerSync('triggerFullSync');
|
|
}
|
|
|
|
$scope.triggerChangedUsersSync = function() {
|
|
console.log('GenericCtrl: triggerChangedUsersSync');
|
|
triggerSync('triggerChangedUsersSync');
|
|
}
|
|
|
|
|
|
function triggerSync(action) {
|
|
UserStorageOperations.sync.save({ action: action, realm: $scope.realm.realm, componentId: $scope.instance.id }, {}, function(syncResult) {
|
|
$route.reload();
|
|
Notifications.success("Sync of users finished successfully. " + syncResult.status);
|
|
}, function() {
|
|
$route.reload();
|
|
Notifications.error("Error during sync of users");
|
|
});
|
|
}
|
|
$scope.removeImportedUsers = function() {
|
|
UserStorageOperations.removeImportedUsers.save({ realm: $scope.realm.realm, componentId: $scope.instance.id }, {}, function(syncResult) {
|
|
$route.reload();
|
|
Notifications.success("Remove imported users finished successfully. ");
|
|
}, function() {
|
|
$route.reload();
|
|
Notifications.error("Error during remove");
|
|
});
|
|
};
|
|
$scope.unlinkUsers = function() {
|
|
UserStorageOperations.unlinkUsers.save({ realm: $scope.realm.realm, componentId: $scope.instance.id }, {}, function(syncResult) {
|
|
$route.reload();
|
|
Notifications.success("Unlink of users finished successfully. ");
|
|
}, function() {
|
|
$route.reload();
|
|
Notifications.error("Error during unlink");
|
|
});
|
|
};
|
|
|
|
var initConnectionTest = function(testAction, ldapConfig) {
|
|
return {
|
|
action: testAction,
|
|
connectionUrl: ldapConfig.connectionUrl && ldapConfig.connectionUrl[0],
|
|
authType: ldapConfig.authType && ldapConfig.authType[0],
|
|
bindDn: ldapConfig.bindDn && ldapConfig.bindDn[0],
|
|
bindCredential: ldapConfig.bindCredential && ldapConfig.bindCredential[0],
|
|
useTruststoreSpi: ldapConfig.useTruststoreSpi && ldapConfig.useTruststoreSpi[0],
|
|
connectionTimeout: ldapConfig.connectionTimeout && ldapConfig.connectionTimeout[0],
|
|
startTls: ldapConfig.startTls && ldapConfig.startTls[0],
|
|
componentId: instance.id
|
|
};
|
|
};
|
|
|
|
$scope.testConnection = function() {
|
|
console.log('LDAPCtrl: testConnection');
|
|
RealmLDAPConnectionTester.save({realm: realm.realm}, initConnectionTest("testConnection", $scope.instance.config), function() {
|
|
Notifications.success("LDAP connection successful.");
|
|
}, function() {
|
|
Notifications.error("Error when trying to connect to LDAP. See server.log for details.");
|
|
});
|
|
}
|
|
|
|
$scope.testAuthentication = function() {
|
|
console.log('LDAPCtrl: testAuthentication');
|
|
RealmLDAPConnectionTester.save({realm: realm.realm}, initConnectionTest("testAuthentication", $scope.instance.config), function() {
|
|
Notifications.success("LDAP authentication successful.");
|
|
}, function() {
|
|
Notifications.error("LDAP authentication failed. See server.log for details");
|
|
});
|
|
}
|
|
|
|
$scope.queryAndSetLdapSupportedExtensions = function() {
|
|
console.log('LDAPCtrl: getLdapSupportedExtensions');
|
|
const PASSWORD_MODIFY_OID = '1.3.6.1.4.1.4203.1.11.1';
|
|
|
|
$http.post(
|
|
authUrl + '/admin/realms/' + realm.realm + '/ldap-server-capabilities',
|
|
initConnectionTest("queryServerCapabilities", $scope.instance.config)).then(
|
|
function(response) {
|
|
Notifications.success("LDAP supported extensions successfully requested.");
|
|
const ldapOids = response.data;
|
|
if (angular.isArray(ldapOids)) {
|
|
const passwordModifyOid = ldapOids.filter(function(ldapOid) { return ldapOid.oid === PASSWORD_MODIFY_OID; });
|
|
$scope.instance.config['usePasswordModifyExtendedOp'][0] = (passwordModifyOid.length > 0).toString();
|
|
}
|
|
},
|
|
function() {
|
|
Notifications.error("Error when trying to request supported extensions of LDAP. See server.log for details.");
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
module.controller('LDAPTabCtrl', function(Dialog, $scope, Current, Notifications, $location) {
|
|
$scope.removeUserFederation = function() {
|
|
Dialog.confirmDelete($scope.instance.name, 'ldap provider', function() {
|
|
$scope.instance.$remove({
|
|
realm : Current.realm.realm,
|
|
componentId : $scope.instance.id
|
|
}, function() {
|
|
$location.url("/realms/" + Current.realm.realm + "/user-federation");
|
|
Notifications.success("The provider has been deleted.");
|
|
});
|
|
});
|
|
};
|
|
});
|
|
|
|
|
|
module.controller('LDAPMapperListCtrl', function($scope, $location, Notifications, $route, Dialog, realm, provider, mappers) {
|
|
console.log('LDAPMapperListCtrl');
|
|
|
|
$scope.realm = realm;
|
|
$scope.provider = provider;
|
|
$scope.instance = provider;
|
|
|
|
$scope.mappers = mappers;
|
|
|
|
});
|
|
|
|
module.controller('LDAPMapperCtrl', function($scope, $route, realm, provider, mapperTypes, mapper, clients, Components, LDAPMapperSync, Notifications, Dialog, $location) {
|
|
console.log('LDAPMapperCtrl');
|
|
$scope.realm = realm;
|
|
$scope.provider = provider;
|
|
$scope.clients = clients;
|
|
$scope.create = false;
|
|
$scope.changed = false;
|
|
|
|
for (var i = 0; i < mapperTypes.length; i++) {
|
|
console.log('mapper.providerId: ' + mapper.providerId);
|
|
console.log('mapperTypes[i].id ' + mapperTypes[i].id);
|
|
if (mapperTypes[i].id == mapper.providerId) {
|
|
$scope.mapperType = mapperTypes[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($scope.mapperType.properties) {
|
|
|
|
for (var i = 0; i < $scope.mapperType.properties.length; i++) {
|
|
var configProperty = $scope.mapperType.properties[i];
|
|
if (!mapper.config[configProperty.name]) {
|
|
if (configProperty.defaultValue) {
|
|
mapper.config[configProperty.name] = [configProperty.defaultValue];
|
|
} else {
|
|
mapper.config[configProperty.name] = [''];
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
$scope.mapper = angular.copy(mapper);
|
|
|
|
|
|
$scope.$watch('mapper', function() {
|
|
if (!angular.equals($scope.mapper, mapper)) {
|
|
$scope.changed = true;
|
|
}
|
|
}, true);
|
|
|
|
$scope.save = function() {
|
|
Components.update({realm: realm.realm,
|
|
componentId: mapper.id
|
|
},
|
|
$scope.mapper, function () {
|
|
$route.reload();
|
|
Notifications.success("The mapper has been updated.");
|
|
});
|
|
};
|
|
|
|
$scope.reset = function() {
|
|
$scope.mapper = angular.copy(mapper);
|
|
$scope.changed = false;
|
|
};
|
|
|
|
$scope.remove = function() {
|
|
Dialog.confirmDelete($scope.mapper.name, 'ldap mapper', function() {
|
|
Components.remove({
|
|
realm : realm.realm,
|
|
componentId : mapper.id
|
|
}, function() {
|
|
$location.url("/realms/" + realm.realm + '/ldap-mappers/' + provider.id);
|
|
Notifications.success("The provider has been deleted.");
|
|
});
|
|
});
|
|
};
|
|
|
|
$scope.triggerFedToKeycloakSync = function() {
|
|
triggerMapperSync("fedToKeycloak")
|
|
}
|
|
|
|
$scope.triggerKeycloakToFedSync = function() {
|
|
triggerMapperSync("keycloakToFed");
|
|
}
|
|
|
|
function triggerMapperSync(direction) {
|
|
LDAPMapperSync.save({ direction: direction, realm: realm.realm, parentId: provider.id, mapperId : $scope.mapper.id }, {}, function(syncResult) {
|
|
Notifications.success("Data synced successfully. " + syncResult.status);
|
|
}, function(error) {
|
|
Notifications.error(error.data.errorMessage);
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
module.controller('LDAPMapperCreateCtrl', function($scope, realm, provider, mapperTypes, clients, Components, Notifications, Dialog, $location) {
|
|
console.log('LDAPMapperCreateCtrl');
|
|
$scope.realm = realm;
|
|
$scope.provider = provider;
|
|
$scope.clients = clients;
|
|
$scope.create = true;
|
|
$scope.mapper = { config: {}};
|
|
$scope.mapperTypes = mapperTypes;
|
|
$scope.mapperType = null;
|
|
$scope.changed = true;
|
|
|
|
$scope.$watch('mapperType', function() {
|
|
if ($scope.mapperType != null) {
|
|
$scope.mapper.config = {};
|
|
if ($scope.mapperType.properties) {
|
|
|
|
for (var i = 0; i < $scope.mapperType.properties.length; i++) {
|
|
var configProperty = $scope.mapperType.properties[i];
|
|
if (!$scope.mapper.config[configProperty.name]) {
|
|
if (configProperty.defaultValue) {
|
|
$scope.mapper.config[configProperty.name] = [configProperty.defaultValue];
|
|
} else {
|
|
$scope.mapper.config[configProperty.name] = [''];
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}, true);
|
|
|
|
$scope.save = function() {
|
|
if ($scope.mapperType == null) {
|
|
Notifications.error("You need to select mapper type!");
|
|
return;
|
|
}
|
|
|
|
$scope.mapper.providerId = $scope.mapperType.id;
|
|
$scope.mapper.providerType = 'org.keycloak.storage.ldap.mappers.LDAPStorageMapper';
|
|
$scope.mapper.parentId = provider.id;
|
|
|
|
if ($scope.mapper.config && $scope.mapper.config["role"] && !Array.isArray($scope.mapper.config["role"])) {
|
|
$scope.mapper.config["role"] = [$scope.mapper.config["role"]];
|
|
}
|
|
|
|
Components.save({realm: realm.realm}, $scope.mapper, function (data, headers) {
|
|
var l = headers().location;
|
|
var id = l.substring(l.lastIndexOf("/") + 1);
|
|
|
|
$location.url("/realms/" + realm.realm + "/ldap-mappers/" + $scope.mapper.parentId + "/mappers/" + id);
|
|
Notifications.success("The mapper has been created.");
|
|
});
|
|
};
|
|
|
|
$scope.reset = function() {
|
|
$location.url("/realms/" + realm.realm + '/ldap-mappers/' + provider.id);
|
|
};
|
|
|
|
|
|
});
|