<commit_before>package com.github.dbadia.sqrl.server.backchannel;

import static com.github.dbadia.sqrl.server.enums.SqrlInternalUserState.IDK_EXISTS;
import static com.github.dbadia.sqrl.server.enums.SqrlInternalUserState.NONE_EXIST;
import static com.github.dbadia.sqrl.server.enums.SqrlInternalUserState.PIDK_EXISTS;
import static com.github.dbadia.sqrl.server.enums.SqrlServerSideKey.idk;
import static com.github.dbadia.sqrl.server.enums.SqrlServerSideKey.pidk;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.dbadia.sqrl.server.SqrlPersistence;
import com.github.dbadia.sqrl.server.SqrlServerOperations;
import com.github.dbadia.sqrl.server.enums.SqrlIdentityFlag;
import com.github.dbadia.sqrl.server.enums.SqrlInternalUserState;
import com.github.dbadia.sqrl.server.enums.SqrlRequestCommand;
import com.github.dbadia.sqrl.server.enums.SqrlRequestOpt;
import com.github.dbadia.sqrl.server.exception.SqrlClientRequestProcessingException;
import com.github.dbadia.sqrl.server.exception.SqrlException;
import com.github.dbadia.sqrl.server.exception.SqrlInvalidRequestException;

public class SqrlClientRequestProcessor {
	private static final Logger logger = LoggerFactory.getLogger(SqrlServerOperations.class);

	private final SqrlClientRequest			sqrlClientRequest;
	private final String			sqrlIdk;
	private final SqrlRequestCommand	command;
	private final String			logHeader;
	private final String			correlator;
	private final SqrlPersistence	sqrlPersistence;
	private SqrlInternalUserState	sqrlInternalUserState	= NONE_EXIST;

	public SqrlClientRequestProcessor(final SqrlClientRequest sqrlClientRequest,
			final SqrlPersistence sqrlPersistence) throws SqrlInvalidRequestException {
		super();
		// Cache the logHeader since we use it a lot and it won't change here
		this.logHeader = SqrlClientRequestLoggingUtil.getLogHeader();
		this.sqrlPersistence = sqrlPersistence;
		this.sqrlClientRequest = sqrlClientRequest;
		this.sqrlIdk = sqrlClientRequest.getKey(idk);
		this.command = sqrlClientRequest.getClientCommand();
		this.correlator = sqrlClientRequest.getCorrelator();
	}

	/**
	 * Processes the request sent by a SQRL client
	 *
	 * @return true if the idk exists in persistence upon return
	 */
	public SqrlInternalUserState processClientCommand() throws SqrlException {
		sqrlInternalUserState = NONE_EXIST;

		final boolean idkExistsInPersistence = sqrlPersistence.doesSqrlIdentityExistByIdk(sqrlIdk);
		// Set IDK /PIDK Tifs
		if (idkExistsInPersistence) {
			sqrlInternalUserState = IDK_EXISTS;
		} else if (sqrlClientRequest.hasKey(pidk)
				&& sqrlPersistence.doesSqrlIdentityExistByIdk(sqrlClientRequest.getKey(pidk))) {
			sqrlInternalUserState = PIDK_EXISTS;
		}

		processCommand();
		if (command.shouldProcessOpts()) {
			processNonKeyOptions();
		}
		return sqrlInternalUserState;
	}

	private void updateOptValueAsNeeded(final SqrlIdentityFlag flag, final SqrlRequestOpt opt) {
		if (opt != null) {
			final boolean clientValue = sqrlClientRequest.getOptList().contains(opt);
			final boolean dbValue = sqrlPersistence.fetchSqrlFlagForIdentity(sqrlIdk, flag);
			if (clientValue != dbValue) { // update it
				logger.debug("{}Updating SQRL flag {} from {} to {}", logHeader, opt, dbValue,
						clientValue);
				sqrlPersistence.setSqrlFlagForIdentity(sqrlIdk, flag, clientValue);
				// TODO_AUDIT, client updated value to clientSet
			}
		}
	}

	/**
	 * Processes all SQRL opt items, except those which request previously stored keys (suk, vuk, etc)
	 */
	private void processNonKeyOptions() {
		// Create a copy so we can track which flags we have processed
		final List<SqrlRequestOpt> optList = sqrlClientRequest.getOptList();

		// Remove the key opts from the list since they are processed in SqrlServerOperations
		for (final SqrlRequestOpt keyOpt : SqrlRequestOpt.getKeyOpts()) {
			optList.remove(keyOpt);
		}

		// The absence of given flags means they should be disabled. So loop through all known flags and take the
		// appropriate action
		for (final SqrlIdentityFlag flag : SqrlIdentityFlag.values()) {
			if (flag.hasOptEquivalent()) {
				final SqrlRequestOpt opt = flag.getSqrlClientOpt();
				updateOptValueAsNeeded(flag, opt);
				// Remove the item from the list since we have processed it
				if (!optList.remove(flag.getSqrlClientOpt())) {
					logger.warn("{}Tried to remove SqrlClientOpt {} but it wasn't in list {}",
							logHeader, opt, optList);
				}
			}
		}

		// Some flags require special processing and were not handled above
		if (!optList.isEmpty()) {
			logger.warn("{}The SQRL client option(s) are not yet supported by the library: {}",
					logHeader, optList);
		}

	}

