You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
6.5 KiB
216 lines
6.5 KiB
package main
|
|
|
|
import (
|
|
"github.com/jinzhu/gorm"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"log"
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"time"
|
|
)
|
|
|
|
type TwilioProvider struct {
|
|
gorm.Model
|
|
AccountSID string
|
|
AuthToken string
|
|
}
|
|
|
|
type TwilioProviderJson struct {
|
|
AccountSID string `json:"accountSID"`
|
|
AuthToken string `json:"authToken"`
|
|
}
|
|
|
|
func (tapit *Tapit) handleTwilioProvider(w http.ResponseWriter, r *http.Request) {
|
|
if strings.ToUpper(r.Method) == "GET" {
|
|
tapit.getTwilioProvider(w, r)
|
|
} else if strings.ToUpper(r.Method) == "POST" {
|
|
tapit.updateTwilioProvider(w, r)
|
|
} else {
|
|
http.Error(w, "HTTP method not implemented", 400)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (tapit *Tapit) getTwilioProvider(w http.ResponseWriter, r *http.Request) {
|
|
var twilioProvider TwilioProvider
|
|
tapit.db.Last(&twilioProvider)
|
|
jsonResults, err := json.Marshal(twilioProviderToJson(twilioProvider))
|
|
if err != nil {
|
|
http.Error(w, err.Error(), 500)
|
|
return
|
|
} else {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write(jsonResults)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (tapit *Tapit) updateTwilioProvider(w http.ResponseWriter, r *http.Request) {
|
|
requestBody, err:= ioutil.ReadAll(r.Body)
|
|
if err != nil {
|
|
http.Error(w, "Bad request", 400)
|
|
return
|
|
}
|
|
var newTwilioProviderJson TwilioProviderJson
|
|
err = json.Unmarshal(requestBody, &newTwilioProviderJson)
|
|
if err != nil {
|
|
http.Error(w, "Bad request", 400)
|
|
return
|
|
}
|
|
|
|
// first check if already exist
|
|
var twilioProvider TwilioProvider
|
|
tapit.db.Last(&twilioProvider)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), 500)
|
|
return
|
|
}
|
|
|
|
// update twilioProvider
|
|
twilioProvider.AccountSID = newTwilioProviderJson.AccountSID
|
|
twilioProvider.AuthToken = newTwilioProviderJson.AuthToken
|
|
|
|
// does not exist
|
|
if twilioProvider.ID == 0 {
|
|
tapit.db.NewRecord(&twilioProvider)
|
|
tapit.db.Create(&twilioProvider)
|
|
|
|
if twilioProvider.ID == 0 {
|
|
notifyPopup(w, r, "failure", "Failed to create Twilio Provider", nil)
|
|
return
|
|
} else {
|
|
notifyPopup(w, r, "success", "Twilio provider updated", newTwilioProviderJson)
|
|
return
|
|
}
|
|
} else {
|
|
// exists
|
|
tapit.db.Save(&twilioProvider)
|
|
notifyPopup(w, r, "success", "Twilio provider updated", newTwilioProviderJson)
|
|
return
|
|
}
|
|
}
|
|
|
|
func twilioProviderToJson(tProvider TwilioProvider) TwilioProviderJson {
|
|
var results TwilioProviderJson
|
|
results.AccountSID = tProvider.AccountSID
|
|
results.AuthToken = tProvider.AuthToken
|
|
return results
|
|
}
|
|
|
|
func (tapit *Tapit) twilioSend(accSid string, accToken string, bodyText string, fromNum string, toNum string) []byte {
|
|
// if burp proxy is necessary
|
|
client := &http.Client{
|
|
Timeout: 5 * time.Second,
|
|
}
|
|
|
|
method1 := "POST"
|
|
url1 := "https://api.twilio.com/2010-04-01/Accounts/"+accSid+"/Messages.json"
|
|
// making body
|
|
params := url.Values{}
|
|
params.Add("Body", bodyText)
|
|
params.Add("From", fromNum)
|
|
params.Add("To", toNum)
|
|
body1 := strings.NewReader(params.Encode())
|
|
log.Println(params.Encode())
|
|
// making request
|
|
newRequest1, err := http.NewRequest(method1, url1, body1)
|
|
if err != nil {
|
|
log.Fatal("Error in creating request")
|
|
}
|
|
|
|
//basic auth with token
|
|
newRequest1.SetBasicAuth(accSid, accToken)
|
|
|
|
//set headers
|
|
newRequest1.Header.Add("Content-Type","application/x-www-form-urlencoded; charset=UTF-8")
|
|
|
|
// sending request
|
|
res, err := client.Do(newRequest1)
|
|
retriesLeft := tapit.globalSettings.MaxRequestRetries
|
|
for err != nil && retriesLeft > 0 {
|
|
log.Println("Error in sending request")
|
|
res, err = client.Do(newRequest1)
|
|
retriesLeft -= 1
|
|
time.Sleep(time.Duration(tapit.globalSettings.WaitBeforeRetry) * time.Millisecond)
|
|
}
|
|
|
|
// exit gracefully if can't
|
|
if err!= nil {
|
|
var emptyBytes []byte
|
|
return emptyBytes
|
|
}
|
|
outputStr, _ := ioutil.ReadAll(res.Body)
|
|
log.Println(string(outputStr))
|
|
return outputStr
|
|
}
|
|
|
|
func (tapit *Tapit) twilioCheck(accSid string, accToken string, messageSid string) []byte {
|
|
client := &http.Client{
|
|
Timeout: 5 * time.Second,
|
|
}
|
|
method1 := "GET"
|
|
url1 := "https://api.twilio.com/2010-04-01/Accounts/"+accSid+"/Messages/"+messageSid+".json"
|
|
body1 := strings.NewReader("")
|
|
newRequest1, err := http.NewRequest(method1, url1, body1)
|
|
|
|
// authenticate
|
|
newRequest1.SetBasicAuth(accSid, accToken)
|
|
|
|
// sending request
|
|
res, err := client.Do(newRequest1)
|
|
retriesLeft := tapit.globalSettings.MaxRequestRetries
|
|
for err != nil && retriesLeft > 0 {
|
|
log.Println("Error in sending request")
|
|
res, err = client.Do(newRequest1)
|
|
retriesLeft -= 1
|
|
time.Sleep(time.Duration(tapit.globalSettings.WaitBeforeRetry) * time.Millisecond)
|
|
}
|
|
|
|
// exit gracefully if can't
|
|
if err!= nil {
|
|
var emptyBytes []byte
|
|
return emptyBytes
|
|
}
|
|
outputStr, _ := ioutil.ReadAll(res.Body)
|
|
log.Println(string(outputStr))
|
|
return outputStr
|
|
}
|
|
|
|
func (tapit *Tapit) workerTwilioChecker() {
|
|
// infinite loop to keep checking for queued jobs to check delivery status
|
|
for true {
|
|
// sleep 5 second per cycle
|
|
time.Sleep(5000 * time.Millisecond)
|
|
var pendJobs []Job
|
|
|
|
tapit.db.Where("provider_tag = ? AND (current_status = ? OR current_status = ?)", "twilio", "Queued", "Sent").Find(&pendJobs)
|
|
|
|
for _, job := range pendJobs {
|
|
// sleep 100ms per job
|
|
time.Sleep(100 * time.Millisecond)
|
|
resultJson := tapit.twilioCheck(job.AccSID, job.AuthToken, job.MessageSid)
|
|
job.ResultStr = string(resultJson)
|
|
|
|
var twilioResult TwilioMessageJson
|
|
err := json.Unmarshal(resultJson, &twilioResult)
|
|
if err != nil {
|
|
log.Println(err)
|
|
job.CurrentStatus = "Failed"
|
|
} else if twilioResult.Status == "queued" {
|
|
job.MessageSid = twilioResult.Sid
|
|
job.CurrentStatus = "Queued"
|
|
} else if twilioResult.Status == "sent" {
|
|
job.MessageSid = twilioResult.Sid
|
|
job.CurrentStatus = "Sent"
|
|
} else if twilioResult.Status == "delivered" {
|
|
job.MessageSid = twilioResult.Sid
|
|
job.CurrentStatus = "Delivered"
|
|
job.TimeSent = time.Now()
|
|
}
|
|
tapit.db.Save(&job)
|
|
}
|
|
}
|
|
}
|
|
|