separate main code into different files (unsub, helpers)

This commit is contained in:
2023-12-26 16:58:04 -06:00
parent d504bd1b2e
commit ef7ca9f16e
4 changed files with 168 additions and 148 deletions

View File

@@ -22,6 +22,9 @@ func Login(username string, password string) {
// Send request
response, err := DoRequestNoRead(request)
if err != nil {
log.Fatal().Err(err).Msg("Error sending login page request")
}
doc, err := goquery.NewDocumentFromReader(response.Body)
defer response.Body.Close()
if err != nil {
@@ -39,21 +42,24 @@ func Login(username string, password string) {
"__RequestVerificationToken": {token},
"log-me-in": {"Log+In"},
}
log.Debug().Str("form", form.Encode()).Msg("Form Data")
request, _ = http.NewRequest("POST", "https://www.utsa.edu/directory/", strings.NewReader(form.Encode()))
ApplyHeaders(request)
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// Send the login request
response, body, err := DoRequest(request)
response, _, err = DoRequest(request)
if err != nil {
log.Fatal().Err(err).Msg("Error sending login request")
}
if response.StatusCode != 200 {
log.Printf("%+v", string(body))
log.Fatal().Str("status", response.Status).Msg("Error logging in")
switch response.StatusCode {
case 500:
log.Fatal().Str("status", response.Status).Msg("Bad Request (check cookies)")
default:
log.Fatal().Str("status", response.Status).Msg("Failed to Login, Unknown Error")
}
}
// TODO: Check if login was successful

52
helpers.go Normal file
View File

@@ -0,0 +1,52 @@
package main
import (
"io"
"net/http"
"github.com/rs/zerolog/log"
)
func DoRequestNoRead(req *http.Request) (*http.Response, error) {
log.Debug().Str("method", req.Method).Str("host", req.Host).Str("path", req.URL.Path).Msg("Request")
resp, err := client.Do(req)
if err != nil {
log.Error().Err(err).Msg("Error making request")
return nil, err
}
log.Debug().Int("code", resp.StatusCode).Str("content-type", resp.Header.Get("Content-Type")).Str("content-length", resp.Header.Get("Content-Length")).Msg("Response")
return resp, nil
}
func DoRequest(req *http.Request) (*http.Response, []byte, error) {
log.Debug().Str("method", req.Method).Str("host", req.Host).Str("path", req.URL.Path).Msg("Request")
resp, err := client.Do(req)
if err != nil {
log.Error().Err(err).Msg("Error making request")
return nil, nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Error().Err(err).Msg("Error reading response body")
return nil, nil, err
}
log.Debug().Int("code", resp.StatusCode).Str("content-type", resp.Header.Get("Content-Type")).Int("content-length", len(body)).Msg("Response")
return resp, body, nil
}
func ApplyHeaders(req *http.Request) {
req.Header.Set("Origin", "http://www2.thescla.org")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:122.0) Gecko/20100101 Firefox/122.0")
req.Header.Set("Accept", "application/json, text/javascript, */*; q=0.01")
req.Header.Set("Accept-Language", "en-US,en;q=0.5")
req.Header.Set("Accept-Encoding", "gzip, deflate")
}

144
main.go
View File

@@ -1,21 +1,14 @@
package main
import (
"crypto/sha256"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/cookiejar"
"net/url"
"os"
"os/signal"
"strings"
"github.com/joho/godotenv"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
)
var client *http.Client
@@ -29,143 +22,6 @@ func init() {
}
}
func DoRequestNoRead(req *http.Request) (*http.Response, error) {
log.Debug().Str("method", req.Method).Str("host", req.Host).Str("path", req.URL.Path).Msg("Request")
resp, err := client.Do(req)
if err != nil {
log.Error().Err(err).Msg("Error making request")
return nil, err
}
log.Debug().Int("code", resp.StatusCode).Str("content-type", resp.Header.Get("Content-Type")).Str("content-length", resp.Header.Get("Content-Length")).Msg("Response")
return resp, nil
}
func DoRequest(req *http.Request) (*http.Response, []byte, error) {
log.Debug().Str("method", req.Method).Str("host", req.Host).Str("path", req.URL.Path).Msg("Request")
resp, err := client.Do(req)
if err != nil {
log.Error().Err(err).Msg("Error making request")
return nil, nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Error().Err(err).Msg("Error reading response body")
return nil, nil, err
}
log.Debug().Int("code", resp.StatusCode).Str("content-type", resp.Header.Get("Content-Type")).Int("content-length", len(body)).Msg("Response")
return resp, body, nil
}
func ApplyHeaders(req *http.Request) {
req.Header.Set("Origin", "http://www2.thescla.org")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:122.0) Gecko/20100101 Firefox/122.0")
req.Header.Set("Accept", "application/json, text/javascript, */*; q=0.01")
req.Header.Set("Accept-Language", "en-US,en;q=0.5")
req.Header.Set("Accept-Encoding", "gzip, deflate")
}
func Unsubscribe(email string) (*ConfirmationResponse, error) {
mktTok := "ODM5LU1PTC01NTIAAAGQRiDbOUWzUhLliVDxTHjxLfZDD1y0MxC47Wf_1C9UTbwEej3Tckhn_QteZR7p5Mpl3_f0ioPUyQ8XUceJ9a0PiOUJb_O3YIj8PwKNQEm4SseaSw"
// Build referrer URL
referrerUrl, _ := url.Parse("http://www2.thescla.org/UnsubscribePage.html")
query := referrerUrl.Query()
query.Add("mkt_unsubscribe", "1")
query.Add("mkt_tok", mktTok)
referrerUrl.RawQuery = query.Encode()
// Build lpUrl
thing := "839-MOL-552"
lpUrl := fmt.Sprintf("http://%s.mktoweb.com/lp/%s/UnsubscribePage.html?cr={creative}&kw={keyword}", thing, thing)
values := url.Values{
"Email": {email},
"Unsubscribed": {"Yes"},
"formid": {"1"},
"lpId": {"1"},
"subId": {"98"},
"munchkinId": {thing},
"lpurl": {lpUrl},
"followupLpId": {"2"},
"cr": {""},
"kw": {""},
"q": {""},
"_mkt_trk": {""},
"formVid": {"1"},
"mkt_tok": {mktTok},
"_mktoReferrer": {referrerUrl.String()},
}
// Grab checksum fields
fields := make([]string, 0, len(values))
for key, _ := range values {
fields = append(fields, key)
}
values.Set("checksumFields", strings.Join(fields, ","))
// Calculate checksum
checksum := sha256.Sum256([]byte(strings.Join(
lo.Map(fields, func(field string, _ int) string {
return values.Get(field)
}), "|")))
values.Set("checksum", fmt.Sprintf("%x", checksum))
// Make request
request, _ := http.NewRequest("POST", "http://www2.thescla.org/index.php/leadCapture/save2", strings.NewReader(values.Encode()))
request.Header.Set("Referer", "http://www2.thescla.org/UnsubscribePage.html?mkt_unsubscribe=1")
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request.Header.Set("X-Requested-With", "XMLHttpRequest")
ApplyHeaders(request)
// Send request
response, body, err := DoRequest(request)
if err != nil {
panic(err)
}
if response.StatusCode != 200 {
// If JSON returned, parse the message for the error
contentType := response.Header.Get("Content-Type")
if !strings.Contains(contentType, "application/json") {
return nil, UnsubscribeUnexpectedError{Message: string(body), Code: response.StatusCode}
}
// Parse the JSON
var errorResponse ErrorResponse
err := json.Unmarshal(body, &errorResponse)
if err != nil {
log.Error().Err(err).Msg("Error parsing error response")
return nil, UnsubscribeUnexpectedError{Message: string(body), Code: response.StatusCode}
}
switch errorResponse.Message {
case "checksum invalid":
return nil, ChecksumInvalidError(checksum)
case "checksum missing":
return nil, ChecksumMissingError(checksum)
case "Rejected":
return nil, UnsubscribeRejectedError(errorResponse.Message)
}
log.Error().Str("content-type", contentType).Str("body", string(body)).Msg("Unknown Error")
return nil, UnsubscribeUnexpectedError{Message: string(body), Code: response.StatusCode}
}
var confirmation ConfirmationResponse
json.Unmarshal(body, &confirmation)
return &confirmation, nil
}
func main() {
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)

