<commit_before>package li.strolch.privilege.handler;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import java.util.*;

import li.strolch.privilege.base.AccessDeniedException;
import li.strolch.privilege.base.InvalidCredentialsException;
import li.strolch.privilege.model.UserState;
import li.strolch.privilege.model.internal.User;
import li.strolch.privilege.policy.PrivilegePolicy;
import li.strolch.utils.dbc.DBC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LdapPrivilegeHandler extends DefaultPrivilegeHandler {

	protected static final Logger logger = LoggerFactory.getLogger(LdapPrivilegeHandler.class);

	private Map<String, Set<String>> rolesForLdapGroups;
	private String providerUrl;
	private String searchBase;
	private String location;
	private String domain;
	private String adminUsers;

	@Override
	public synchronized void initialize(Map<String, String> parameterMap, EncryptionHandler encryptionHandler,
			PersistenceHandler persistenceHandler, UserChallengeHandler userChallengeHandler,
			SingleSignOnHandler ssoHandler, Map<String, Class<PrivilegePolicy>> policyMap) {

		rolesForLdapGroups = getLdapGroupToRolesMappingFromConfig(parameterMap);

		this.providerUrl = parameterMap.get("providerUrl");
		this.searchBase = parameterMap.get("searchBase");
		this.location = parameterMap.get("location");
		this.domain = parameterMap.get("domain");
		this.adminUsers = parameterMap.get("adminUsers");

		super.initialize(parameterMap, encryptionHandler, persistenceHandler, userChallengeHandler, ssoHandler,
				policyMap);
	}

	@Override
	protected synchronized User checkCredentialsAndUserState(String username, char[] password)
			throws InvalidCredentialsException, AccessDeniedException {

		// first see if this is a local user
		User internalUser = this.persistenceHandler.getUser(username);
		if (internalUser != null && internalUser.getUserState() != UserState.REMOTE)
			return super.checkCredentialsAndUserState(username, password);

		// Set up the environment for creating the initial context
		Hashtable<String, String> env = new Hashtable<>();

		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.PROVIDER_URL, this.providerUrl);

		// Authenticate 
		env.put(Context.SECURITY_AUTHENTICATION, "simple");
		env.put(Context.SECURITY_PRINCIPAL, username + this.domain);
		env.put(Context.SECURITY_CREDENTIALS, new String(password));

		logger.info("User {} tries to login on ldap", username + this.domain);

		String memberOfLdapString = "";
		Set<String> strolchRoles = new HashSet<>();

		// Create the initial context
		DirContext ctx = null;
		try {
			ctx = new InitialDirContext(env);

			//Create the search controls        
			SearchControls searchCtls = new SearchControls();

			//Specify the search scope
			searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

			String searchFilter =
					"(&(objectCategory=person)(objectClass=user)(userPrincipalName=" + username + this.domain + "))";

			// Search for objects using the filter
			NamingEnumeration<SearchResult> answer = ctx.search(this.searchBase, searchFilter, searchCtls);

			if (!answer.hasMore())
				throw new AccessDeniedException(
						"Could not login with user: " + username + this.domain + " on Ldap: no LDAP Data");

			SearchResult sr = (SearchResult) answer.next();
			if (answer.hasMore())
				throw new AccessDeniedException(
						"Could not login with user: " + username + this.domain + " on Ldap: Multiple LDAP Data");

			Attributes attrs = sr.getAttributes();

			Attribute sAMAccountName = attrs.get("sAMAccountName");
			if (sAMAccountName == null || !username.equals(sAMAccountName.get().toString()))
				throw new AccessDeniedException(
						"Could not login with user: " + username + this.domain + " on Ldap: Wrong LDAP Data");
<commit_msg>[Minor] if no LDAP data for userPrincipalName, then try with sAMAccountName<commit_after>package li.strolch.privilege.handler;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import java.util.*;

import li.strolch.privilege.base.AccessDeniedException;
import li.strolch.privilege.base.InvalidCredentialsException;
import li.strolch.privilege.model.UserState;
import li.strolch.privilege.model.internal.User;
import li.strolch.privilege.policy.PrivilegePolicy;
import li.strolch.utils.dbc.DBC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LdapPrivilegeHandler extends DefaultPrivilegeHandler {

	protected static final Logger logger = LoggerFactory.getLogger(LdapPrivilegeHandler.class);

	private Map<String, Set<String>> rolesForLdapGroups;
	private String providerUrl;
	private String searchBase;
	private String location;
	private String domain;
	private String adminUsers;

	@Override
	public synchronized void initialize(Map<String, String> parameterMap, EncryptionHandler encryptionHandler,
			PersistenceHandler persistenceHandler, UserChallengeHandler userChallengeHandler,
			SingleSignOnHandler ssoHandler, Map<String, Class<PrivilegePolicy>> policyMap) {

		rolesForLdapGroups = getLdapGroupToRolesMappingFromConfig(parameterMap);

		this.providerUrl = parameterMap.get("providerUrl");
		this.searchBase = parameterMap.get("searchBase");
		this.location = parameterMap.get("location");
		this.domain = parameterMap.get("domain");
		this.adminUsers = parameterMap.get("adminUsers");

		super.initialize(parameterMap, encryptionHandler, persistenceHandler, userChallengeHandler, ssoHandler,
				policyMap);
	}

	@Override
	protected synchronized User checkCredentialsAndUserState(String username, char[] password)
			throws InvalidCredentialsException, AccessDeniedException {

		// first see if this is a local user
		User internalUser = this.persistenceHandler.getUser(username);
		if (internalUser != null && internalUser.getUserState() != UserState.REMOTE)
			return super.checkCredentialsAndUserState(username, password);

		// Set up the environment for creating the initial context
		Hashtable<String, String> env = new Hashtable<>();

		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.PROVIDER_URL, this.providerUrl);

		// Authenticate 
		env.put(Context.SECURITY_AUTHENTICATION, "simple");
		env.put(Context.SECURITY_PRINCIPAL, username + this.domain);
		env.put(Context.SECURITY_CREDENTIALS, new String(password));

		logger.info("User {} tries to login on ldap", username + this.domain);

		String memberOfLdapString = "";
		Set<String> strolchRoles = new HashSet<>();

		// Create the initial context
		DirContext ctx = null;
		try {
			ctx = new InitialDirContext(env);

			//Create the search controls        
			SearchControls searchCtls = new SearchControls();

			//Specify the search scope
			searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

			String searchFilter =
					"(&(objectCategory=person)(objectClass=user)(userPrincipalName=" + username + this.domain + "))";

			// Search for objects using the filter
			NamingEnumeration<SearchResult> answer = ctx.search(this.searchBase, searchFilter, searchCtls);

			if (!answer.hasMore()) {

				logger.warn("No LDAP data retrieved using userPrincipalName, trying with sAMAccountName...");
				searchFilter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" + username + "))";
				answer = ctx.search(this.searchBase, searchFilter, searchCtls);

				if (!answer.hasMore())
					throw new AccessDeniedException("Could not login with user: " + username + this.domain
							+ " on Ldap: no LDAP Data, for either userPrincipalName or sAMAccountName");
			}

			SearchResult sr = (SearchResult) answer.next();
			if (answer.hasMore())
				throw new AccessDeniedException(
						"Could not login with user: " + username + this.domain + " on Ldap: Multiple LDAP Data");

			Attributes attrs = sr.getAttributes();

			Attribute sAMAccountName = attrs.get("sAMAccountName");
			if (sAMAccountName == null || !username.equals(sAMAccountName.get().toString()))
				throw new AccessDeniedException(
						"Could not login with user: " + username + this.domain + " on Ldap: Wrong LDAP Data");

{'fraction_non_alphanumeric': 0.10393625877036508, 'fraction_numerical': 0.00047568081817100726, 'mean_word_length': 5.313813813813814, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1093944', 'n_tokens_mistral': 2721, 'n_tokens_neox': 2457, 'n_words': 576}