content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.camel.component.undertow;
  
  import java.security.MessageDigest;
  import java.security.NoSuchAlgorithmException;
  import java.security.Principal;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.Map;
  import java.util.Set;
  
  import io.undertow.security.idm.Account;
  import io.undertow.security.idm.Credential;
  import io.undertow.security.idm.DigestCredential;
  import io.undertow.security.idm.IdentityManager;
  import io.undertow.security.idm.PasswordCredential;
  import io.undertow.util.HexConverter;
  
  import static java.nio.charset.StandardCharsets.UTF_8;
  
  class MapIdentityManager implements IdentityManager {
  
      private final Map<String, char[]> users;
  
      MapIdentityManager(final Map<String, char[]> users) {
          this.users = users;
      }
  
      @Override
      public Account verify(Account account) {
          // An existing account so for testing assume still valid.
          return account;
      }
  
      @Override
      public Account verify(String id, Credential credential) {
          Account account = getAccount(id);
          if (account != null && verifyCredential(account, credential)) {
              return account;
          }
  
          return null;
      }
  
      @Override
      public Account verify(Credential credential) {
          return null;
      }
  
      private boolean verifyCredential(Account account, Credential credential) {
          if (credential instanceof PasswordCredential) {
              char[] password = ((PasswordCredential) credential).getPassword();
              char[] expectedPassword = users.get(account.getPrincipal().getName());
  
              return Arrays.equals(password, expectedPassword);
          } else if (credential instanceof DigestCredential) {
              DigestCredential digCred = (DigestCredential) credential;
              MessageDigest digest = null;
              try {
                  digest = digCred.getAlgorithm().getMessageDigest();
  
                  digest.update(account.getPrincipal().getName().getBytes(UTF_8));
                  digest.update((byte) ':');
                  digest.update(digCred.getRealm().getBytes(UTF_8));
                  digest.update((byte) ':');
                  char[] expectedPassword = users.get(account.getPrincipal().getName());
                  digest.update(new String(expectedPassword).getBytes(UTF_8));
  
                  return digCred.verifyHA1(HexConverter.convertToHexBytes(digest.digest()));
              } catch (NoSuchAlgorithmException e) {
                  throw new IllegalStateException("Unsupported Algorithm", e);
              } finally {
                  digest.reset();
              }
          }
          return false;
      }
  
      private Account getAccount(final String id) {
          if (users.containsKey(id)) {
              return new Account() {
  
                  private static final long serialVersionUID = 1L;
                  private final Principal principal = new Principal() {
  
                      @Override
                      public String getName() {
                          return id;
                      }
                  };
  
                  @Override
                  public Principal getPrincipal() {
                      return principal;
                  }
  
                  @Override
                  public Set<String> getRoles() {
                      return Collections.emptySet();
                  }
  
              };
          }
          return null;
      }
  
  }
  