	private void processCommand() throws SqrlException {
		switch (command) {
			case QUERY:
				// Nothing to do
				return;
			case IDENT:
				processIdentCommand();
				return;<commit_msg>Removed in correct log warning<commit_after>package com.github.dbadia.sqrl.server.backchannel;

import static com.github.dbadia.sqrl.server.enums.SqrlInternalUserState.IDK_EXISTS;
import static com.github.dbadia.sqrl.server.enums.SqrlInternalUserState.NONE_EXIST;
import static com.github.dbadia.sqrl.server.enums.SqrlInternalUserState.PIDK_EXISTS;
import static com.github.dbadia.sqrl.server.enums.SqrlServerSideKey.idk;
import static com.github.dbadia.sqrl.server.enums.SqrlServerSideKey.pidk;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.dbadia.sqrl.server.SqrlPersistence;
import com.github.dbadia.sqrl.server.SqrlServerOperations;
import com.github.dbadia.sqrl.server.enums.SqrlIdentityFlag;
import com.github.dbadia.sqrl.server.enums.SqrlInternalUserState;
import com.github.dbadia.sqrl.server.enums.SqrlRequestCommand;
import com.github.dbadia.sqrl.server.enums.SqrlRequestOpt;
import com.github.dbadia.sqrl.server.exception.SqrlClientRequestProcessingException;
import com.github.dbadia.sqrl.server.exception.SqrlException;
import com.github.dbadia.sqrl.server.exception.SqrlInvalidRequestException;

public class SqrlClientRequestProcessor {
	private static final Logger logger = LoggerFactory.getLogger(SqrlServerOperations.class);

	private final SqrlClientRequest			sqrlClientRequest;
	private final String			sqrlIdk;
	private final SqrlRequestCommand	command;
	private final String			logHeader;
	private final String			correlator;
	private final SqrlPersistence	sqrlPersistence;
	private SqrlInternalUserState	sqrlInternalUserState	= NONE_EXIST;

	public SqrlClientRequestProcessor(final SqrlClientRequest sqrlClientRequest,
			final SqrlPersistence sqrlPersistence) throws SqrlInvalidRequestException {
		super();
		// Cache the logHeader since we use it a lot and it won't change here
		this.logHeader = SqrlClientRequestLoggingUtil.getLogHeader();
		this.sqrlPersistence = sqrlPersistence;
		this.sqrlClientRequest = sqrlClientRequest;
		this.sqrlIdk = sqrlClientRequest.getKey(idk);
		this.command = sqrlClientRequest.getClientCommand();
		this.correlator = sqrlClientRequest.getCorrelator();
	}

	/**
	 * Processes the request sent by a SQRL client
	 *
	 * @return true if the idk exists in persistence upon return
	 */
	public SqrlInternalUserState processClientCommand() throws SqrlException {
		sqrlInternalUserState = NONE_EXIST;

		final boolean idkExistsInPersistence = sqrlPersistence.doesSqrlIdentityExistByIdk(sqrlIdk);
		// Set IDK /PIDK Tifs
		if (idkExistsInPersistence) {
			sqrlInternalUserState = IDK_EXISTS;
		} else if (sqrlClientRequest.hasKey(pidk)
				&& sqrlPersistence.doesSqrlIdentityExistByIdk(sqrlClientRequest.getKey(pidk))) {
			sqrlInternalUserState = PIDK_EXISTS;
		}

		processCommand();
		if (command.shouldProcessOpts()) {
			processNonKeyOptions();
		}
		return sqrlInternalUserState;
	}

	private void updateOptValueAsNeeded(final SqrlIdentityFlag flag, final SqrlRequestOpt opt) {
		if (opt != null) {
			final boolean clientValue = sqrlClientRequest.getOptList().contains(opt);
			final boolean dbValue = sqrlPersistence.fetchSqrlFlagForIdentity(sqrlIdk, flag);
			if (clientValue != dbValue) { // update it
				logger.debug("{}Updating SQRL flag {} from {} to {}", logHeader, opt, dbValue,
						clientValue);
				sqrlPersistence.setSqrlFlagForIdentity(sqrlIdk, flag, clientValue);
				// TODO_AUDIT, client updated value to clientSet
			}
		}
	}

	/**
	 * Processes all SQRL opt items, except those which request previously stored keys (suk, vuk, etc)
	 */
	private void processNonKeyOptions() {
		// Create a copy so we can track which flags we have processed
		final List<SqrlRequestOpt> optList = sqrlClientRequest.getOptList();

		// Remove the key opts from the list since they are processed in SqrlServerOperations
		for (final SqrlRequestOpt keyOpt : SqrlRequestOpt.getKeyOpts()) {
			optList.remove(keyOpt);
		}

		// The absence of given flags means they should be disabled. So loop through all known flags and take the
		// appropriate action
		for (final SqrlIdentityFlag flag : SqrlIdentityFlag.values()) {
			if (flag.hasOptEquivalent()) {
				final SqrlRequestOpt opt = flag.getSqrlClientOpt();
				updateOptValueAsNeeded(flag, opt);
				// Return type of remove is irrelevant since absence of opt means disable
				optList.remove(flag.getSqrlClientOpt());
			}
		}

		// Some flags require special processing and were not handled above
		if (!optList.isEmpty()) {
			logger.warn("{}The SQRL client option(s) are not yet supported by the library: {}",
					logHeader, optList);
		}

	}

	private void processCommand() throws SqrlException {
		switch (command) {
			case QUERY:
				// Nothing to do
				return;
			case IDENT:
				processIdentCommand();
				return;
{'fraction_non_alphanumeric': 0.08704641786415797, 'fraction_numerical': 0.00041352217512664115, 'mean_word_length': 4.898780487804878, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '6991754', 'n_tokens_mistral': 3369, 'n_tokens_neox': 3098, 'n_words': 711}