Inserted web templates, readme, license. Updated logo and favicon
This commit is contained in:
468
tapit-backend/web-template.go
Normal file
468
tapit-backend/web-template.go
Normal file
@@ -0,0 +1,468 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/gorilla/mux"
|
||||
"time"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"strings"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"encoding/csv"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// WebTemplate is the persistent object within Postgres
|
||||
type WebTemplate struct {
|
||||
gorm.Model
|
||||
Name string
|
||||
TemplateType string // enum redirect, harvester
|
||||
RedirectAgent string
|
||||
RedirectNegAgent string
|
||||
RedirectPlaceholderHtml string
|
||||
RedirectUrl string
|
||||
HarvesterBeforeHtml string
|
||||
HarvesterAfterHtml string
|
||||
}
|
||||
|
||||
// WebTemplateJson is the temporary object for JSON data passing
|
||||
type WebTemplateJson struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
TemplateType string `json:"templateType"`
|
||||
RedirectAgent string `json:"redirectAgent"`
|
||||
RedirectNegAgent string `json:"redirectNegAgent"`
|
||||
RedirectPlaceholderHtml string `json:"redirectPlaceholderHtml"`
|
||||
RedirectUrl string `json:"redirectUrl"`
|
||||
HarvesterBeforeHtml string `json:"harvesterBeforeHtml"`
|
||||
HarvesterAfterHtml string `json:"harvesterAfterHtml"`
|
||||
CreateDate time.Time `json:"createDate"`
|
||||
}
|
||||
|
||||
type Visit struct {
|
||||
gorm.Model
|
||||
JobId uint
|
||||
SourceIp string
|
||||
UserAgent string
|
||||
Method string
|
||||
BodyContent string
|
||||
RawRequest string
|
||||
}
|
||||
|
||||
type VisitJson struct {
|
||||
Id uint `json:"id"`
|
||||
JobId uint `json:"jobId"`
|
||||
SourceIP string `json:"sourceIp"`
|
||||
UserAgent string `json:"userAgent"`
|
||||
Method string `json:"method"`
|
||||
BodyContent string `json:"bodyContent"`
|
||||
RawRequest string `json:"rawRequest"`
|
||||
CreateDate time.Time `json:"createDate"`
|
||||
}
|
||||
|
||||
func (tapit *Tapit) handleWebTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.ToUpper(r.Method) == "GET" {
|
||||
tapit.getWebTemplates(w, r)
|
||||
} else if strings.ToUpper(r.Method) == "POST" {
|
||||
tapit.createWebTemplate(w, r)
|
||||
} else {
|
||||
http.Error(w, "HTTP method not implemented", 400)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (tapit *Tapit) getWebTemplates(w http.ResponseWriter, r *http.Request) {
|
||||
webTemplates := []WebTemplate{}
|
||||
tapit.db.Find(&webTemplates)
|
||||
jsonResults, err := json.Marshal(webTemplatesToJson(webTemplates))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
} else {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(jsonResults)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func webTemplatesToJson(webTemplates []WebTemplate) []WebTemplateJson {
|
||||
webTemplateJson := make([]WebTemplateJson, 0)
|
||||
for _, webTemplate := range webTemplates {
|
||||
var currentWebTemplateJson WebTemplateJson
|
||||
currentWebTemplateJson.Id = int(webTemplate.ID)
|
||||
currentWebTemplateJson.Name = webTemplate.Name
|
||||
currentWebTemplateJson.TemplateType = webTemplate.TemplateType
|
||||
currentWebTemplateJson.RedirectAgent = webTemplate.RedirectAgent
|
||||
currentWebTemplateJson.RedirectNegAgent = webTemplate.RedirectNegAgent
|
||||
currentWebTemplateJson.RedirectPlaceholderHtml = webTemplate.RedirectPlaceholderHtml
|
||||
currentWebTemplateJson.RedirectUrl = webTemplate.RedirectUrl
|
||||
currentWebTemplateJson.HarvesterBeforeHtml = webTemplate.HarvesterBeforeHtml
|
||||
currentWebTemplateJson.HarvesterAfterHtml = webTemplate.HarvesterAfterHtml
|
||||
currentWebTemplateJson.CreateDate = webTemplate.CreatedAt
|
||||
|
||||
webTemplateJson = append(webTemplateJson, currentWebTemplateJson)
|
||||
}
|
||||
return webTemplateJson
|
||||
}
|
||||
|
||||
func (tapit *Tapit) createWebTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
// start doing work
|
||||
requestBody, err:= ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
newWebTemplateJson := WebTemplateJson{}
|
||||
err = json.Unmarshal(requestBody, &newWebTemplateJson)
|
||||
if err != nil {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
if newWebTemplateJson.Name != "" && newWebTemplateJson.TemplateType != "" {
|
||||
// check that not both user agents are filled
|
||||
if newWebTemplateJson.RedirectAgent != "" && newWebTemplateJson.RedirectNegAgent != "" {
|
||||
notifyPopup(w, r, "failure", "Please fill in only either positive or negative redirect user agent.", nil)
|
||||
return
|
||||
}
|
||||
newWebTemplate := jsonToWebTemplate(newWebTemplateJson)
|
||||
tapit.db.NewRecord(&newWebTemplate)
|
||||
tapit.db.Create(&newWebTemplate)
|
||||
if newWebTemplate.ID == 0 {
|
||||
notifyPopup(w, r, "failure", "Failed to create text template", nil)
|
||||
return
|
||||
}
|
||||
newWebTemplateJson.Id = int(newWebTemplate.ID)
|
||||
newWebTemplateJson.CreateDate = newWebTemplate.CreatedAt
|
||||
|
||||
notifyPopup(w, r, "success", "Successfully added new text template", newWebTemplateJson)
|
||||
return
|
||||
} else {
|
||||
notifyPopup(w, r, "failure", "Please fill in all details", nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func jsonToWebTemplate(currentWebTemplateJson WebTemplateJson) WebTemplate {
|
||||
var webTemplate WebTemplate
|
||||
|
||||
webTemplate.Name = currentWebTemplateJson.Name
|
||||
webTemplate.TemplateType = currentWebTemplateJson.TemplateType
|
||||
webTemplate.RedirectAgent = currentWebTemplateJson.RedirectAgent
|
||||
webTemplate.RedirectNegAgent = currentWebTemplateJson.RedirectNegAgent
|
||||
webTemplate.RedirectPlaceholderHtml = currentWebTemplateJson.RedirectPlaceholderHtml
|
||||
webTemplate.RedirectUrl = currentWebTemplateJson.RedirectUrl
|
||||
webTemplate.HarvesterBeforeHtml = currentWebTemplateJson.HarvesterBeforeHtml
|
||||
webTemplate.HarvesterAfterHtml = currentWebTemplateJson.HarvesterAfterHtml
|
||||
|
||||
return webTemplate
|
||||
}
|
||||
|
||||
func (tapit *Tapit) handleSpecificWebTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.ToUpper(r.Method) == "PUT" {
|
||||
tapit.updateWebTemplate(w, r)
|
||||
} else if strings.ToUpper(r.Method) == "DELETE" {
|
||||
tapit.deleteWebTemplate(w,r)
|
||||
} else if strings.ToUpper(r.Method) == "GET" {
|
||||
tapit.getWebTemplate(w,r)
|
||||
} else {
|
||||
http.Error(w, "HTTP method not implemented", 400)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (tapit *Tapit) updateWebTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
requestBody, err:= ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
var newWebTemplateJson WebTemplateJson
|
||||
err = json.Unmarshal(requestBody, &newWebTemplateJson)
|
||||
if err != nil {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
if newWebTemplateJson.Name != "" && newWebTemplateJson.TemplateType != "" {
|
||||
var newWebTemplate WebTemplate
|
||||
|
||||
// get current phonebook
|
||||
var dbSearchWT WebTemplate
|
||||
dbSearchWT.ID = uint(newWebTemplateJson.Id)
|
||||
tapit.db.Where(&dbSearchWT).First(&newWebTemplate)
|
||||
|
||||
if newWebTemplate.ID == uint(newWebTemplateJson.Id) {
|
||||
// update name & template
|
||||
newWebTemplate.Name = newWebTemplateJson.Name
|
||||
newWebTemplate.TemplateType = newWebTemplateJson.TemplateType
|
||||
newWebTemplate.RedirectAgent = newWebTemplateJson.RedirectAgent
|
||||
newWebTemplate.RedirectNegAgent = newWebTemplateJson.RedirectNegAgent
|
||||
newWebTemplate.RedirectPlaceholderHtml = newWebTemplateJson.RedirectPlaceholderHtml
|
||||
newWebTemplate.RedirectUrl = newWebTemplateJson.RedirectUrl
|
||||
newWebTemplate.HarvesterBeforeHtml = newWebTemplateJson.HarvesterBeforeHtml
|
||||
newWebTemplate.HarvesterAfterHtml = newWebTemplateJson.HarvesterAfterHtml
|
||||
|
||||
// update database
|
||||
tapit.db.Save(&newWebTemplate)
|
||||
if newWebTemplate.ID == 0 {
|
||||
notifyPopup(w, r, "failure", "Failed to update phonebook", nil)
|
||||
return
|
||||
}
|
||||
newWebTemplateJson.Id = int(newWebTemplate.ID)
|
||||
newWebTemplateJson.CreateDate = newWebTemplate.CreatedAt
|
||||
|
||||
notifyPopup(w, r, "success", "Successfully updated web template", newWebTemplateJson)
|
||||
return
|
||||
} else {
|
||||
notifyPopup(w, r, "failure", "Failed to update web template", nil)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
notifyPopup(w, r, "failure", "Please enter all details", nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (tapit *Tapit) deleteWebTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
tempID, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
|
||||
// start working
|
||||
var webTemplate WebTemplate
|
||||
|
||||
// get tt
|
||||
var dbSearchWT WebTemplate
|
||||
dbSearchWT.ID = uint(tempID)
|
||||
tapit.db.Where(dbSearchWT).First(&webTemplate)
|
||||
|
||||
if webTemplate.ID == uint(tempID) {
|
||||
// finally delete it
|
||||
tapit.db.Delete(&webTemplate)
|
||||
notifyPopup(w, r, "success", "Successfully deleted phonebook", nil)
|
||||
return
|
||||
} else {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (tapit *Tapit) getWebTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
tempID, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
|
||||
// start working
|
||||
var webTemplate WebTemplate
|
||||
|
||||
// get tt
|
||||
var dbSearchWT WebTemplate
|
||||
dbSearchWT.ID = uint(tempID)
|
||||
tapit.db.Where(dbSearchWT).First(&webTemplate)
|
||||
|
||||
if webTemplate.ID == uint(tempID) {
|
||||
jsonResults, err := json.Marshal(webTemplateToJson(webTemplate))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
} else {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(jsonResults)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (tapit *Tapit) generateWebTemplateRoute() string {
|
||||
charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||
// generate 5 char
|
||||
var newRoute string
|
||||
var successRoute bool
|
||||
successRoute = false
|
||||
|
||||
for !successRoute {
|
||||
newRoute = ""
|
||||
for i:=0; i<5; i++ {
|
||||
num := rand.Int() % len(charset)
|
||||
newRoute = newRoute + string(charset[num])
|
||||
|
||||
// search if route already exists
|
||||
var dbSearchJob Job
|
||||
var jobs []Job
|
||||
dbSearchJob.WebRoute = newRoute
|
||||
tapit.db.Where(&dbSearchJob).Find(&jobs)
|
||||
if len(jobs) == 0 {
|
||||
successRoute = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return newRoute
|
||||
}
|
||||
|
||||
func webTemplateToJson(webTemplate WebTemplate) WebTemplateJson {
|
||||
var currentWebTemplateJson WebTemplateJson
|
||||
currentWebTemplateJson.Id = int(webTemplate.ID)
|
||||
currentWebTemplateJson.Name = webTemplate.Name
|
||||
currentWebTemplateJson.TemplateType = webTemplate.TemplateType
|
||||
currentWebTemplateJson.RedirectAgent = webTemplate.RedirectAgent
|
||||
currentWebTemplateJson.RedirectNegAgent = webTemplate.RedirectNegAgent
|
||||
currentWebTemplateJson.RedirectPlaceholderHtml = webTemplate.RedirectPlaceholderHtml
|
||||
currentWebTemplateJson.RedirectUrl = webTemplate.RedirectUrl
|
||||
currentWebTemplateJson.HarvesterBeforeHtml = webTemplate.HarvesterBeforeHtml
|
||||
currentWebTemplateJson.HarvesterAfterHtml = webTemplate.HarvesterAfterHtml
|
||||
currentWebTemplateJson.CreateDate = webTemplate.CreatedAt
|
||||
return currentWebTemplateJson
|
||||
}
|
||||
|
||||
func (tapit *Tapit) webTemplateRouteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
vars := mux.Vars(r)
|
||||
currRoute := vars["route"]
|
||||
|
||||
currJob := Job{}
|
||||
err = tapit.db.Where(&Job{WebRoute:currRoute}).First(&currJob).Error
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
|
||||
currCampaign := Campaign{}
|
||||
err = tapit.db.Where(&Campaign{Model: gorm.Model{ID:currJob.CampaignId}}).First(&currCampaign).Error
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
|
||||
currWebTemplate := WebTemplate{}
|
||||
err = tapit.db.Where(&WebTemplate{Model: gorm.Model{ID:currCampaign.WebTemplateId}}).First(&currWebTemplate).Error
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
|
||||
// check type for "redirect" or "harvester"
|
||||
if currWebTemplate.TemplateType == "redirect" {
|
||||
if currWebTemplate.RedirectAgent != "" {
|
||||
listOfUA := strings.Split(currWebTemplate.RedirectAgent, ",")
|
||||
currCheck := false
|
||||
for _, currUA := range listOfUA {
|
||||
// check if user agent matches
|
||||
if strings.Contains(r.UserAgent(), currUA) {
|
||||
currCheck = true
|
||||
}
|
||||
}
|
||||
|
||||
// if matches at least once, redirect, otherwise placeholder
|
||||
if currCheck == true {
|
||||
http.Redirect(w, r, currWebTemplate.RedirectUrl, 302)
|
||||
} else {
|
||||
w.Write([]byte(currWebTemplate.RedirectPlaceholderHtml))
|
||||
}
|
||||
} else {
|
||||
listOfUA := strings.Split(currWebTemplate.RedirectNegAgent, ",")
|
||||
currCheck := true
|
||||
for _, currUA := range listOfUA {
|
||||
// check if user agent matches
|
||||
if strings.Contains(r.UserAgent(), currUA) {
|
||||
currCheck = false
|
||||
}
|
||||
}
|
||||
|
||||
// if matches at least once, redirect, otherwise placeholder
|
||||
if currCheck == true {
|
||||
http.Redirect(w, r, currWebTemplate.RedirectUrl, 302)
|
||||
} else {
|
||||
w.Write([]byte(currWebTemplate.RedirectPlaceholderHtml))
|
||||
}
|
||||
}
|
||||
} else if currWebTemplate.TemplateType == "harvester" {
|
||||
// if get show before, if post show after
|
||||
if strings.ToUpper(r.Method) == "GET"{
|
||||
w.Write([]byte(currWebTemplate.HarvesterBeforeHtml))
|
||||
} else if strings.ToUpper(r.Method) == "POST"{
|
||||
w.Write([]byte(currWebTemplate.HarvesterAfterHtml))
|
||||
} else {
|
||||
http.Error(w, "Bad request", 400)
|
||||
}
|
||||
}
|
||||
|
||||
// saving records
|
||||
requestBody, err:= ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
|
||||
var newVisit Visit
|
||||
|
||||
newVisit = Visit{}
|
||||
newVisit.JobId = currJob.ID
|
||||
if r.Header.Get("X-Forwarded-For") == "" {
|
||||
newVisit.SourceIp = r.RemoteAddr
|
||||
} else {
|
||||
newVisit.SourceIp = r.Header.Get("X-Forwarded-For")
|
||||
}
|
||||
newVisit.UserAgent = r.UserAgent()
|
||||
newVisit.Method = r.Method
|
||||
newVisit.BodyContent = string(requestBody)
|
||||
rawReqBytes, err := httputil.DumpRequest(r, true)
|
||||
if err == nil {
|
||||
newVisit.RawRequest = string(rawReqBytes)
|
||||
}
|
||||
|
||||
// Update visited status
|
||||
var visits []Visit
|
||||
tapit.db.Where(Visit{JobId: uint(currJob.ID)}).Find(&visits)
|
||||
currJob.WebStatus = strconv.Itoa(len(visits) + 1) + " visits"
|
||||
|
||||
tapit.db.Save(&currJob)
|
||||
|
||||
tapit.db.NewRecord(&newVisit)
|
||||
tapit.db.Create(&newVisit)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (tapit *Tapit) handleDownloadView(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.ToUpper(r.Method) == "GET" {
|
||||
var csvBuffer bytes.Buffer
|
||||
vars := mux.Vars(r)
|
||||
tempID, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
http.Error(w, "Bad request", 400)
|
||||
return
|
||||
}
|
||||
|
||||
var visits []Visit
|
||||
tapit.db.Where(Visit{JobId: uint(tempID)}).Find(&visits)
|
||||
|
||||
// generate csv
|
||||
csvWriter := csv.NewWriter(&csvBuffer)
|
||||
csvWriter.Write([]string{"ID", "Time", "Source IP", "User Agent", "Method", "Body Content", "Raw Request"})
|
||||
for _, visit := range visits {
|
||||
csvWriter.Write([]string{strconv.Itoa(int(visit.ID)), visit.CreatedAt.String(), visit.SourceIp, visit.UserAgent, visit.Method, visit.BodyContent, visit.RawRequest})
|
||||
}
|
||||
csvWriter.Flush()
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=\"results.csv\"")
|
||||
w.Write(csvBuffer.Bytes())
|
||||
return
|
||||
} else {
|
||||
http.Error(w, "HTTP method not implemented", 400)
|
||||
return
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user