001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.shiro.crypto.hash;
020
021import org.apache.shiro.lang.util.ByteSource;
022
023import java.util.Map;
024import java.util.Optional;
025import java.util.concurrent.ConcurrentHashMap;
026
027import static java.util.Collections.unmodifiableMap;
028import static java.util.Objects.requireNonNull;
029
030/**
031 * Simple implementation of {@link HashRequest} that can be used when interacting with a {@link HashService}.
032 *
033 * @since 1.2
034 */
035public class SimpleHashRequest implements HashRequest {
036
037    /**
038     * cannot be null - this is the source to hash.
039     */
040    private final ByteSource source;
041    /**
042     * can be null = no salt specified
043     */
044    private final ByteSource salt;
045    /**
046     * can be null = let the HashService decide.
047     */
048    private final String algorithmName;
049    private final Map<String, Object> parameters = new ConcurrentHashMap<>();
050
051    /**
052     * Creates a new SimpleHashRequest instance.
053     *
054     * @param algorithmName the name of the hash algorithm to use.  This is often null as the
055     *                      {@link HashService} implementation is usually configured with an
056     *                      appropriate algorithm name, but this can be non-null
057     *                      if the hash service's algorithm should be overridden with a
058     *                      specific one for the duration of the request.
059     * @param source        the source to be hashed
060     * @param salt          any public salt which should be used when computing the hash
061     * @param parameters    e.g. the number of hash iterations to execute or other parameters.
062     * @throws NullPointerException if {@code source} is null or empty or {@code parameters} is {@code null}.
063     */
064    public SimpleHashRequest(String algorithmName, ByteSource source, ByteSource salt, Map<String, Object> parameters) {
065        this.source = requireNonNull(source);
066        this.salt = salt;
067        this.algorithmName = algorithmName;
068        this.parameters.putAll(requireNonNull(parameters));
069    }
070
071    @Override
072    public ByteSource getSource() {
073        return this.source;
074    }
075
076    @Override
077    public Optional<ByteSource> getSalt() {
078        return Optional.ofNullable(this.salt);
079    }
080
081
082    @Override
083    public Optional<String> getAlgorithmName() {
084        return Optional.ofNullable(algorithmName);
085    }
086
087    @Override
088    public Map<String, Object> getParameters() {
089        return unmodifiableMap(this.parameters);
090    }
091}