Skip to content

Commit 8a25b9a

Browse files
committed
Added support for auth proxies to selenium
Closes #1146
1 parent 5e905b1 commit 8a25b9a

File tree

3 files changed

+340
-105
lines changed

3 files changed

+340
-105
lines changed

RuriLib/Blocks/Selenium/Browser/Methods.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using OpenQA.Selenium;
1212
using System.Linq;
1313
using System.Drawing;
14+
using RuriLib.Extensions;
1415
using RuriLib.Helpers;
1516

1617
namespace RuriLib.Blocks.Selenium.Browser;
@@ -84,8 +85,7 @@ public static void SeleniumOpenBrowser(BotData data, string extraCmdLineArgs = "
8485

8586
if (data is { UseProxy: true, Proxy: not null })
8687
{
87-
// TODO: Add support for auth proxies using yove
88-
chromeop.AddArgument($"--proxy-server={data.Proxy.Type.ToString().ToLower()}://{data.Proxy.Host}:{data.Proxy.Port}");
88+
chromeop.AddProxy(data.Proxy);
8989
}
9090

9191
data.SetObject("selenium", new ChromeDriver(chromeservice, chromeop));
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
using System;
2+
using System.IO;
3+
using System.IO.Compression;
4+
using System.Text;
5+
using OpenQA.Selenium.Chrome;
6+
using RuriLib.Models.Proxies;
7+
8+
namespace RuriLib.Extensions;
9+
10+
/// <summary>
11+
/// Extensions for ChromeOptions (Selenium Driver).
12+
/// Credits: https://github.com/RDavydenko/OpenQA.Selenium.Chrome.ChromeDriverExtensions
13+
/// </summary>
14+
public static class ChromeOptionsExtensions
15+
{
16+
private const string _backgroundJs = """
17+
18+
var config = {
19+
mode: "fixed_servers",
20+
rules: {
21+
singleProxy: {
22+
scheme: "{PROTOCOL}",
23+
host: "{HOST}",
24+
port: parseInt({PORT})
25+
},
26+
bypassList: []
27+
}
28+
};
29+
30+
chrome.proxy.settings.set({ value: config, scope: "regular" }, function() { });
31+
32+
function callbackFn(details)
33+
{
34+
return {
35+
authCredentials:
36+
{
37+
username: "{USERNAME}",
38+
password: "{PASSWORD}"
39+
}
40+
};
41+
}
42+
43+
chrome.webRequest.onAuthRequired.addListener(
44+
callbackFn,
45+
46+
{ urls:["<all_urls>"] },
47+
['blocking']
48+
);
49+
""";
50+
51+
private const string _manifestJson = """
52+
53+
{
54+
"version": "1.0.0",
55+
"manifest_version": 2,
56+
"name": "Chrome Proxy",
57+
"permissions": [
58+
"proxy",
59+
"tabs",
60+
"unlimitedStorage",
61+
"storage",
62+
"<all_urls>",
63+
"webRequest",
64+
"webRequestBlocking"
65+
],
66+
"background": {
67+
"scripts": ["background.js"]
68+
},
69+
"minimum_chrome_version":"22.0.0"
70+
}
71+
""";
72+
73+
/// <summary>
74+
/// Adds a proxy to the ChromeOptions.
75+
/// </summary>
76+
public static void AddProxy(this ChromeOptions options, Proxy proxy)
77+
{
78+
if (proxy.NeedsAuthentication)
79+
{
80+
AddAuthenticatedProxy(options, proxy);
81+
}
82+
else
83+
{
84+
options.AddArgument($"--proxy-server={proxy.Protocol}://{proxy.Host}:{proxy.Port}");
85+
}
86+
}
87+
88+
private static void AddAuthenticatedProxy(ChromeOptions options, Proxy proxy)
89+
{
90+
if (!proxy.NeedsAuthentication)
91+
{
92+
throw new ArgumentException(
93+
"The proxy does not require authentication. Use the AddProxy method instead.");
94+
}
95+
96+
var backgroundProxyJs = ReplaceTemplates(_backgroundJs, proxy);
97+
var baseDir = Path.Combine(Path.GetTempPath(), "AuthProxy", Guid.NewGuid().ToString());
98+
var manifestPath = Path.Combine(baseDir, "manifest.json");
99+
var backgroundPath = Path.Combine(baseDir, "background.js");
100+
var archiveFilePath = Path.Combine(baseDir, "extension.zip");
101+
102+
// If the extension.zip file already exists, use the existing one
103+
if (File.Exists(archiveFilePath))
104+
{
105+
options.AddExtension(archiveFilePath);
106+
return;
107+
}
108+
109+
if (!Directory.Exists(baseDir))
110+
{
111+
Directory.CreateDirectory(baseDir);
112+
}
113+
114+
File.WriteAllText(manifestPath, _manifestJson);
115+
File.WriteAllText(backgroundPath, backgroundProxyJs);
116+
117+
using (var zip = ZipFile.Open(archiveFilePath, ZipArchiveMode.Create))
118+
{
119+
zip.CreateEntryFromFile(manifestPath, "manifest.json");
120+
zip.CreateEntryFromFile(backgroundPath, "background.js");
121+
}
122+
123+
File.Delete(manifestPath);
124+
File.Delete(backgroundPath);
125+
126+
options.AddExtension(archiveFilePath);
127+
}
128+
129+
private static string ReplaceTemplates(string str, Proxy proxy) =>
130+
new StringBuilder(str)
131+
.Replace("{PROTOCOL}", proxy.Protocol)
132+
.Replace("{HOST}", proxy.Host)
133+
.Replace("{PORT}", proxy.Port.ToString())
134+
.Replace("{USERNAME}", proxy.Username)
135+
.Replace("{PASSWORD}", proxy.Password)
136+
.ToString();
137+
}

0 commit comments

Comments
 (0)