<commit_before>/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2016 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed 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.wildfly.security.sasl.test;

import static org.wildfly.security.sasl.test.SaslTestUtil.obtainSaslServerFactory;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.Permissions;
import java.security.Provider;
import java.security.spec.KeySpec;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Supplier;

import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;

import org.junit.Assert;
import org.hsqldb.jdbc.JDBCDataSource;
import org.wildfly.security.auth.permission.LoginPermission;
import org.wildfly.security.auth.principal.NamePrincipal;
import org.wildfly.security.auth.realm.FileSystemSecurityRealm;
import org.wildfly.security.auth.realm.LegacyPropertiesSecurityRealm;
import org.wildfly.security.auth.realm.SimpleMapBackedSecurityRealm;
import org.wildfly.security.auth.realm.SimpleRealmEntry;
import org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm;
import org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper;
import org.wildfly.security.auth.server.MechanismConfiguration;
import org.wildfly.security.auth.server.MechanismConfigurationSelector;
import org.wildfly.security.auth.server.MechanismRealmConfiguration;
import org.wildfly.security.auth.server.ModifiableRealmIdentity;
import org.wildfly.security.auth.server.SecurityDomain;
import org.wildfly.security.auth.server.SecurityRealm;
import org.wildfly.security.auth.server.sasl.SaslAuthenticationFactory;
import org.wildfly.security.authz.Attributes;
import org.wildfly.security.credential.Credential;
import org.wildfly.security.credential.PasswordCredential;
import org.wildfly.security.password.Password;
import org.wildfly.security.password.PasswordFactory;
import org.wildfly.security.password.interfaces.BCryptPassword;
import org.wildfly.security.password.interfaces.ClearPassword;
import org.wildfly.security.password.interfaces.SaltedSimpleDigestPassword;
import org.wildfly.security.password.interfaces.ScramDigestPassword;
import org.wildfly.security.password.spec.ClearPasswordSpec;
import org.wildfly.security.password.spec.Encoding;
import org.wildfly.security.permission.PermissionVerifier;
import org.wildfly.security.sasl.WildFlySasl;
import org.wildfly.security.sasl.util.AvailableRealmsSaslServerFactory;
import org.wildfly.security.sasl.util.ChannelBindingSaslServerFactory;
import org.wildfly.security.sasl.util.CredentialSaslServerFactory;
import org.wildfly.security.sasl.util.KeyManagerCredentialSaslServerFactory;
import org.wildfly.security.sasl.util.PropertiesSaslServerFactory;
import org.wildfly.security.sasl.util.ProtocolSaslServerFactory;
import org.wildfly.security.sasl.util.SecurityProviderSaslServerFactory;
import org.wildfly.security.sasl.util.ServerNameSaslServerFactory;
import org.wildfly.security.sasl.util.TrustManagerSaslServerFactory;

/**
 * @author <NAME>
 */
public class SaslServerBuilder {
    public static final String DEFAULT_REALM_NAME = "mainRealm";

    //Server factory info
    private final Class<? extends SaslServerFactory> serverFactoryClass;
    private final String mechanismName;

    //Security domain info
    private String username;
    private Password password = <PASSWORD>;
    private String realmName = DEFAULT_REALM_NAME;
    private String defaultRealmName = realmName;
    private boolean modifiableRealm;
    private InputStream legacyInputStream;
    private boolean plainText;
    private String principalQuery;
    private JDBCDataSource dataSource;
    private String mapperAlgorithm;
    private Map<String, Permissions> permissionsMap = null;
    private Map<String, SimpleRealmEntry> passwordMap;
    private Map<String, SecurityRealm> realms = new HashMap<String, SecurityRealm>();
    private Map<String, MechanismRealmConfiguration> mechanismRealms = new LinkedHashMap<>();
    private Encoding hashEncoding = Encoding.BASE64;
    private Charset hashCharset = StandardCharsets.UTF_8;

