Compare commits

...

8 Commits
v0.1 ... master

12 changed files with 423 additions and 251 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.idea/
*.swp
*.save

358
README.md
View File

@ -2,11 +2,43 @@
[![GoDoc](https://godoc.org/git.tcp.direct/kayos/proxygonanza?status.svg)](https://godoc.org/git.tcp.direct/kayos/proxygonanza)
[![Go Report Card](https://goreportcard.com/badge/github.com/yunginnanet/proxygonanza)](https://goreportcard.com/report/github.com/yunginnanet/proxygonanza)
--
# Table of Contents
1. [ProxyGonanza](#proxygonanza)
1. [Import Path](#import-path)
1. [Constants and Variables](#constants-and-variables)
1. [API Types](#api-types)
1. [type AddAuthIPResponse](#type-addauthipresponse)
1. [type AuthIP](#type-authip)
1. [type AuthIPResponse](#type-authipresponse)
1. [type DelAuthIPResponse](#type-delauthipresponse)
1. [type Package](#type-package)
1. [type PackageDetails](#type-packagedetails)
1. [type PackageResponse](#type-packageresponse)
1. [type PackageStatistics](#type-packagestatistics)
1. [type UserPackage](#type-userpackage)
1. [Client](#client)
1. [type APIClient](#type-apiclient)
1. [Constructors](#constructors)
1. [func NewAPIClient](#func--newapiclient)
1. [func NewCustomClient](#func--newcustomclient)
1. [Methods](#methods)
1. [func (*APIClient) AddAuthIP](#func-apiclient-addauthip)
1. [func (*APIClient) AddCurrentIPtoAllPackages](#func-apiclient-addcurrentiptoallpackages)
1. [func (*APIClient) DeleteAllAuthIPs](#func-apiclient-deleteallauthips)
1. [func (*APIClient) DeleteAuthIPByID](#func-apiclient-deleteauthipbyid)
1. [func (*APIClient) DeleteAuthIPByIP](#func-apiclient-deleteauthipbyip)
1. [func (*APIClient) DeleteOtherAuthIPs](#func-apiclient-deleteotherauthips)
1. [func (*APIClient) GetAllSOCKSIPsAndPorts](#func-apiclient-getallsocksipsandports)
1. [func (*APIClient) GetAuthIPs](#func-apiclient-getauthips)
1. [func (*APIClient) GetPackageSOCKS](#func-apiclient-getpackagesocks)
1. [func (*APIClient) GetProxyPackages](#func-apiclient-getproxypackages)
## Import Path
`import "git.tcp.direct/kayos/proxygonanza"`
## Documentation
## Constants and Variables
```go
const (
@ -14,29 +46,176 @@ const (
)
```
#### func GetMyIP
## API Types
### type AddAuthIPResponse
```go
func GetMyIP() net.IP
type AddAuthIPResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Data struct {
ID int `json:"id"`
} `json:"data"`
}
```
#### type APIClient
AddAuthIPResponse represents an API response from proxybonanza.com.
### type AuthIP
```go
type AuthIP struct {
UserpackageID int `json:"userpackage_id"`
ID interface{} `json:"id"`
IP string `json:"ip"`
}
```
AuthIP is an IP address authorized to use the proxies in the related package.
### type AuthIPResponse
```go
type AuthIPResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
AuthIPData []AuthIP `json:"data"`
Pages pagination `json:"pagination"`
}
```
AuthIPResponse represents an API response from proxybonanza.com.
### type DelAuthIPResponse
```go
type DelAuthIPResponse struct {
Success bool `json:"success"`
}
```
DelAuthIPResponse represents an API response from proxybonanza.com.
### type Package
```go
type Package struct {
ID int
AuthIPs []AuthIP
AllTimeStats PackageStatistics
HourlyStats map[time.Time]PackageStatistics
}
```
Package contains what we know about a particular proxybonanza package.
### type PackageDetails
```go
type PackageDetails struct {
Name string `json:"name"`
Bandwidth int64 `json:"bandwidth"`
Price interface{} `json:"price"`
HowmanyIPs int `json:"howmany_ips"`
PricePerGig interface{} `json:"price_per_gig"`
PackageType string `json:"package_type"`
HowmanyAuthips int `json:"howmany_authips"`
IPType int `json:"ip_type"`
PriceUserFormatted string `json:"price_user_formatted"`
}
```
PackageDetails represents an API response from proxybonanza.com containing proxy
package information.
### type PackageResponse
```go
type PackageResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
PackageData []UserPackage `json:"data"`
Pages pagination `json:"pagination"`
}
```
PackageResponse represents an API response from proxybonanza.com containing
proxy package information.
### type PackageStatistics
```go
type PackageStatistics struct {
UserpackageID int `json:"userpackage_id"`
Date string `json:"date"`
BndHTTP int `json:"bnd_http"`
ConnHTTP int `json:"conn_http"`
BndSocks int `json:"bnd_socks"`
ConnSocks int `json:"conn_socks"`
BndTotal int `json:"bnd_total"`
ConnTotal int `json:"conn_total"`
}
```
PackageStatistics represents the statistics for the related proxy package.
### type UserPackage
```go
type UserPackage struct {
ID int `json:"id"`
CustomName interface{} `json:"custom_name"`
Login string `json:"login"`
Password string `json:"password"`
Expires time.Time `json:"expires"`
Bandwidth int64 `json:"bandwidth"`
LowBanwidthNotificationPercent int `json:"low_banwidth_notification_percent"`
Package PackageDetails `json:"package"`
BandwidthGb float64 `json:"bandwidth_gb"`
AdditionalBandwidthGb float64 `json:"additional_bandwidth_gb"`
BandwidthPercentLeftHuman string `json:"bandwidth_percent_left_human"`
ExpirationDateHuman string `json:"expiration_date_human"`
Name string `json:"name"`
}
```
UserPackage represents a proxy package purchased from proxybonanza.com.
## Client
### type APIClient
```go
type APIClient struct {
Key string
KnownPackages map[int]PackageDetails
Debug bool
}
```
APIClient is a client for ProxyBonanza.com.
#### func NewApiClient
### Constructors
#### func NewAPIClient
```go
func NewApiClient(key string) *APIClient
func NewAPIClient(key string) *APIClient
```
NewApiClient instantiates a proxybonanza.com API client with the given key.
NewAPIClient instantiates a proxybonanza.com API client with the given key using
golang's default http client.
#### func NewCustomClient
```go
func NewCustomClient(key string, client *http.Client) *APIClient
```
NewCustomClient insantiates a proxybonanza API client with the given key and the
given http.Client.
### Methods
#### func (*APIClient) AddAuthIP
@ -51,7 +230,8 @@ AddAuthIP adds a new IP to the corresponding/provided proxy package ID.
func (api *APIClient) AddCurrentIPtoAllPackages() (success int)
```
AddCurrentIPtoAllPackages adds your current WAN IP to all packages on your
account. It returns the amount of successful packages that it was applied to.
account. It returns the amount of successful packages that it was applied to. It
will skip packages that are already using the current IP.
#### func (*APIClient) DeleteAllAuthIPs
@ -75,6 +255,22 @@ func (api *APIClient) DeleteAuthIPByIP(ipa net.IP) (err error)
DeleteAuthIPByIP will iterate through all the authips on your account and delete
one that matches the given IP.
#### func (*APIClient) DeleteOtherAuthIPs
```go
func (api *APIClient) DeleteOtherAuthIPs() ([]int, error)
```
DeleteOtherAuthIPs deletes all authenticaiton IPs from your account's packages
that do not match your current IP address. Returns a slice of authentication IP
IDs that were deleted and any errors that occurred.
#### func (*APIClient) GetAllSOCKSIPsAndPorts
```go
func (api *APIClient) GetAllSOCKSIPsAndPorts() ([]string, error)
```
GetAllSOCKSIPsAndPorts will return a slice of IP:Port formatted proxy strings
#### func (*APIClient) GetAuthIPs
```go
@ -82,144 +278,16 @@ func (api *APIClient) GetAuthIPs() ([]AuthIP, error)
```
GetAuthIPs gets all authentication IPs active on your account.
#### func (*APIClient) GetPackageSOCKS
```go
func (api *APIClient) GetPackageSOCKS(packageid int) ([]string, error)
```
GetPackageSOCKS returns a specified packages SOCKS5 proxies in host:port format.
#### func (*APIClient) GetProxyPackages
```go
func (api *APIClient) GetProxyPackages() ([]UserPackage, error)
```
GetProxyPackages gets current proxy packages from your account.
#### type AddAuthIPResponse
```go
type AddAuthIPResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Data struct {
ID int `json:"id"`
} `json:"data"`
}
```
AddAuthIPResponse represents an API response from proxybonanza.com.
#### type AuthIP
```go
type AuthIP struct {
UserpackageID int `json:"userpackage_id"`
ID interface{} `json:"id"`
IP string `json:"ip"`
}
```
AuthIP is an IP address authorized to use the proxies in the related package.
#### type AuthIPResponse
```go
type AuthIPResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
AuthIPData []AuthIP `json:"data"`
Pages pagination `json:"pagination"`
}
```
AuthIPResponse represents an API response from proxybonanza.com.
#### type DelAuthIPResponse
```go
type DelAuthIPResponse struct {
Success bool `json:"success"`
}
```
DelAuthIPResponse represents an API response from proxybonanza.com.
#### type Package
```go
type Package struct {
ID int
AuthIPs []AuthIP
AllTimeStats PackageStatistics
HourlyStats map[time.Time]PackageStatistics
}
```
Package contains what we know about a particular proxybonanza package.
#### type PackageDetails
```go
type PackageDetails struct {
Name string `json:"name"`
Bandwidth int64 `json:"bandwidth"`
Price interface{} `json:"price"`
HowmanyIPs int `json:"howmany_ips"`
PricePerGig interface{} `json:"price_per_gig"`
PackageType string `json:"package_type"`
HowmanyAuthips int `json:"howmany_authips"`
IPType int `json:"ip_type"`
PriceUserFormatted string `json:"price_user_formatted"`
}
```
PackageDetails represents an API response from proxybonanza.com containing proxy
package information.
#### type PackageResponse
```go
type PackageResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
PackageData []UserPackage `json:"data"`
Pages pagination `json:"pagination"`
}
```
PackageResponse represents an API response from proxybonanza.com containing
proxy package information.
#### type PackageStatistics
```go
type PackageStatistics struct {
UserpackageID int `json:"userpackage_id"`
Date string `json:"date"`
BndHTTP int `json:"bnd_http"`
ConnHTTP int `json:"conn_http"`
BndSocks int `json:"bnd_socks"`
ConnSocks int `json:"conn_socks"`
BndTotal int `json:"bnd_total"`
ConnTotal int `json:"conn_total"`
}
```
PackageStatistics represents the statistics for the related proxy package.
#### type UserPackage
```go
type UserPackage struct {
ID int `json:"id"`
CustomName interface{} `json:"custom_name"`
Login string `json:"login"`
Password string `json:"password"`
Expires time.Time `json:"expires"`
Bandwidth int64 `json:"bandwidth"`
LastIPChange time.Time `json:"last_ip_change"`
LowBanwidthNotificationPercent int `json:"low_banwidth_notification_percent"`
Package PackageDetails `json:"package"`
BandwidthGb float64 `json:"bandwidth_gb"`
AdditionalBandwidthGb int `json:"additional_bandwidth_gb"`
BandwidthPercentLeftHuman string `json:"bandwidth_percent_left_human"`
ExpirationDateHuman string `json:"expiration_date_human"`
Name string `json:"name"`
}
```
UserPackage represents a proxy package purchased from proxybonanza.com.

View File

@ -11,7 +11,6 @@ import (
"strconv"
)
func (api *APIClient) debugPrintf(format string, obj ...interface{}) {
if api.Debug {
fmt.Println(fmt.Sprintf(format, obj...))
@ -103,14 +102,15 @@ func (api *APIClient) GetProxyPackages() ([]UserPackage, error) {
func (api *APIClient) GetAuthIPs() ([]AuthIP, error) {
body, err := api.getReq(authips)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to get auth IPs: %w", err)
}
var auths AuthIPResponse
err = json.Unmarshal(body, &auths)
if err != nil {
return nil, err
print(string(body))
return nil, fmt.Errorf("failed to unmarshal auth ips: %w", err)
}
if !auths.Success {
@ -143,6 +143,36 @@ func (api *APIClient) DeleteAllAuthIPs() (int, error) {
return done, err
}
// DeleteOtherAuthIPs deletes all authenticaiton IPs from your account's packages that do not match your current IP address.
// Returns a slice of authentication IP IDs that were deleted and any errors that occurred.
func (api *APIClient) DeleteOtherAuthIPs() ([]int, error) {
myip, err := getMyIP()
if err != nil {
return []int{}, fmt.Errorf("failed to get my IP: %w", err)
}
aips, err := api.GetAuthIPs()
if err != nil {
return []int{}, fmt.Errorf("failed to get auth IPs: %w", err)
}
todo := len(aips)
done := 0
var deleted []int
for _, aip := range aips {
if net.ParseIP(aip.IP).Equal(myip) {
todo--
continue
}
if api.DeleteAuthIPByID(int(aip.ID.(float64))) {
done++
deleted = append(deleted, int(aip.ID.(float64)))
}
}
if done < todo {
err = errors.New("failed to delete some IPs")
}
return deleted, err
}
// AddAuthIP adds a new IP to the corresponding/provided proxy package ID.
func (api *APIClient) AddAuthIP(ip net.IP, packageID int) (AddAuthIPResponse, error) {
failadd := AddAuthIPResponse{Success: false}
@ -179,7 +209,11 @@ func (api *APIClient) DeleteAuthIPByIP(ipa net.IP) (err error) {
if ipa.IsPrivate() || ipa.IsUnspecified() || ipa.IsLoopback() {
return errors.New("IP is invalid")
}
aips, err := api.GetAuthIPs()
var aips []AuthIP
aips, err = api.GetAuthIPs()
if err != nil {
return
}
for _, aip := range aips {
if net.ParseIP(aip.IP).Equal(ipa) {
target := int(aip.ID.(float64))
@ -193,16 +227,38 @@ func (api *APIClient) DeleteAuthIPByIP(ipa net.IP) (err error) {
// AddCurrentIPtoAllPackages adds your current WAN IP to all packages on your account.
// It returns the amount of successful packages that it was applied to.
// It will skip packages that are already using the current IP.
func (api *APIClient) AddCurrentIPtoAllPackages() (success int) {
packs, err := api.GetProxyPackages()
if err != nil {
fmt.Println(err)
myip, myIPErr := getMyIP()
if myIPErr != nil {
// TODO: probably don't handle any of these errors like this - avoiding breaking changes for now.
println("ProxyGonanza failed to retrieve own IP: " + myIPErr.Error())
return
}
myip := getMyIP()
for _, p := range packs {
_, err := api.AddAuthIP(myip, p.ID)
aips, aipErr := api.GetAuthIPs()
if aipErr != nil {
println("ProxyGonanza failed to get auth IPs: " + aipErr.Error())
return
}
packs, packErr := api.GetProxyPackages()
if packErr != nil {
println("ProxyGonanza failed to get proxy packages: " + packErr.Error())
return 0
}
var skips []int
for _, aip := range aips {
aipIP := net.ParseIP(aip.IP)
if aipIP.Equal(myip) {
skips = append(skips, aip.UserpackageID)
}
}
for _, pack := range packs {
for _, skip := range skips {
if pack.ID == skip {
continue
}
}
_, err := api.AddAuthIP(myip, pack.ID)
if err == nil {
success++
}

20
api.go
View File

@ -81,17 +81,21 @@ type pagination struct {
// UserPackage represents a proxy package purchased from proxybonanza.com.
type UserPackage struct {
ID int `json:"id"`
CustomName interface{} `json:"custom_name"`
Login string `json:"login"`
Password string `json:"password"`
Expires time.Time `json:"expires"`
Bandwidth int64 `json:"bandwidth"`
LastIPChange time.Time `json:"last_ip_change"`
ID int `json:"id"`
CustomName interface{} `json:"custom_name"`
Login string `json:"login"`
Password string `json:"password"`
Expires time.Time `json:"expires"`
Bandwidth int64 `json:"bandwidth"`
// TODO:
// See https://github.com/yunginnanet/ProxyGonanza/issues/1
// LastIPChange time.Time `json:"last_ip_change"`
LowBanwidthNotificationPercent int `json:"low_banwidth_notification_percent"`
Package PackageDetails `json:"package"`
BandwidthGb float64 `json:"bandwidth_gb"`
AdditionalBandwidthGb int `json:"additional_bandwidth_gb"`
AdditionalBandwidthGb float64 `json:"additional_bandwidth_gb"`
BandwidthPercentLeftHuman string `json:"bandwidth_percent_left_human"`
ExpirationDateHuman string `json:"expiration_date_human"`
Name string `json:"name"`

1
cmd/README.md Normal file
View File

@ -0,0 +1 @@
##### This folder contains example implementations of ProxyGonanza.

49
cmd/authips/addip.go Normal file
View File

@ -0,0 +1,49 @@
package main
import (
"errors"
"fmt"
"os"
"git.tcp.direct/kayos/proxygonanza"
"git.tcp.direct/kayos/proxygonanza/internal"
)
func init() {
internal.ParseArgs()
}
var ErrNoNonMatchingIPs = errors.New("no non-matching IPs found or deleted")
func purge(c *proxygonanza.APIClient) error {
println("clearing all auth IPs that do not match current IP...")
deleted, err := c.DeleteOtherAuthIPs()
if err != nil {
return fmt.Errorf("failed to delete other auth IPs: %w", err)
}
if len(deleted) == 0 {
return ErrNoNonMatchingIPs
}
println("deleted other auth IP IDs:")
for _, del := range deleted {
fmt.Println(del)
}
return nil
}
func main() {
c := proxygonanza.NewAPIClient(internal.APIKey)
if internal.Purge {
if err := purge(c); err != nil && !errors.Is(err, ErrNoNonMatchingIPs) {
println(err.Error())
os.Exit(1)
}
}
println("adding current IP to all packages...")
count := c.AddCurrentIPtoAllPackages()
if count == 0 {
println("all authentication IPs are already set")
os.Exit(0)
}
fmt.Printf("successfully added your external IP to %d packages\n", count)
}

View File

@ -5,15 +5,15 @@ import (
"fmt"
"git.tcp.direct/kayos/proxygonanza"
"git.tcp.direct/kayos/proxygonanza/example"
"git.tcp.direct/kayos/proxygonanza/internal"
)
func init() {
example.ParseArgs()
internal.ParseArgs()
}
func main() {
c := proxygonanza.NewAPIClient(example.APIKey)
c := proxygonanza.NewAPIClient(internal.APIKey)
println("getting proxy packages...")
packs, err := c.GetProxyPackages()
@ -37,6 +37,6 @@ func main() {
fmt.Printf("\nfound %d auth IPs\n", len(authips))
for _, i := range authips {
pretty, _ := json.MarshalIndent(i, "", "\t")
fmt.Print(string(pretty)+"\n")
fmt.Print(string(pretty) + "\n")
}
}

View File

@ -1,19 +1,20 @@
package main
import (
"fmt"
"os"
"git.tcp.direct/kayos/proxygonanza"
"git.tcp.direct/kayos/proxygonanza/example"
"git.tcp.direct/kayos/proxygonanza/internal"
)
func init() {
example.ParseArgs()
internal.ParseArgs()
}
func main() {
c := proxygonanza.NewAPIClient(example.APIKey)
if example.Debug {
c := proxygonanza.NewAPIClient(internal.APIKey)
if internal.Debug {
c.Debug = true
println("debug enabled")
}
@ -23,6 +24,6 @@ func main() {
os.Exit(1)
}
for _, line := range socks {
println(line)
fmt.Fprint(os.Stdout, line+"\n")
}
}

View File

@ -1,36 +0,0 @@
package main
import (
"fmt"
"strconv"
"git.tcp.direct/kayos/proxygonanza"
"git.tcp.direct/kayos/proxygonanza/example"
)
func init() {
example.ParseArgs()
}
func main() {
println("clearing all auth IPs...")
c := proxygonanza.NewAPIClient(example.APIKey)
deleted, err := c.DeleteAllAuthIPs()
if err != nil {
println(err.Error())
return
}
println("deleted " + strconv.Itoa(deleted) + " IPs successfully")
println("adding current IP to all packages...")
count := c.AddCurrentIPtoAllPackages()
if count == 0 {
println("failed!")
return
}
fmt.Printf("successfully added your external IP to %d packages\n", count)
}

View File

@ -1,28 +0,0 @@
package example
import (
"fmt"
"os"
)
var (
Debug = false
APIKey string
)
func ParseArgs() {
if len(os.Args) < 2 {
fmt.Printf("\t ~*~ ProxyGonanza ~*~ \nhttps://git.tcp.direct/kayos/proxygonanza\n\nFatal: missing API Key \n\nUsage: %s [--verbose|-v] '<apikey>'\n\n", os.Args[0])
os.Exit(1)
}
for _, arg := range os.Args {
switch arg {
case "-d", "--debug", "-v", "--verbose":
Debug = true
break
default:
APIKey = arg
}
}
}

46
internal/common.go Normal file
View File

@ -0,0 +1,46 @@
package internal
import (
"fmt"
"net/http"
"os"
)
var (
Debug = false
APIKey = os.Getenv("PROXY_BONANZA")
Purge = false
)
func ParseArgs() {
if len(os.Args) < 2 && len(APIKey) < 2 {
fmt.Printf("\t ~*~ ProxyGonanza ~*~ \nhttps://git.tcp.direct/kayos/proxygonanza\n\nFatal: missing API Key \n\nUsage: %s [--verbose|-v] '<apikey>'\n\n", os.Args[0])
os.Exit(1)
}
for i, arg := range os.Args {
if i == 0 {
continue
}
switch arg {
case "-d", "--debug", "-v", "--verbose":
Debug = true
case "-p", "--purge":
Purge = true
default:
APIKey = arg
}
}
}
// CloseBody is crude error handling for any potential errors closing the response body.
func CloseBody(res *http.Response) {
if res == nil || res.Body == nil {
return
}
err := res.Body.Close()
if err != nil {
println("WARN: ProxyGonanza failed to close body for request to ",
res.Request.RequestURI+": "+err.Error())
}
}

View File

@ -1,12 +1,14 @@
package proxygonanza
import (
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"strings"
"git.tcp.direct/kayos/proxygonanza/internal"
)
func (api *APIClient) newRequest(method, u string) (r *http.Request) {
@ -37,11 +39,11 @@ func (api *APIClient) postReq(endpoint string, post map[string]string) ([]byte,
}
enc := params.Encode()
req, err := http.NewRequest("POST", APIBaseURL+endpoint, strings.NewReader(enc))
req.Header.Add("accept", "application/json")
req.Header.Add("Authorization", api.Key)
if err != nil {
return nil, err
}
req.Header.Add("accept", "application/json")
req.Header.Add("Authorization", api.Key)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
@ -80,8 +82,7 @@ func (api *APIClient) deleteReq(endpoint string) ([]byte, error) {
}
func processBody(res *http.Response) ([]byte, error) {
defer res.Body.Close()
defer internal.CloseBody(res)
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
@ -89,16 +90,23 @@ func processBody(res *http.Response) ([]byte, error) {
return body, nil
}
func getMyIP() net.IP {
res, err := http.DefaultClient.Get("https://wtfismyip.com/text")
if err != nil {
fmt.Println(err)
return net.IP{}
func getMyIP() (final net.IP, err error) {
endpoint := "https://wtfismyip.com/text"
envopt := os.Getenv("PROXYBONANZA_GETIP")
if envopt != "" {
endpoint = envopt
}
body, err := ioutil.ReadAll(res.Body)
var res *http.Response
res, err = http.DefaultClient.Get(endpoint)
if err != nil {
fmt.Println(err)
return net.IP{}
return
}
return net.ParseIP(strings.TrimSpace(string(body)))
defer internal.CloseBody(res)
var body []byte
body, err = ioutil.ReadAll(res.Body)
if err != nil {
return
}
final = net.ParseIP(strings.TrimSpace(string(body)))
return
}