ProxyGonanza/actions.go

289 lines
7.1 KiB
Go

package proxygonanza
import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"strconv"
)
func (api *APIClient) debugPrintf(format string, obj ...interface{}) {
if api.Debug {
fmt.Println(fmt.Sprintf(format, obj...))
}
}
// NewAPIClient instantiates a proxybonanza.com API client with the given key using golang's default http client.
func NewAPIClient(key string) *APIClient {
return &APIClient{
Key: key,
KnownPackages: make(map[int]PackageDetails),
c: http.DefaultClient,
}
}
// NewCustomClient insantiates a proxybonanza API client with the given key and the given http.Client.
func NewCustomClient(key string, client *http.Client) *APIClient {
return &APIClient{
Key: key,
KnownPackages: make(map[int]PackageDetails),
c: client,
}
}
// GetAllSOCKSIPsAndPorts will return a slice of IP:Port formatted proxy strings
func (api *APIClient) GetAllSOCKSIPsAndPorts() ([]string, error) {
packs, err := api.GetProxyPackages()
if err != nil {
return []string{}, err
}
var results []string
for _, pack := range packs {
packsocks, err := api.GetPackageSOCKS(pack.ID)
if err != nil {
return results, err
}
results = append(results, packsocks...)
}
return results, nil
}
// fun fact, this wasn't in their api docs.
// proxybonanza.com/api/v1/userpackages_ippacks.csv?_delimiter=%3A&userpackage_id=xxxxx&_csvNoHeader=0&_csvFields=ip%2Cport_socks
// GetPackageSOCKS returns a specified packages SOCKS5 proxies in host:port format.
func (api *APIClient) GetPackageSOCKS(packageid int) ([]string, error) {
body, err := api.getReq("userpackages_ippacks.csv?_delimiter=%3A&userpackage_id=" + strconv.Itoa(packageid) + "&_csvNoHeader=0&_csvFields=ip%2Cport_socks")
if err != nil {
return []string{}, err
}
var results []string
scanner := bufio.NewScanner(bytes.NewReader(body))
for i := 0; scanner.Scan(); i++ {
if i == 0 {
continue
}
results = append(results, scanner.Text())
}
return results, nil
}
// GetProxyPackages gets current proxy packages from your account.
func (api *APIClient) GetProxyPackages() ([]UserPackage, error) {
body, err := api.getReq(packages)
if err != nil {
return nil, err
}
var packs PackageResponse
err = json.Unmarshal(body, &packs)
if err != nil {
return nil, err
}
if !packs.Success {
return nil, errors.New("ERROR: " + string(body))
}
for _, p := range packs.PackageData {
api.KnownPackages[p.ID] = p.Package
}
return packs.PackageData, nil
}
// GetAuthIPs gets all authentication IPs active on your account.
func (api *APIClient) GetAuthIPs() ([]AuthIP, error) {
body, err := api.getReq(authips)
if err != nil {
return nil, fmt.Errorf("failed to get auth IPs: %w", err)
}
var auths AuthIPResponse
err = json.Unmarshal(body, &auths)
if err != nil {
print(string(body))
return nil, fmt.Errorf("failed to unmarshal auth ips: %w", err)
}
if !auths.Success {
return nil, errors.New("ERROR: " + string(body))
}
return auths.AuthIPData, nil
}
// DeleteAllAuthIPs deletes all authenticaiton IPs from your account.
func (api *APIClient) DeleteAllAuthIPs() (int, error) {
aips, err := api.GetAuthIPs()
if err != nil {
return 0, err
}
todo := len(aips)
done := 0
for _, aip := range aips {
target := int(aip.ID.(float64))
fmt.Println("deleting ", target)
if api.DeleteAuthIPByID(target) {
done++
}
}
if done < todo {
err = errors.New("failed to delete some IPs")
}
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}
if ip.IsPrivate() || ip.IsUnspecified() || ip.IsLoopback() {
return failadd, errors.New("ip is private: " + ip.String())
}
post := map[string]string{
"ip": ip.String(),
"userpackage_id": strconv.Itoa(packageID),
}
body, err := api.postReq(authips, post)
if err != nil {
return failadd, err
}
var addipres AddAuthIPResponse
err = json.Unmarshal(body, &addipres)
if err != nil {
return failadd, err
}
if !addipres.Success {
return failadd, errors.New("ERROR: " + addipres.Message)
}
return addipres, nil
}
// DeleteAuthIPByIP will iterate through all the authips on your account and delete one that matches the given IP.
func (api *APIClient) DeleteAuthIPByIP(ipa net.IP) (err error) {
if ipa.IsPrivate() || ipa.IsUnspecified() || ipa.IsLoopback() {
return errors.New("IP is invalid")
}
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))
if api.DeleteAuthIPByID(target) {
return nil
}
}
}
return errors.New("IP doesn't exist")
}
// 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) {
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
}
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++
}
}
return
}
// DeleteAuthIPByID deletes an authentication IP with the matching ID provided
func (api *APIClient) DeleteAuthIPByID(ipID int) (ok bool) {
body, err := api.deleteReq("authips/" + strconv.Itoa(ipID) + ".json")
if err != nil {
return
}
var delipres DelAuthIPResponse
err = json.Unmarshal(body, &delipres)
if err != nil {
return
}
if delipres.Success {
ok = true
}
return
}