106
unsub.go Normal file
View File

@@ -0,0 +1,106 @@
package main
import (
"crypto/sha256"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
)
func Unsubscribe(email string) (*ConfirmationResponse, error) {
mktTok := "ODM5LU1PTC01NTIAAAGQRiDbOUWzUhLliVDxTHjxLfZDD1y0MxC47Wf_1C9UTbwEej3Tckhn_QteZR7p5Mpl3_f0ioPUyQ8XUceJ9a0PiOUJb_O3YIj8PwKNQEm4SseaSw"
// Build referrer URL
referrerUrl, _ := url.Parse("http://www2.thescla.org/UnsubscribePage.html")
query := referrerUrl.Query()
query.Add("mkt_unsubscribe", "1")
query.Add("mkt_tok", mktTok)
referrerUrl.RawQuery = query.Encode()
// Build lpUrl
thing := "839-MOL-552"
lpUrl := fmt.Sprintf("http://%s.mktoweb.com/lp/%s/UnsubscribePage.html?cr={creative}&kw={keyword}", thing, thing)
values := url.Values{
"Email": {email},
"Unsubscribed": {"Yes"},
"formid": {"1"},
"lpId": {"1"},
"subId": {"98"},
"munchkinId": {thing},
"lpurl": {lpUrl},
"followupLpId": {"2"},
"cr": {""},
"kw": {""},
"q": {""},
"_mkt_trk": {""},
"formVid": {"1"},
"mkt_tok": {mktTok},
"_mktoReferrer": {referrerUrl.String()},
}
// Grab checksum fields
fields := make([]string, 0, len(values))
for key, _ := range values {
fields = append(fields, key)
}
values.Set("checksumFields", strings.Join(fields, ","))
// Calculate checksum
checksum := sha256.Sum256([]byte(strings.Join(
lo.Map(fields, func(field string, _ int) string {
return values.Get(field)
}), "|")))
values.Set("checksum", fmt.Sprintf("%x", checksum))
// Make request
request, _ := http.NewRequest("POST", "http://www2.thescla.org/index.php/leadCapture/save2", strings.NewReader(values.Encode()))
request.Header.Set("Referer", "http://www2.thescla.org/UnsubscribePage.html?mkt_unsubscribe=1")
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request.Header.Set("X-Requested-With", "XMLHttpRequest")
ApplyHeaders(request)
// Send request
response, body, err := DoRequest(request)
if err != nil {
panic(err)
}
if response.StatusCode != 200 {
// If JSON returned, parse the message for the error
contentType := response.Header.Get("Content-Type")
if !strings.Contains(contentType, "application/json") {
return nil, UnsubscribeUnexpectedError{Message: string(body), Code: response.StatusCode}
}
// Parse the JSON
var errorResponse ErrorResponse
err := json.Unmarshal(body, &errorResponse)
if err != nil {
log.Error().Err(err).Msg("Error parsing error response")
return nil, UnsubscribeUnexpectedError{Message: string(body), Code: response.StatusCode}
}
switch errorResponse.Message {
case "checksum invalid":
return nil, ChecksumInvalidError(checksum)
case "checksum missing":
return nil, ChecksumMissingError(checksum)
case "Rejected":
return nil, UnsubscribeRejectedError(errorResponse.Message)
}
log.Error().Str("content-type", contentType).Str("body", string(body)).Msg("Unknown Error")
return nil, UnsubscribeUnexpectedError{Message: string(body), Code: response.StatusCode}
}
var confirmation ConfirmationResponse
json.Unmarshal(body, &confirmation)
return &confirmation, nil
}