Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
mahdibland authored Oct 13, 2020
1 parent dc178b0 commit 9ab1cab
Show file tree
Hide file tree
Showing 15 changed files with 1,349 additions and 0 deletions.
25 changes: 25 additions & 0 deletions SeleniumProxyAuthentication.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30330.147
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeleniumProxyAuthentication", "SeleniumProxyAuthentication\SeleniumProxyAuthentication.csproj", "{078BD000-3E5B-4B02-AB14-68CE2A95E11C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{078BD000-3E5B-4B02-AB14-68CE2A95E11C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{078BD000-3E5B-4B02-AB14-68CE2A95E11C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{078BD000-3E5B-4B02-AB14-68CE2A95E11C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{078BD000-3E5B-4B02-AB14-68CE2A95E11C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A72D345D-C64F-4811-94BB-DC5AD52B2AA5}
EndGlobalSection
EndGlobal
4 changes: 4 additions & 0 deletions SeleniumProxyAuthentication.sln.DotSettings.user
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer&gt;&#xD;
&lt;Assembly Path="C:\Users\Mahdi Bland\source\repos\MatchChecker\MatchChecker\bin\Debug\netcoreapp3.1\Newtonsoft.Json.dll" /&gt;&#xD;
&lt;/AssemblyExplorer&gt;</s:String></wpf:ResourceDictionary>
18 changes: 18 additions & 0 deletions SeleniumProxyAuthentication/CrxManifest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Collections.Generic;

namespace SeleniumProxyAuthentication
{
public class CrxManifest
{
public string version { get; set; }
public int manifest_version { get; set; }
public string name { get; set; }
public List<string> permissions { get; set; }
public BackGround background { get; set; }
public string minimum_chrome_version { get; set; }
}
public partial class BackGround
{
public List<string> scripts { get; set; }
}
}
63 changes: 63 additions & 0 deletions SeleniumProxyAuthentication/GenerateCrx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Text.Json;

namespace SeleniumProxyAuthentication
{
internal static class GenerateCrx
{
/// <summary>
/// Convert Protocol to Scheme
/// </summary>
internal static readonly Func<ProxyProtocols, string> GetScheme = protocol =>
(protocol == ProxyProtocols.HTTP) ? "http" :
(protocol == ProxyProtocols.SOCKS4) ? "socks4" :
(protocol == ProxyProtocols.SOCKS4A) ? "socks4a" :
(protocol == ProxyProtocols.SOCKS5) ? "socks5" : String.Empty;

/// <summary>
/// Get Proxy Rule For Protocols (Always use singleProxy Not proxyforHttp)
/// </summary>
internal static readonly Func<string> GetProxyRule = () => "singleProxy";

/// <summary>
/// Get APPData Path from Machine
/// </summary>
internal static Func<string> GetAppDataPath =
() => Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

/// <summary>
/// Generate Manifest Json
/// </summary>
internal static Func<CrxManifest, string> GetManifest = crxManifest => JsonSerializer.Serialize(crxManifest);

/// <summary>
/// Generate Js Code For Crx Background
/// </summary>
internal static Func<Proxy,string> GenerateCrxCode = proxy =>
$@"
var config = {{
mode: 'fixed_servers',
rules: {{
{GetProxyRule()}: {{
scheme: '" + GetScheme(proxy.ProxyProtocol) + @"',
host: '" + proxy.Host +@"',
port: "+ proxy.Port +@"
},
bypassList:['foobar.com']
}
};
chrome.proxy.settings.set({value: config, scope: 'regular'}, function() { });
function callbackFn(details)
{
return { authCredentials: { username: '" + proxy.Credential.UserName + @"', password: '" + proxy.Credential.Password + @"' } };
}
chrome.webRequest.onAuthRequired.addListener(
callbackFn,
{urls: ['<all_urls>']},
['blocking']
);
";
}
}
42 changes: 42 additions & 0 deletions SeleniumProxyAuthentication/Proxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Net;

namespace SeleniumProxyAuthentication
{
public class Proxy
{
/// <summary>
/// Default Constructor
/// </summary>
/// <param name="proxyProtocol">Proxy Protocol</param>
/// <param name="proxy">Proxy</param>
public Proxy(ProxyProtocols proxyProtocol,string proxy)
{
this.ProxyProtocol = proxyProtocol;
var proxyDetails = proxy.Split(':');
this.Host = proxyDetails[0];
Int32.TryParse(proxyDetails[1], out int port);
this.Port = port;
if (proxyDetails.Length > 2 && proxyDetails.Length == 4)
{
this.Credential = new NetworkCredential(proxyDetails[2],proxyDetails[3]);
}
}
/// <summary>
/// Proxy Host
/// </summary>
public string Host { get; private set; }
/// <summary>
/// Proxy Port
/// </summary>
public int Port { get; private set; }
/// <summary>
/// Proxy Credential
/// </summary>
public NetworkCredential Credential { get; private set; }
/// <summary>
/// Proxy Protocol
/// </summary>
public ProxyProtocols ProxyProtocol { get; private set; }
}
}
44 changes: 44 additions & 0 deletions SeleniumProxyAuthentication/ProxyAuthentication.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.IO;
using System.Runtime.InteropServices;
using OpenQA.Selenium.Chrome;

namespace SeleniumProxyAuthentication
{
/// <summary>
/// Auth Proxy For Chrome
/// </summary>
public static class ProxyAuthentication
{
/// <summary>
/// Add Proxy With Extension To Chrome Option (Chrome Only Support Http Auth Proxies (!Didn't Test It With Socks4 Auth Proxies))
/// </summary>
/// <param name="chromeOptions"></param>
/// <param name="proxy">Your Proxy With This Format host:port or host:port:user:pass as string</param>
/// <param name="crxManifest">Edit Chrome Extension Manifest File (Leave it Empty If You Don't Want To Change It)</param>
public static void AddProxyAuthenticationExtension(this ChromeOptions chromeOptions, Proxy proxy, [Optional] CrxManifest crxManifest)
{
var cachePath = Utilities.GetCachePath();

var tempFolder = Utilities.GetTempFolder(cachePath, proxy);

var crxDetailsFolder = Utilities.GetCrxDetailsFolder(tempFolder);

var manifestLocation = Path.Combine(crxDetailsFolder, "manifest.json");
var backgroundLocation = Path.Combine(crxDetailsFolder, "background.js");

Utilities.WriteDetailsFiles(crxManifest, manifestLocation, backgroundLocation, proxy);

chromeOptions.AddExtension(Utilities.CreateExtension(tempFolder, crxDetailsFolder));
}
/// <summary>
/// Delete All Files That Made By Extensions
/// </summary>
/// <param name="chromeOptions"></param>
public static void DeleteExtensionsCache(this ChromeOptions chromeOptions)
{
var cacheFolder = Path.Combine(GenerateCrx.GetAppDataPath(), "ProxyAuthCache");
if(Directory.Exists(cacheFolder))
Directory.Delete(cacheFolder);
}
}
}
13 changes: 13 additions & 0 deletions SeleniumProxyAuthentication/ProxyProtocols.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace SeleniumProxyAuthentication
{
/// <summary>
/// Proxy Protocols Type
/// </summary>
public enum ProxyProtocols
{
HTTP,
SOCKS4,
SOCKS4A,
SOCKS5
}
}
32 changes: 32 additions & 0 deletions SeleniumProxyAuthentication/SeleniumProxyAuthentication.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<PackageId>SeleniumProxyAuthentication.Chrome</PackageId>
<Authors>MahdiBland</Authors>
<Description>Providing Support of Auth, Chain, Rotating Proxies For Selenium Chrome Driver
Support Only HTTP Proxies (Chrome Not Support Socks4&amp;5 For Now)</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageTags>Auth, Authentication, HTTP, Chain, Rotating, Proxy, Proxies, Selenium, Chrome, ChromeDriver, WebDriver, username, password</PackageTags>
<Product>Selenium Proxy Authentication</Product>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageIcon>chrome-logo.png</PackageIcon>
<RepositoryUrl>https://github.com/mahdibland/Selenium-Proxy-Authentication.Chrome</RepositoryUrl>
<PackageProjectUrl>https://github.com/mahdibland/Selenium-Proxy-Authentication.Chrome</PackageProjectUrl>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
<PackageReference Include="System.Text.Json" Version="4.7.2" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\..\..\Desktop\chrome-logo.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
106 changes: 106 additions & 0 deletions SeleniumProxyAuthentication/Utilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;

namespace SeleniumProxyAuthentication
{
internal class Utilities
{
internal static char[] NotAllowedChars = new[] {'\\', '/', '*', ':', '?', '"', '|', '<', '>'};
internal static Random rnd = new Random();

internal static Func<string, string> GetValidName = name =>
NotAllowedChars.Select(x => (name = name.Replace(x, '!'))).Last();

internal static Func<string> GetCachePath = () =>
{
var cachePath = Path.Combine(GenerateCrx.GetAppDataPath(), "ProxyAuthCache");
try{
if (!Directory.Exists(cachePath))
Directory.CreateDirectory(cachePath);
}catch{}
return cachePath;
};

internal static Func<string, Proxy, string> GetTempFolder = (path, proxy) =>
{
var currentFolder = Path.Combine(path, Utilities.GetValidName(proxy.Host + proxy.Port));
while (Directory.Exists(currentFolder))
{
currentFolder += rnd.Next(0, 1000000);
}
//Directory of .crx File
Directory.CreateDirectory(currentFolder);
return currentFolder;
};

internal static Func<string, string> GetCrxDetailsFolder = path =>
{
var detailsFolder = Path.Combine(path, "Details");
try{
if (Directory.Exists(detailsFolder))
{
Directory.Delete(detailsFolder, true);
}
}catch{}
//Directory of manifest and background files
Directory.CreateDirectory(detailsFolder);
return detailsFolder;
};

internal static Action<CrxManifest, string, string, Proxy> WriteDetailsFiles =
async (crxManifest, manifestLocation, backgroundLocation, proxy) =>
{
using (StreamWriter streamWriter = new StreamWriter(manifestLocation))
{
if (crxManifest == null)
{
await streamWriter.WriteAsync(GenerateCrx.GetManifest(new CrxManifest
{
version = "1.0.0",
manifest_version = 2,
name = "Proxy Authentication",
permissions = new List<string>
{
"proxy", "tabs", "unlimitedStorage", "storage", "<all_urls>", "webRequest",
"webRequestBlocking"
},
background = new BackGround {scripts = new List<string> {"background.js"}},
minimum_chrome_version = "24.0.0"
}));
}
else
{
await streamWriter.WriteAsync(GenerateCrx.GetManifest(new CrxManifest
{
version = crxManifest.version,
manifest_version = crxManifest.manifest_version,
name = crxManifest.name,
permissions = crxManifest.permissions,
background = crxManifest.background,
minimum_chrome_version = crxManifest.minimum_chrome_version
}));
}
}
using (StreamWriter streamWriter2 = new StreamWriter(backgroundLocation))
{
await streamWriter2.WriteAsync(GenerateCrx.GenerateCrxCode(proxy));
}
};

internal static Func<string, string, string> CreateExtension = (tempFolder, crxDetails) =>
{
var crxLocation = Path.Combine(tempFolder, "AuthChromeExtension.crx");
try{
if (File.Exists(crxLocation))
File.Delete(crxLocation);
}catch{}
ZipFile.CreateFromDirectory(crxDetails, crxLocation);
return crxLocation;
};
}
}
Binary file not shown.
Loading

0 comments on commit 9ab1cab

Please sign in to comment.