|
|
|
@@ -2,16 +2,131 @@ package main |
|
|
|
|
|
|
|
import ( |
|
|
|
"encoding/base64" |
|
|
|
"encoding/json" |
|
|
|
"errors" |
|
|
|
"fmt" |
|
|
|
"log" |
|
|
|
"math/rand" |
|
|
|
"net/http" |
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
) |
|
|
|
|
|
|
|
func crmpixel(w http.ResponseWriter, r *http.Request) { |
|
|
|
func crmpixelImage() (pixel []byte, err error) { |
|
|
|
b64pixel := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QcIBzEJ3JY/6wAAAAh0RVh0Q29tbWVudAD2zJa/AAAADUlEQVQI12NgYGBgAAAABQABXvMqOgAAAABJRU5ErkJggg==" |
|
|
|
pixel, err := base64.StdEncoding.DecodeString(b64pixel) |
|
|
|
pixel, err = base64.StdEncoding.DecodeString(b64pixel) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func crmpixel(w http.ResponseWriter, r *http.Request) { |
|
|
|
|
|
|
|
cookie, lead := crmpixelCookie(r) |
|
|
|
log.Println(lead) |
|
|
|
http.SetCookie(w, &cookie) |
|
|
|
|
|
|
|
//send out pixel 1x1 transparent png file |
|
|
|
pixel, err := crmpixelImage() |
|
|
|
if err == nil { |
|
|
|
w.Write(pixel) |
|
|
|
} else { |
|
|
|
fmt.Fprint(w, "decodig wrong") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func crmpixelCookie(r *http.Request) (ret http.Cookie, info crmdLead) { |
|
|
|
cookie, leadok := r.Cookie("biukop_cl") //crm lead |
|
|
|
|
|
|
|
if leadok != nil { |
|
|
|
ret, info = createNewCookie(r) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
valid, info := isValidCookieBiukopCL(cookie.Value) |
|
|
|
if !valid { |
|
|
|
ret, info = createNewCookie(r) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
//refresh expiration |
|
|
|
ret = *cookie |
|
|
|
ret.Expires = time.Now().Add(10 * 365 * 24 * time.Hour) |
|
|
|
|
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func createNewCookie(r *http.Request) (ret http.Cookie, info crmdLead) { |
|
|
|
expiration := time.Now().Add(10 * 365 * 24 * time.Hour) |
|
|
|
info = crmCreateNewAnonymousLeadByHTTPRequest(r) |
|
|
|
cookieValue := buildBiukopCLValue(info.ID) |
|
|
|
ret = http.Cookie{Name: "biukop_cl", Value: cookieValue, Expires: expiration} |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func crmCreateNewAnonymousLeadByHTTPRequest(r *http.Request) (info crmdLead) { |
|
|
|
info.FirstName = "Anonymous" |
|
|
|
info.LastName = "User" |
|
|
|
info.Password = "Password" |
|
|
|
info.Status = "Anonymous" |
|
|
|
info.Description = "Anonymous from " + r.RemoteAddr |
|
|
|
info.ForceDuplicate = true |
|
|
|
b, err := json.Marshal(info) |
|
|
|
if err != nil { |
|
|
|
return |
|
|
|
} |
|
|
|
entity, err := crmCreateEntity("Lead", b) |
|
|
|
if err == nil || isErrIndicateDuplicate(err) { |
|
|
|
info, _ = entity.(crmdLead) |
|
|
|
} |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func isValidCookieBiukopCL(cookieValue string) (valid bool, info crmdLead) { |
|
|
|
valid = false |
|
|
|
|
|
|
|
//correctly split string |
|
|
|
s := strings.Split(cookieValue, "|") |
|
|
|
if len(s) != 4 || s[0] == "" { |
|
|
|
return |
|
|
|
} |
|
|
|
id, nonce, timestamp, signature := s[0], s[1], s[2], s[3] |
|
|
|
|
|
|
|
//check signature |
|
|
|
combined := id + nonce |
|
|
|
expected := calculateSignature(timestamp, combined, IntraAPIConfig.CRMSecrete) |
|
|
|
if expected != signature { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
//find lead data |
|
|
|
info, err := crmpixelLead(id) |
|
|
|
if err != nil { |
|
|
|
return |
|
|
|
} |
|
|
|
valid = true |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func buildBiukopCLsignature(id, nonce string) (timestamp, signature string) { |
|
|
|
combined := id + nonce |
|
|
|
timestamp = fmt.Sprintf("%d", time.Now().Unix()) |
|
|
|
signature = calculateSignature(timestamp, combined, IntraAPIConfig.CRMSecrete) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func buildBiukopCLValue(id string) (ret string) { |
|
|
|
rand.Seed(time.Now().Unix()) |
|
|
|
nonce := fmt.Sprintf("%d", rand.Intn(655352017)) |
|
|
|
timestamp, signature := buildBiukopCLsignature(id, nonce) |
|
|
|
strs := []string{id, nonce, timestamp, signature} //order is very important |
|
|
|
ret = strings.Join(strs, "|") |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func crmpixelLead(id string) (info crmdLead, err error) { |
|
|
|
entity, err := crmGetEntity("Lead", id) |
|
|
|
info, ok := entity.(crmdLead) |
|
|
|
if !ok { |
|
|
|
err = errors.New("search lead, return a bad entity type") |
|
|
|
} |
|
|
|
return |
|
|
|
} |