    //Server factory decorators
    private Map<String, Object> properties;
    private Tuple<String, byte[]> bindingTypeAndData;
    private String protocol;
    private String serverName;
    private X509TrustManager trustManager;
    private X509KeyManager keyManager;
    private Credential credential;
    private boolean dontAssertBuiltServer;

    private SecurityDomain securityDomain;
    private BuilderReference<Closeable> closeableReference;
    private BuilderReference<SecurityDomain> securityDomainReference;

    private ScheduledExecutorService scheduledExecutorService;
    private Supplier<Provider[]> providerSupplier;

    public SaslServerBuilder(Class<? extends SaslServerFactory> serverFactoryClass, String mechanismName) {
        this.serverFactoryClass = serverFactoryClass;
        this.mechanismName = mechanismName;
    }

    public SaslServerBuilder copy(boolean keepDomain) {
        if (securityDomain == null && keepDomain) {
            throw new IllegalStateException("Can only copy a built server when keeping domain");
        }
        SaslServerBuilder copy = new SaslServerBuilder(serverFactoryClass, mechanismName);
        copy.username = username;
        copy.password = password;
        copy.realmName = realmName;
        copy.defaultRealmName = defaultRealmName;
        copy.modifiableRealm = modifiableRealm;
        copy.legacyInputStream = legacyInputStream;
        copy.plainText = plainText;
        copy.principalQuery = principalQuery;
        copy.dataSource = dataSource;
        copy.mapperAlgorithm = mapperAlgorithm;
        copy.hashEncoding = hashEncoding;
        copy.hashCharset = hashCharset;
        if (permissionsMap != null) {
            copy.permissionsMap = new HashMap<>(permissionsMap);
        }
        if (properties != null) {
            copy.properties = new HashMap<>(properties);
        }
        copy.bindingTypeAndData = bindingTypeAndData;
        copy.protocol = protocol;
        copy.serverName = serverName;
        copy.dontAssertBuiltServer = dontAssertBuiltServer;
        if (keepDomain) {
            copy.securityDomain = securityDomain;
        }
        return copy;
    }


    public SaslServerBuilder setUserName(String username) {
        this.username = username;
        return this;
    }

    public SaslServerBuilder setPassword(char[] password) throws Exception {
        Assert.assertNotNull(password);
        setPassword(ClearPassword.ALGORITHM_CLEAR, new ClearPasswordSpec(password));
        return this;
    }

    public SaslServerBuilder setPassword(final String algorithm, final KeySpec keySpec) throws Exception {
        Assert.assertNotNull(algorithm);
        Assert.assertNotNull(password);
        final PasswordFactory factory = providerSupplier != null ? PasswordFactory.getInstance(algorithm, providerSupplier) : PasswordFactory.getInstance(algorithm);
        return setPassword(factory.generatePassword(keySpec));
    }

    public SaslServerBuilder setPassword(Password password) {
        Assert.assertNotNull(this.password);
        this.password = password;
        return this;
    }

    public SaslServerBuilder setPasswordInstanceMap(final Map<String, Password> passwordMap) {
        Assert.assertNotNull(passwordMap);
        this.passwordMap = new HashMap<String, SimpleRealmEntry>(passwordMap.size());
        passwordMap.forEach((userName, password) -> {
            if (password == null) {
                password = <PASSWORD>;
            }
            this.passwordMap.put(userName, new SimpleRealmEntry(Collections.singletonList(new PasswordCredential(password))));
        });
        return this;
    }

