<commit_before>﻿using System;
using System.Collections.Specialized;
using System.Net.Http.Headers;
using System.Text;
using Thinktecture.IdentityServer.Core.Connect.Models;
using Thinktecture.IdentityServer.Core.Services;

namespace Thinktecture.IdentityServer.Core.Connect
{
    public class ClientValidator
    {
        private ICoreSettings _settings;
        private ILogger _logger;

        public ClientValidator(ICoreSettings settings, ILogger logger)
        {
            _settings = settings;
            _logger = logger;
        }

        public ClientCredential ValidateRequest(AuthenticationHeaderValue header, NameValueCollection body)
        {
            var credentials = ParseBasicAuthenticationScheme(header);

            if (credentials.IsPresent || credentials.IsMalformed)
            {
                return credentials;
            }

            return ParsePostBody(body);
        }

        public Client ValidateClient(ClientCredential credential)
        {
            if (credential == null || credential.ClientId == null || credential.Secret == null)
            {
                throw new InvalidOperationException("credential is null");
            }

            var client = _settings.FindClientById(credential.ClientId);
            if (client == null)
            {
                _logger.Error("Client not found in registry: " + credential.ClientId);
                return null;
            }

            if (client.ClientSecret != credential.Secret)
            {
                _logger.Error("Invalid client secret: " + client.ClientId);
                return null;
            }

            _logger.InformationFormat("Client found in registry: {0} / {1}", client.ClientId, client.ClientName);
            return client;
        }

        private ClientCredential ParseBasicAuthenticationScheme(AuthenticationHeaderValue header)
        {
            if (header == null ||
                !header.Scheme.Equals("Basic", StringComparison.OrdinalIgnoreCase))
            {
                _logger.Information("No Basic Authentication header found");

                return new ClientCredential
                {
                    IsPresent = false,
                    IsMalformed = false
                };
            }

            string pair;<commit_msg>Use ObfuscatingComparer for client secret validation<commit_after>﻿using System;
using System.Collections.Specialized;
using System.Net.Http.Headers;
using System.Text;
using Thinktecture.IdentityModel;
using Thinktecture.IdentityServer.Core.Connect.Models;
using Thinktecture.IdentityServer.Core.Services;

namespace Thinktecture.IdentityServer.Core.Connect
{
    public class ClientValidator
    {
        private ICoreSettings _settings;
        private ILogger _logger;

        public ClientValidator(ICoreSettings settings, ILogger logger)
        {
            _settings = settings;
            _logger = logger;
        }

        public ClientCredential ValidateRequest(AuthenticationHeaderValue header, NameValueCollection body)
        {
            var credentials = ParseBasicAuthenticationScheme(header);

            if (credentials.IsPresent || credentials.IsMalformed)
            {
                return credentials;
            }

            return ParsePostBody(body);
        }

        public Client ValidateClient(ClientCredential credential)
        {
            if (credential == null || credential.ClientId == null || credential.Secret == null)
            {
                throw new InvalidOperationException("credential is null");
            }

            var client = _settings.FindClientById(credential.ClientId);
            if (client == null)
            {
                _logger.Error("Client not found in registry: " + credential.ClientId);
                return null;
            }

            if (!ObfuscatingComparer.IsEqual(client.ClientSecret, credential.Secret))
            {
                _logger.Error("Invalid client secret: " + client.ClientId);
                return null;
            }

            _logger.InformationFormat("Client found in registry: {0} / {1}", client.ClientId, client.ClientName);
            return client;
        }

        private ClientCredential ParseBasicAuthenticationScheme(AuthenticationHeaderValue header)
        {
            if (header == null ||
                !header.Scheme.Equals("Basic", StringComparison.OrdinalIgnoreCase))
            {
                _logger.Information("No Basic Authentication header found");

                return new ClientCredential
                {
                    IsPresent = false,
                    IsMalformed = false
                };
            }

            string pair;
{'fraction_non_alphanumeric': 0.07503699006552526, 'fraction_numerical': 0.0008454872120059184, 'mean_word_length': 1.8941896024464833, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '5101134', 'n_tokens_mistral': 1105, 'n_tokens_neox': 1063, 'n_words': 246}