diff --git a/.gitignore b/.gitignore index 06a5ef1..0bd63e2 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ matacc.txt scripts/langmover/lang scripts/langmover/lang2 scripts/langmover/out +tinyproxy.conf diff --git a/config/config-base.json b/config/config-base.json index 93cea87..8001812 100644 --- a/config/config-base.json +++ b/config/config-base.json @@ -347,6 +347,54 @@ "type": "number", "value": 10, "description": "Duration in seconds to wait between connection retries." + }, + "proxy": { + "name": "Use Proxy", + "required": false, + "requires_restart": true, + "type": "bool", + "value": false, + "description": "Whether or not to use a HTTP/SOCKS5 Proxy." + }, + "proxy_protocol": { + "name": "Proxy Protocol", + "depends_true": "proxy", + "required": false, + "requires_restart": true, + "type": "select", + "options": [ + ["http", "HTTP"], + ["socks", "SOCKS5"] + ], + "value": "http", + "description": "Protocol to use for proxy connection." + }, + "proxy_address": { + "name": "Proxy Address", + "depends_true": "proxy", + "required": false, + "requires_restart": true, + "type": "text", + "value": "", + "description": "Proxy address, including port." + }, + "proxy_user": { + "name": "Proxy Username", + "depends_true": "proxy", + "required": false, + "requires_restart": true, + "type": "text", + "value": "", + "description": "Leave blank for no Authentication." + }, + "proxy_password": { + "name": "Proxy Password", + "depends_true": "proxy", + "required": false, + "requires_restart": true, + "type": "password", + "value": "", + "description": "Leave blank for no Authentication." } } }, diff --git a/easyproxy/easyproxy.go b/easyproxy/easyproxy.go new file mode 100644 index 0000000..b9c9bba --- /dev/null +++ b/easyproxy/easyproxy.go @@ -0,0 +1,42 @@ +// Package easyproxy provides a method to quickly create a http.Transport using given proxy details (SOCKS5 or HTTP). +package easyproxy + +import ( + "net/http" + "net/url" + + "golang.org/x/net/proxy" +) + +type Protocol int + +const ( + SOCKS5 Protocol = iota // SOCKS5 + HTTP // HTTP +) + +// NewTransport returns a http.Transport using the given proxy details. Leave user/pass blank if not needed. +func NewTransport(p Protocol, addr, user, pass string) (*http.Transport, error) { + t := &http.Transport{} + if p == HTTP { + u := &url.URL{ + Scheme: "http", + Host: addr, + } + if user != "" && pass != "" { + u.User = url.UserPassword(user, pass) + } + t.Proxy = http.ProxyURL(u) + return t, nil + } + var auth *proxy.Auth = nil + if user != "" && pass != "" { + auth = &proxy.Auth{User: user, Password: pass} + } + dialer, err := proxy.SOCKS5("tcp", addr, auth, proxy.Direct) + if err != nil { + return nil, nil + } + t.Dial = dialer.Dial + return t, nil +} diff --git a/easyproxy/go.mod b/easyproxy/go.mod new file mode 100644 index 0000000..d2c531f --- /dev/null +++ b/easyproxy/go.mod @@ -0,0 +1,5 @@ +module github.com/hrfee/jfa-go/easyproxy + +go 1.20 + +require golang.org/x/net v0.15.0 diff --git a/easyproxy/go.sum b/easyproxy/go.sum new file mode 100644 index 0000000..9746d02 --- /dev/null +++ b/easyproxy/go.sum @@ -0,0 +1,2 @@ +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= diff --git a/go.mod b/go.mod index db66fcc..c4650b4 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,8 @@ replace github.com/hrfee/jfa-go/linecache => ./linecache replace github.com/hrfee/jfa-go/api => ./api +replace github.com/hrfee/jfa-go/easyproxy => ./easyproxy + require ( github.com/bwmarrin/discordgo v0.27.1 github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a @@ -31,7 +33,7 @@ require ( github.com/hrfee/jfa-go/linecache v0.0.0-20230626224816-f72960635dc3 github.com/hrfee/jfa-go/logger v0.0.0-20230626224816-f72960635dc3 github.com/hrfee/jfa-go/ombi v0.0.0-20230626224816-f72960635dc3 - github.com/hrfee/mediabrowser v0.3.11 + github.com/hrfee/mediabrowser v0.3.12 github.com/itchyny/timefmt-go v0.1.5 github.com/lithammer/shortuuid/v3 v3.0.7 github.com/mailgun/mailgun-go/v4 v4.9.1 @@ -85,6 +87,7 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/hrfee/jfa-go/easyproxy v0.0.0-00010101000000-000000000000 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.6 // indirect @@ -116,12 +119,12 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.10.0 // indirect + golang.org/x/crypto v0.13.0 // indirect golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect golang.org/x/image v0.8.0 // indirect - golang.org/x/net v0.11.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.10.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 3e3a432..85f8f14 100644 --- a/go.sum +++ b/go.sum @@ -224,8 +224,8 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hrfee/mediabrowser v0.3.11 h1:k7sVOwYT6kUv7+lEY+vcS3bNncCycLrW/YB2nUX625E= -github.com/hrfee/mediabrowser v0.3.11/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U= +github.com/hrfee/mediabrowser v0.3.12 h1:fqDxt1be3e+ZNjAtlKc8MTqg7peo6fuGCrk2wOXo20k= +github.com/hrfee/mediabrowser v0.3.12/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= @@ -435,6 +435,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= @@ -474,6 +476,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -517,6 +521,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -528,6 +534,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/main.go b/main.go index 5af0818..45ed009 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ import ( "github.com/fatih/color" "github.com/hrfee/jfa-go/common" _ "github.com/hrfee/jfa-go/docs" + "github.com/hrfee/jfa-go/easyproxy" "github.com/hrfee/jfa-go/logger" "github.com/hrfee/jfa-go/ombi" "github.com/hrfee/mediabrowser" @@ -390,6 +391,23 @@ func start(asDaemon, firstCall bool) { if debugMode { app.jf.Verbose = true } + + if app.config.Section("advanced").Key("proxy").MustBool(false) { + // FIXME: Use Proxy + protocol := easyproxy.HTTP + if strings.Contains(app.config.Section("advanced").Key("proxy_protocol").MustString("http"), "socks") { + protocol = easyproxy.SOCKS5 + } + addr := app.config.Section("advanced").Key("proxy_address").MustString("") + user := app.config.Section("advanced").Key("proxy_user").MustString("") + password := app.config.Section("advanced").Key("proxy_password").MustString("") + transport, err := easyproxy.NewTransport(protocol, addr, user, password) + if err != nil { + app.err.Printf("Failed to initialize Proxy: %v\n", err) + } + app.jf.SetTransport(transport) + } + var status int retryOpts := mediabrowser.MustAuthenticateOptions{ RetryCount: app.config.Section("advanced").Key("auth_retry_count").MustInt(6), diff --git a/ombi/ombi.go b/ombi/ombi.go index 29a6e1c..38fa369 100644 --- a/ombi/ombi.go +++ b/ombi/ombi.go @@ -239,9 +239,9 @@ type NotificationPref struct { func (ombi *Ombi) SetNotificationPrefs(user map[string]interface{}, discordID, telegramUser string) (result string, code int, err error) { id := user["id"].(string) url := fmt.Sprintf("%s/api/v1/Identity/NotificationPreferences", ombi.server) - var data []NotificationPref + data := []NotificationPref{} if discordID != "" { - data = []NotificationPref{NotificationPref{NotifAgentDiscord, id, discordID, true}} + data = append(data, NotificationPref{NotifAgentDiscord, id, discordID, true}) } if telegramUser != "" { data = append(data, NotificationPref{NotifAgentTelegram, id, telegramUser, true})