@Override
 public boolean validCredentials(
     RealmModel realm, UserModel user, List<UserCredentialModel> input) {
   UserFederationProvider link = getFederationLink(realm, user);
   if (link != null) {
     validateUser(realm, user);
     Set<String> supportedCredentialTypes = link.getSupportedCredentialTypes(user);
     if (supportedCredentialTypes.size() > 0) {
       List<UserCredentialModel> fedCreds = new ArrayList<UserCredentialModel>();
       List<UserCredentialModel> localCreds = new ArrayList<UserCredentialModel>();
       for (UserCredentialModel cred : input) {
         if (supportedCredentialTypes.contains(cred.getType())) {
           fedCreds.add(cred);
         } else {
           localCreds.add(cred);
         }
       }
       if (!link.validCredentials(realm, user, fedCreds)) {
         return false;
       }
       return session.userStorage().validCredentials(realm, user, localCreds);
     }
   }
   return session.userStorage().validCredentials(realm, user, input);
 }
  /**
   * Is the user configured to use this credential type
   *
   * @return
   */
  public boolean configuredForCredentialType(String type, RealmModel realm, UserModel user) {
    UserFederationProvider link = getFederationLink(realm, user);
    if (link != null) {
      Set<String> supportedCredentialTypes = link.getSupportedCredentialTypes(user);
      if (supportedCredentialTypes.contains(type)) return true;
    }
    if (UserCredentialModel.isOtp(type)) {
      if (!user.isOtpEnabled()) return false;
    }

    List<UserCredentialValueModel> creds = user.getCredentialsDirectly();
    for (UserCredentialValueModel cred : creds) {
      if (cred.getType().equals(type)) {
        if (UserCredentialModel.isOtp(type)) {
          OTPPolicy otpPolicy = realm.getOTPPolicy();
          if (!cred.getAlgorithm().equals(otpPolicy.getAlgorithm())
              || cred.getDigits() != otpPolicy.getDigits()) {
            return false;
          }
          if (type.equals(UserCredentialModel.TOTP) && cred.getPeriod() != otpPolicy.getPeriod()) {
            return false;
          }
        }
        return true;
      }
    }
    return false;
  }
 @Override
 public void preRemove(RealmModel realm, RoleModel role) {
   for (UserFederationProviderModel federation : realm.getUserFederationProviders()) {
     UserFederationProvider fed = getFederationProvider(federation);
     fed.preRemove(realm, role);
   }
   session.userStorage().preRemove(realm, role);
 }
  protected void validateUser(RealmModel realm, UserModel user) {
    if (managedUsers.containsKey(user.getId())) {
      return;
    }

    UserFederationProvider link = getFederationLink(realm, user);
    if (link != null && !link.isValid(realm, user)) {
      deleteInvalidUser(realm, user);
      throw new IllegalStateException("Federated user no longer valid");
    }
  }
 protected UserModel registerWithFederation(RealmModel realm, UserModel user) {
   for (UserFederationProviderModel federation : realm.getUserFederationProviders()) {
     UserFederationProvider fed = getFederationProvider(federation);
     if (fed.synchronizeRegistrations()) {
       user.setFederationLink(federation.getId());
       UserModel registered = fed.register(realm, user);
       managedUsers.put(registered.getId(), registered);
       return registered;
     }
   }
   return user;
 }
 @Override
 public UserModel getUserByEmail(String email, RealmModel realm) {
   UserModel user = session.userStorage().getUserByEmail(email.toLowerCase(), realm);
   if (user != null) {
     user = validateAndProxyUser(realm, user);
     if (user != null) return user;
   }
   for (UserFederationProviderModel federation : realm.getUserFederationProviders()) {
     UserFederationProvider fed = getFederationProvider(federation);
     user = fed.getUserByEmail(realm, email);
     if (user != null) return user;
   }
   return user;
 }
  protected UserModel validateAndProxyUser(RealmModel realm, UserModel user) {
    UserModel managed = managedUsers.get(user.getId());
    if (managed != null) {
      return managed;
    }

    UserFederationProvider link = getFederationLink(realm, user);
    if (link != null) {
      UserModel validatedProxyUser = link.validateAndProxy(realm, user);
      if (validatedProxyUser != null) {
        managedUsers.put(user.getId(), validatedProxyUser);
        return validatedProxyUser;
      } else {
        deleteInvalidUser(realm, user);
        return null;
      }
    }
    return user;
  }
 @Override
 public boolean removeUser(RealmModel realm, UserModel user) {
   UserFederationProvider link = getFederationLink(realm, user);
   if (link != null) {
     boolean fedRemoved = link.removeUser(realm, user);
     if (fedRemoved) {
       boolean localRemoved = session.userStorage().removeUser(realm, user);
       managedUsers.remove(user.getId());
       if (!localRemoved) {
         logger.warn(
             "User removed from federation provider, but failed to remove him from keycloak model");
       }
       return localRemoved;
     } else {
       logger.warn("Failed to remove user from federation provider");
       return false;
     }
   }
   return session.userStorage().removeUser(realm, user);
 }
  @Override
  public CredentialValidationOutput validCredentials(
      RealmModel realm, UserCredentialModel... input) {
    List<UserFederationProviderModel> fedProviderModels = realm.getUserFederationProviders();
    List<UserFederationProvider> fedProviders = new ArrayList<UserFederationProvider>();
    for (UserFederationProviderModel fedProviderModel : fedProviderModels) {
      fedProviders.add(getFederationProvider(fedProviderModel));
    }

    CredentialValidationOutput result = null;
    for (UserCredentialModel cred : input) {
      UserFederationProvider providerSupportingCreds = null;

      // Find first provider, which supports required credential type
      for (UserFederationProvider fedProvider : fedProviders) {
        if (fedProvider.getSupportedCredentialTypes().contains(cred.getType())) {
          providerSupportingCreds = fedProvider;
          break;
        }
      }

      if (providerSupportingCreds == null) {
        logger.warn("Don't have provider supporting credentials of type " + cred.getType());
        return CredentialValidationOutput.failed();
      }

      logger.debug(
          "Found provider ["
              + providerSupportingCreds
              + "] supporting credentials of type "
              + cred.getType());
      CredentialValidationOutput currentResult =
          providerSupportingCreds.validCredentials(realm, cred);
      result = (result == null) ? currentResult : result.merge(currentResult);
    }

    // For now, validCredentials(realm, input) is not supported for local userProviders
    return (result != null) ? result : CredentialValidationOutput.failed();
  }
 void federationLoad(RealmModel realm, Map<String, String> attributes) {
   for (UserFederationProviderModel federation : realm.getUserFederationProviders()) {
     UserFederationProvider fed = getFederationProvider(federation);
     fed.searchByAttributes(attributes, realm, 30);
   }
 }