    public SaslServerBuilder setPasswordMap(final Map<String, String> passwordMap) throws Exception {
        Assert.assertNotNull(passwordMap);
        this.passwordMap = new HashMap<String, SimpleRealmEntry>(passwordMap.size());
        passwordMap.forEach((userName, passwordStr) -> {
            final Password password;
            if (passwordStr == null) {
                password = <PASSWORD>;
            } else {
                try {
                    final PasswordFactory factory = PasswordFactory.getInstance(ClearPassword.ALGORITHM_CLEAR);
                    password = factory.generatePassword(new ClearPasswordSpec(passwordStr.toCharArray()));
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            Assert.assertNotNull(password);
            this.passwordMap.put(userName, new SimpleRealmEntry(Collections.singletonList(new PasswordCredential(password))));
        });
        return this;
    }

    public SaslServerBuilder setRealmName(String realmName) {
        Assert.assertNotNull(realmName);
        this.realmName = realmName;
        return this;
    }

    public SaslServerBuilder setDefaultRealmName(String realmName) {
        this.defaultRealmName = realmName;
        return this;
    }

    public SaslServerBuilder setModifiableRealm() {
        this.modifiableRealm = true;
        return this;
    }

    public SaslServerBuilder setHashEncoding(Encoding hashEncoding) {
        Assert.assertNotNull(hashEncoding);
        this.hashEncoding = hashEncoding;
        return this;
    }

    public SaslServerBuilder setHashCharset(Charset hashCharset) {
        Assert.assertNotNull(hashCharset);
        this.hashCharset = hashCharset;
        return this;
    }

    public SaslServerBuilder setLegacyInputStream(InputStream legacyInputStream) {
        Assert.assertNotNull(legacyInputStream);
        this.legacyInputStream = legacyInputStream;
        return this;
    }

    public SaslServerBuilder setPlainText(boolean plainText) {
        Assert.assertNotNull(plainText);
        this.plainText = plainText;
        return this;
    }

    public SaslServerBuilder setPrincipalQuery(String principalQuery) {
        Assert.assertNotNull(principalQuery);
        this.principalQuery = principalQuery;
        return this;
    }

    public SaslServerBuilder setDataSource(JDBCDataSource dataSource) {<commit_msg>[ELY-2399] Remove invalid assertion from SaslServerBuilder#setPlainText<commit_after>/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2016 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed 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.wildfly.security.sasl.test;

import static org.wildfly.security.sasl.test.SaslTestUtil.obtainSaslServerFactory;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.Permissions;
import java.security.Provider;
import java.security.spec.KeySpec;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Supplier;

import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;

import org.junit.Assert;
import org.hsqldb.jdbc.JDBCDataSource;
import org.wildfly.security.auth.permission.LoginPermission;
import org.wildfly.security.auth.principal.NamePrincipal;
import org.wildfly.security.auth.realm.FileSystemSecurityRealm;
import org.wildfly.security.auth.realm.LegacyPropertiesSecurityRealm;
import org.wildfly.security.auth.realm.SimpleMapBackedSecurityRealm;
import org.wildfly.security.auth.realm.SimpleRealmEntry;
import org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm;
import org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper;
import org.wildfly.security.auth.server.MechanismConfiguration;
import org.wildfly.security.auth.server.MechanismConfigurationSelector;
import org.wildfly.security.auth.server.MechanismRealmConfiguration;
import org.wildfly.security.auth.server.ModifiableRealmIdentity;
import org.wildfly.security.auth.server.SecurityDomain;
import org.wildfly.security.auth.server.SecurityRealm;
import org.wildfly.security.auth.server.sasl.SaslAuthenticationFactory;
import org.wildfly.security.authz.Attributes;
import org.wildfly.security.credential.Credential;
import org.wildfly.security.credential.PasswordCredential;
import org.wildfly.security.password.Password;
import org.wildfly.security.password.PasswordFactory;
import org.wildfly.security.password.interfaces.BCryptPassword;
import org.wildfly.security.password.interfaces.ClearPassword;
import org.wildfly.security.password.interfaces.SaltedSimpleDigestPassword;
import org.wildfly.security.password.interfaces.ScramDigestPassword;
import org.wildfly.security.password.spec.ClearPasswordSpec;
import org.wildfly.security.password.spec.Encoding;
import org.wildfly.security.permission.PermissionVerifier;
import org.wildfly.security.sasl.WildFlySasl;
import org.wildfly.security.sasl.util.AvailableRealmsSaslServerFactory;
import org.wildfly.security.sasl.util.ChannelBindingSaslServerFactory;
import org.wildfly.security.sasl.util.CredentialSaslServerFactory;
import org.wildfly.security.sasl.util.KeyManagerCredentialSaslServerFactory;
import org.wildfly.security.sasl.util.PropertiesSaslServerFactory;
import org.wildfly.security.sasl.util.ProtocolSaslServerFactory;
import org.wildfly.security.sasl.util.SecurityProviderSaslServerFactory;
import org.wildfly.security.sasl.util.ServerNameSaslServerFactory;
import org.wildfly.security.sasl.util.TrustManagerSaslServerFactory;

/**
 * @author <NAME>
 */
public class SaslServerBuilder {
    public static final String DEFAULT_REALM_NAME = "mainRealm";

    //Server factory info
    private final Class<? extends SaslServerFactory> serverFactoryClass;
    private final String mechanismName;

    //Security domain info
    private String username;
    private Password password = <PASSWORD>;
    private String realmName = DEFAULT_REALM_NAME;
    private String defaultRealmName = realmName;
    private boolean modifiableRealm;
    private InputStream legacyInputStream;
    private boolean plainText;
    private String principalQuery;
    private JDBCDataSource dataSource;
    private String mapperAlgorithm;
    private Map<String, Permissions> permissionsMap = null;
    private Map<String, SimpleRealmEntry> passwordMap;
    private Map<String, SecurityRealm> realms = new HashMap<String, SecurityRealm>();
    private Map<String, MechanismRealmConfiguration> mechanismRealms = new LinkedHashMap<>();
    private Encoding hashEncoding = Encoding.BASE64;
    private Charset hashCharset = StandardCharsets.UTF_8;

    //Server factory decorators
    private Map<String, Object> properties;
    private Tuple<String, byte[]> bindingTypeAndData;
    private String protocol;
    private String serverName;
    private X509TrustManager trustManager;
    private X509KeyManager keyManager;
    private Credential credential;
    private boolean dontAssertBuiltServer;

    private SecurityDomain securityDomain;
    private BuilderReference<Closeable> closeableReference;
    private BuilderReference<SecurityDomain> securityDomainReference;

    private ScheduledExecutorService scheduledExecutorService;
    private Supplier<Provider[]> providerSupplier;

    public SaslServerBuilder(Class<? extends SaslServerFactory> serverFactoryClass, String mechanismName) {
        this.serverFactoryClass = serverFactoryClass;
        this.mechanismName = mechanismName;
    }

    public SaslServerBuilder copy(boolean keepDomain) {
        if (securityDomain == null && keepDomain) {
            throw new IllegalStateException("Can only copy a built server when keeping domain");
        }
        SaslServerBuilder copy = new SaslServerBuilder(serverFactoryClass, mechanismName);
        copy.username = username;
        copy.password = password;
        copy.realmName = realmName;
        copy.defaultRealmName = defaultRealmName;
        copy.modifiableRealm = modifiableRealm;
        copy.legacyInputStream = legacyInputStream;
        copy.plainText = plainText;
        copy.principalQuery = principalQuery;
        copy.dataSource = dataSource;
        copy.mapperAlgorithm = mapperAlgorithm;
        copy.hashEncoding = hashEncoding;
        copy.hashCharset = hashCharset;
        if (permissionsMap != null) {
            copy.permissionsMap = new HashMap<>(permissionsMap);
        }
        if (properties != null) {
            copy.properties = new HashMap<>(properties);
        }
        copy.bindingTypeAndData = bindingTypeAndData;
        copy.protocol = protocol;
        copy.serverName = serverName;
        copy.dontAssertBuiltServer = dontAssertBuiltServer;
        if (keepDomain) {
            copy.securityDomain = securityDomain;
        }
        return copy;
    }


    public SaslServerBuilder setUserName(String username) {
        this.username = username;
        return this;
    }

    public SaslServerBuilder setPassword(char[] password) throws Exception {
        Assert.assertNotNull(password);
        setPassword(ClearPassword.ALGORITHM_CLEAR, new ClearPasswordSpec(password));
        return this;
    }

    public SaslServerBuilder setPassword(final String algorithm, final KeySpec keySpec) throws Exception {
        Assert.assertNotNull(algorithm);
        Assert.assertNotNull(password);
        final PasswordFactory factory = providerSupplier != null ? PasswordFactory.getInstance(algorithm, providerSupplier) : PasswordFactory.getInstance(algorithm);
        return setPassword(factory.generatePassword(keySpec));
    }

    public SaslServerBuilder setPassword(Password password) {
        Assert.assertNotNull(this.password);
        this.password = password;
        return this;
    }

    public SaslServerBuilder setPasswordInstanceMap(final Map<String, Password> passwordMap) {
        Assert.assertNotNull(passwordMap);
        this.passwordMap = new HashMap<String, SimpleRealmEntry>(passwordMap.size());
        passwordMap.forEach((userName, password) -> {
            if (password == null) {
                password = <PASSWORD>;
            }
            this.passwordMap.put(userName, new SimpleRealmEntry(Collections.singletonList(new PasswordCredential(password))));
        });
        return this;
    }

    public SaslServerBuilder setPasswordMap(final Map<String, String> passwordMap) throws Exception {
        Assert.assertNotNull(passwordMap);
        this.passwordMap = new HashMap<String, SimpleRealmEntry>(passwordMap.size());
        passwordMap.forEach((userName, passwordStr) -> {
            final Password password;
            if (passwordStr == null) {
                password = <PASSWORD>;
            } else {
                try {
                    final PasswordFactory factory = PasswordFactory.getInstance(ClearPassword.ALGORITHM_CLEAR);
                    password = factory.generatePassword(new ClearPasswordSpec(passwordStr.toCharArray()));
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            Assert.assertNotNull(password);
            this.passwordMap.put(userName, new SimpleRealmEntry(Collections.singletonList(new PasswordCredential(password))));
        });
        return this;
    }

    public SaslServerBuilder setRealmName(String realmName) {
        Assert.assertNotNull(realmName);
        this.realmName = realmName;
        return this;
    }

    public SaslServerBuilder setDefaultRealmName(String realmName) {
        this.defaultRealmName = realmName;
        return this;
    }

    public SaslServerBuilder setModifiableRealm() {
        this.modifiableRealm = true;
        return this;
    }

    public SaslServerBuilder setHashEncoding(Encoding hashEncoding) {
        Assert.assertNotNull(hashEncoding);
        this.hashEncoding = hashEncoding;
        return this;
    }

    public SaslServerBuilder setHashCharset(Charset hashCharset) {
        Assert.assertNotNull(hashCharset);
        this.hashCharset = hashCharset;
        return this;
    }

    public SaslServerBuilder setLegacyInputStream(InputStream legacyInputStream) {
        Assert.assertNotNull(legacyInputStream);
        this.legacyInputStream = legacyInputStream;
        return this;
    }

    public SaslServerBuilder setPlainText(boolean plainText) {
        this.plainText = plainText;
        return this;
    }

    public SaslServerBuilder setPrincipalQuery(String principalQuery) {
        Assert.assertNotNull(principalQuery);
        this.principalQuery = principalQuery;
        return this;
    }

    public SaslServerBuilder setDataSource(JDBCDataSource dataSource) {
{'fraction_non_alphanumeric': 0.08036153742896773, 'fraction_numerical': 0.002237236565394425, 'mean_word_length': 3.836615451201039, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '142613', 'n_tokens_mistral': 6132, 'n_tokens_neox': 5918, 'n_words': 1280}