Merge pull request #3437 from patriot1burke/master
disable credential type REST and admin ui
This commit is contained in:
commit
ccaac40863
23 changed files with 271 additions and 40 deletions
|
@ -24,6 +24,7 @@ import java.util.Arrays;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -48,6 +49,7 @@ public class UserRepresentation {
|
|||
@JsonDeserialize(using = StringListMapDeserializer.class)
|
||||
protected Map<String, List<String>> attributes;
|
||||
protected List<CredentialRepresentation> credentials;
|
||||
protected Set<String> disableableCredentialTypes;
|
||||
protected List<String> requiredActions;
|
||||
protected List<FederatedIdentityRepresentation> federatedIdentities;
|
||||
protected List<String> realmRoles;
|
||||
|
@ -254,4 +256,12 @@ public class UserRepresentation {
|
|||
public void setOrigin(String origin) {
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
public Set<String> getDisableableCredentialTypes() {
|
||||
return disableableCredentialTypes;
|
||||
}
|
||||
|
||||
public void setDisableableCredentialTypes(Set<String> disableableCredentialTypes) {
|
||||
this.disableableCredentialTypes = disableableCredentialTypes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,10 @@ import org.keycloak.models.UserModel;
|
|||
import org.keycloak.models.cache.CachedUserModel;
|
||||
import org.keycloak.models.cache.OnUserCache;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -82,11 +85,23 @@ public class SecretQuestionCredentialProvider implements CredentialProvider, Cre
|
|||
@Override
|
||||
public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) {
|
||||
if (!SECRET_QUESTION.equals(credentialType)) return;
|
||||
session.userCredentialManager().disableCredential(realm, user, credentialType);
|
||||
session.userCredentialManager().disableCredentialType(realm, user, credentialType);
|
||||
session.getUserCache().evict(realm, user);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
if (!session.userCredentialManager().getStoredCredentialsByType(realm, user, SECRET_QUESTION).isEmpty()) {
|
||||
Set<String> set = new HashSet<>();
|
||||
set.add(SECRET_QUESTION);
|
||||
return set;
|
||||
} else {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCredentialType(String credentialType) {
|
||||
return SECRET_QUESTION.equals(credentialType);
|
||||
|
|
|
@ -23,7 +23,9 @@ import org.keycloak.models.RealmModel;
|
|||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -90,4 +92,9 @@ public class ClasspathPropertiesFederationProvider extends BasePropertiesFederat
|
|||
public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@ import org.keycloak.models.UserModel;
|
|||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -108,4 +110,9 @@ public class FilePropertiesFederationProvider extends BasePropertiesFederationPr
|
|||
public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,9 +44,11 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -199,6 +201,17 @@ public class EjbExampleUserStorageProvider implements UserStorageProvider,
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
if (getUserAdapter(user).getPassword() != null) {
|
||||
Set<String> set = new HashSet<>();
|
||||
set.add(CredentialModel.PASSWORD);
|
||||
return set;
|
||||
} else {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType) {
|
||||
return supportsCredentialType(credentialType) && getPassword(user) != null;
|
||||
|
|
|
@ -164,6 +164,11 @@ public class KerberosFederationProvider implements UserFederationProvider {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCredentialType(String credentialType) {
|
||||
return credentialType.equals(CredentialModel.KERBEROS) || (kerberosConfig.isAllowPasswordAuthentication() && credentialType.equals(CredentialModel.PASSWORD));
|
||||
|
|
|
@ -424,6 +424,11 @@ public class LDAPFederationProvider implements UserFederationProvider {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCredentialType(String credentialType) {
|
||||
return getSupportedCredentialTypes().contains(credentialType);
|
||||
|
|
|
@ -180,6 +180,11 @@ public class SSSDFederationProvider implements UserFederationProvider {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCredentialType(String credentialType) {
|
||||
return CredentialModel.PASSWORD.equals(credentialType);
|
||||
|
|
|
@ -19,6 +19,9 @@ package org.keycloak.credential;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
@ -27,4 +30,14 @@ public interface CredentialInputUpdater {
|
|||
boolean supportsCredentialType(String credentialType);
|
||||
boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input);
|
||||
void disableCredentialType(RealmModel realm, UserModel user, String credentialType);
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns a set of credential types that can be disabled by disableCredentialType() method
|
||||
*
|
||||
* @param realm
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ package org.keycloak.credential;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.keycloak.credential.CredentialInput;
|
|||
import org.keycloak.credential.UserCredentialStore;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -67,7 +68,16 @@ public interface UserCredentialManager extends UserCredentialStore {
|
|||
* @param user
|
||||
* @param credentialType
|
||||
*/
|
||||
void disableCredential(RealmModel realm, UserModel user, String credentialType);
|
||||
void disableCredentialType(RealmModel realm, UserModel user, String credentialType);
|
||||
|
||||
/**
|
||||
* Returns a set of credential types that can be disabled by disableCredentialType() method
|
||||
*
|
||||
* @param realm
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user);
|
||||
|
||||
/**
|
||||
* Checks to see if user has credential type configured. Looks in UserStorageProvider or UserFederationProvider first,
|
||||
|
@ -82,7 +92,8 @@ public interface UserCredentialManager extends UserCredentialStore {
|
|||
|
||||
/**
|
||||
* Only loops through each CredentialProvider to see if credential type is configured for the user.
|
||||
* This allows UserStorageProvider and UserFederationProvider to look to abort isValid
|
||||
* This allows UserStorageProvider and UserFederationProvider isValid() implementations to punt to local storage
|
||||
* when validating a credential that has been overriden in Keycloak storage.
|
||||
*
|
||||
* @param realm
|
||||
* @param user
|
||||
|
|
|
@ -189,6 +189,7 @@ public class ModelToRepresentation {
|
|||
rep.setEnabled(user.isEnabled());
|
||||
rep.setEmailVerified(user.isEmailVerified());
|
||||
rep.setTotp(session.userCredentialManager().isConfiguredFor(realm, user, CredentialModel.OTP));
|
||||
rep.setDisableableCredentialTypes(session.userCredentialManager().getDisableableCredentialTypes(realm, user));
|
||||
rep.setFederationLink(user.getFederationLink());
|
||||
|
||||
List<String> reqActions = new ArrayList<String>();
|
||||
|
|
|
@ -29,7 +29,9 @@ import org.keycloak.models.utils.HmacOTP;
|
|||
import org.keycloak.models.utils.TimeBasedOTP;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -139,6 +141,19 @@ public class OTPCredentialProvider implements CredentialProvider, CredentialInpu
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
if (!getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.HOTP).isEmpty()
|
||||
|| !getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP).isEmpty()) {
|
||||
Set<String> set = new HashSet<>();
|
||||
set.add(CredentialModel.OTP);
|
||||
return set;
|
||||
} else {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsCredentialType(String credentialType) {
|
||||
return CredentialModel.OTP.equals(credentialType)
|
||||
|
|
|
@ -33,8 +33,10 @@ import org.keycloak.policy.PolicyError;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -150,6 +152,17 @@ public class PasswordCredentialProvider implements CredentialProvider, Credentia
|
|||
expirePassword(realm, user, policy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
if (!getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.PASSWORD).isEmpty()) {
|
||||
Set<String> set = new HashSet<>();
|
||||
set.add(CredentialModel.PASSWORD);
|
||||
return set;
|
||||
} else {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCredentialType(String credentialType) {
|
||||
return credentialType.equals(CredentialModel.PASSWORD);
|
||||
|
|
|
@ -35,9 +35,11 @@ import org.keycloak.storage.UserStorageProvider;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -196,7 +198,7 @@ public class UserCredentialStoreManager implements UserCredentialManager, OnUser
|
|||
}
|
||||
}
|
||||
@Override
|
||||
public void disableCredential(RealmModel realm, UserModel user, String credentialType) {
|
||||
public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) {
|
||||
if (!StorageId.isLocalStorage(user)) {
|
||||
String providerId = StorageId.resolveProviderId(user);
|
||||
UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, providerId);
|
||||
|
@ -229,6 +231,38 @@ public class UserCredentialStoreManager implements UserCredentialManager, OnUser
|
|||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
Set<String> types = new HashSet<>();
|
||||
if (!StorageId.isLocalStorage(user)) {
|
||||
String providerId = StorageId.resolveProviderId(user);
|
||||
UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, providerId);
|
||||
if (provider instanceof CredentialInputUpdater) {
|
||||
CredentialInputUpdater updater = (CredentialInputUpdater)provider;
|
||||
types.addAll(updater.getDisableableCredentialTypes(realm, user));
|
||||
}
|
||||
} else {
|
||||
UserFederationProvider link = session.users().getFederationLink(realm, user);
|
||||
if (link != null) {
|
||||
types.addAll(link.getDisableableCredentialTypes(realm, user));
|
||||
}
|
||||
else if (user.getFederationLink() != null) {
|
||||
UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, user.getFederationLink());
|
||||
if (provider != null && provider instanceof CredentialInputUpdater) {
|
||||
types.addAll(((CredentialInputUpdater)provider).getDisableableCredentialTypes(realm, user));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
List<CredentialInputUpdater> credentialProviders = getCredentialProviders(realm, CredentialInputUpdater.class);
|
||||
for (CredentialInputUpdater updater : credentialProviders) {
|
||||
types.addAll(updater.getDisableableCredentialTypes(realm, user));
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfiguredFor(RealmModel realm, UserModel user, String type) {
|
||||
if (!StorageId.isLocalStorage(user)) {
|
||||
|
|
|
@ -440,7 +440,7 @@ public class AccountService extends AbstractSecuredLocalService {
|
|||
csrfCheck(stateChecker);
|
||||
|
||||
UserModel user = auth.getUser();
|
||||
session.userCredentialManager().disableCredential(realm, user, CredentialModel.OTP);
|
||||
session.userCredentialManager().disableCredentialType(realm, user, CredentialModel.OTP);
|
||||
|
||||
event.event(EventType.REMOVE_TOTP).client(auth.getClient()).user(auth.getUser()).success();
|
||||
|
||||
|
|
|
@ -719,7 +719,32 @@ public class UsersResource {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Disable all credentials for a user of a specific type
|
||||
*
|
||||
* @param id
|
||||
* @param credentialTypes
|
||||
*/
|
||||
@Path("{id}/disable-credential-types")
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public void disableCredentialType(@PathParam("id") String id, List<String> credentialTypes) {
|
||||
auth.requireManage();
|
||||
|
||||
UserModel user = session.users().getUserById(id, realm);
|
||||
if (user == null) {
|
||||
throw new NotFoundException("User not found");
|
||||
}
|
||||
if (credentialTypes == null) return;
|
||||
for (String type : credentialTypes) {
|
||||
session.userCredentialManager().disableCredentialType(realm, user, type);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up a temporary password for the user
|
||||
*
|
||||
* User will have to reset the temporary password next time they log in.
|
||||
|
@ -777,7 +802,7 @@ public class UsersResource {
|
|||
throw new NotFoundException("User not found");
|
||||
}
|
||||
|
||||
session.userCredentialManager().disableCredential(realm, user, CredentialModel.OTP);
|
||||
session.userCredentialManager().disableCredentialType(realm, user, CredentialModel.OTP);
|
||||
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,11 @@ public class DummyUserFederationProvider implements UserFederationProvider {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCredentialType(String credentialType) {
|
||||
return getSupportedCredentialTypes().contains(credentialType);
|
||||
|
|
|
@ -33,7 +33,9 @@ import org.keycloak.storage.adapter.AbstractUserAdapterFederatedStorage;
|
|||
import org.keycloak.storage.user.UserLookupProvider;
|
||||
import org.keycloak.storage.user.UserRegistrationProvider;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
|
@ -103,6 +105,11 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType) {
|
||||
return CredentialModel.PASSWORD.equals(credentialType);
|
||||
|
|
|
@ -1206,4 +1206,16 @@ userStorage.cachePolicy.maxLifespan=Max Lifespan
|
|||
userStorage.cachePolicy.maxLifespan.tooltip=Max lifespan of a user cache entry in milliseconds.
|
||||
user-origin-link=Storage Origin
|
||||
|
||||
disable=Disable
|
||||
disableable-credential-types=Disableable Types
|
||||
credentials.disableable.tooltip=List of credential types that you can disable
|
||||
disable-credential-types=Disable Credential Types
|
||||
credentials.disable.tooltip=Click button to disable selected credential types
|
||||
credential-types=Credential Types
|
||||
manage-user-password=Manage Password
|
||||
disable-credentials=Disable Credentials
|
||||
credential-reset-actions=Credential Reset
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -501,7 +501,7 @@ module.controller('UserDetailCtrl', function($scope, realm, user, BruteForceUser
|
|||
}
|
||||
});
|
||||
|
||||
module.controller('UserCredentialsCtrl', function($scope, realm, user, RequiredActions, User, UserExecuteActionsEmail, UserCredentials, Notifications, Dialog) {
|
||||
module.controller('UserCredentialsCtrl', function($scope, realm, user, $route, RequiredActions, User, UserExecuteActionsEmail, UserCredentials, Notifications, Dialog) {
|
||||
console.log('UserCredentialsCtrl');
|
||||
|
||||
$scope.realm = realm;
|
||||
|
@ -554,18 +554,19 @@ module.controller('UserCredentialsCtrl', function($scope, realm, user, RequiredA
|
|||
});
|
||||
};
|
||||
|
||||
$scope.removeTotp = function() {
|
||||
Dialog.confirm('Remove totp', 'Are you sure you want to remove the users totp configuration?', function() {
|
||||
UserCredentials.removeTotp({ realm: realm.realm, userId: user.id }, { }, function() {
|
||||
Notifications.success("The users totp configuration has been removed");
|
||||
$scope.user.totp = false;
|
||||
$scope.disableCredentialTypes = function() {
|
||||
Dialog.confirm('Disable credentials', 'Are you sure you want to disable these the users credentials?', function() {
|
||||
UserCredentials.disableCredentialTypes({ realm: realm.realm, userId: user.id }, $scope.disableableCredentialTypes, function() {
|
||||
$route.reload();
|
||||
Notifications.success("Credentials disabled");
|
||||
}, function() {
|
||||
Notifications.error("Failed to remove the users totp configuration");
|
||||
Notifications.error("Failed to disable credentials");
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.emailActions = [];
|
||||
$scope.disableableCredentialTypes = [];
|
||||
|
||||
$scope.sendExecuteActionsEmail = function() {
|
||||
if ($scope.changed) {
|
||||
|
|
|
@ -531,6 +531,15 @@ module.factory('UserCredentials', function($resource) {
|
|||
}
|
||||
}).update;
|
||||
|
||||
credentials.disableCredentialTypes = $resource(authUrl + '/admin/realms/:realm/users/:userId/disable-credential-types', {
|
||||
realm : '@realm',
|
||||
userId : '@userId'
|
||||
}, {
|
||||
update : {
|
||||
method : 'PUT'
|
||||
}
|
||||
}).update;
|
||||
|
||||
return credentials;
|
||||
});
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
<input type="password" readonly value="this is not a login form" style="display: none;">
|
||||
|
||||
<fieldset class="border-top">
|
||||
<div class="form-group">
|
||||
<legend><span class="text">{{:: 'manage-user-password' | translate}}</span></legend>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="password">{{:: 'new-password' | translate}} <span class="required" data-ng-show="create">*</span></label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="password" id="password" name="password" data-ng-model="password" required>
|
||||
|
@ -40,35 +41,50 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="border-top" data-ng-show="user.totp">
|
||||
<div class="form-group" data-ng-show="user.totp">
|
||||
<label class="col-md-2 control-label">{{:: 'remove-totp' | translate}}</label>
|
||||
<div class="col-sm-5" data-ng-show="user.totp">
|
||||
<button class="btn btn-danger" type="submit" data-ng-click="removeTotp()" tooltip-trigger="mouseover mouseout" tooltip="{{:: 'credentials.remove-totp.tooltip' | translate}}" tooltip-placement="right">{{:: 'remove-totp' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset >
|
||||
<fieldset class="border-top" data-ng-show="user.email">
|
||||
<div class="form-group clearfix">
|
||||
<label class="col-md-2 control-label" for="reqActions">{{:: 'reset-actions' | translate}}</label>
|
||||
<fieldset class="border-top" data-ng-show="user.disableableCredentialTypes && user.disableableCredentialTypes.length > 0">
|
||||
<legend><span class="text">{{:: 'disable-credentials' | translate}}</span></legend>
|
||||
<div class="form-group clearfix">
|
||||
<label class="col-md-2 control-label" for="credentialTypeList">{{:: 'disableable-credential-types' | translate}}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<select ui-select2 id="reqActions" ng-model="emailActions" data-placeholder="{{:: 'select-an-action.placeholder' | translate}}" multiple>
|
||||
<option ng-repeat="action in userReqActionList" value="{{action.alias}}">{{action.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'credentials.reset-actions.tooltip' | translate}}</kc-tooltip>
|
||||
<div class="col-md-6">
|
||||
<select ui-select2 id="credentialTypeList" ng-model="disableableCredentialTypes" data-placeholder="{{:: 'select-a-type.placeholder' | translate}}" multiple>
|
||||
<option ng-repeat="credType in user.disableableCredentialTypes" value="{{credType}}">{{credType}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group clearfix">
|
||||
<label class="col-md-2 control-label" for="reqActionsEmail">{{:: 'reset-actions-email' | translate}}</label>
|
||||
<kc-tooltip>{{:: 'credentials.disableable.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group clearfix">
|
||||
<label class="col-md-2 control-label" for="disableCredentialTypes">{{:: 'disable-credential-types' | translate}}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<button id="reqActionsEmail" class="btn btn-default" data-ng-click="sendExecuteActionsEmail()">{{:: 'send-email' | translate}}</button>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'credentials.reset-actions-email.tooltip' | translate}}</kc-tooltip>
|
||||
<div class="col-md-6">
|
||||
<button id="disableCredentialTypes" class="btn btn-default" data-ng-click="disableCredentialTypes()">{{:: 'disable' | translate}}</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<kc-tooltip>{{:: 'credentials.disable.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="border-top" data-ng-show="user.email">
|
||||
<legend><span class="text">{{:: 'credential-reset-actions' | translate}}</span></legend>
|
||||
<div class="form-group clearfix">
|
||||
<label class="col-md-2 control-label" for="reqActions">{{:: 'reset-actions' | translate}}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<select ui-select2 id="reqActions" ng-model="emailActions" data-placeholder="{{:: 'select-an-action.placeholder' | translate}}" multiple>
|
||||
<option ng-repeat="action in userReqActionList" value="{{action.alias}}">{{action.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'credentials.reset-actions.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group clearfix">
|
||||
<label class="col-md-2 control-label" for="reqActionsEmail">{{:: 'reset-actions-email' | translate}}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<button id="reqActionsEmail" class="btn btn-default" data-ng-click="sendExecuteActionsEmail()">{{:: 'send-email' | translate}}</button>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'credentials.reset-actions-email.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<kc-menu></kc-menu>
|
||||
|
|
Loading…
Reference in a new issue