github.com/prebid/prebid-server/v2@v2.18.0/pbs/usersync.go (about) 1 package pbs 2 3 import ( 4 "crypto/tls" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "net/url" 9 "strings" 10 11 "github.com/golang/glog" 12 "github.com/julienschmidt/httprouter" 13 "github.com/prebid/prebid-server/v2/config" 14 "github.com/prebid/prebid-server/v2/server/ssl" 15 "github.com/prebid/prebid-server/v2/usersync" 16 ) 17 18 // Recaptcha code from https://github.com/haisum/recaptcha/blob/master/recaptcha.go 19 const RECAPTCHA_URL = "https://www.google.com/recaptcha/api/siteverify" 20 21 type UserSyncDeps struct { 22 ExternalUrl string 23 RecaptchaSecret string 24 HostCookieConfig *config.HostCookie 25 PriorityGroups [][]string 26 } 27 28 // Struct for parsing json in google's response 29 type googleResponse struct { 30 Success bool 31 ErrorCodes []string `json:"error-codes"` 32 } 33 34 func (deps *UserSyncDeps) VerifyRecaptcha(response string) error { 35 ts := &http.Transport{ 36 Proxy: http.ProxyFromEnvironment, 37 TLSClientConfig: &tls.Config{RootCAs: ssl.GetRootCAPool()}, 38 } 39 40 client := &http.Client{ 41 Transport: ts, 42 } 43 resp, err := client.PostForm(RECAPTCHA_URL, 44 url.Values{"secret": {deps.RecaptchaSecret}, "response": {response}}) 45 if err != nil { 46 return err 47 } 48 defer resp.Body.Close() 49 var gr = googleResponse{} 50 if err := json.NewDecoder(resp.Body).Decode(&gr); err != nil { 51 return err 52 } 53 if !gr.Success { 54 return fmt.Errorf("Captcha verify failed: %s", strings.Join(gr.ErrorCodes, ", ")) 55 } 56 return nil 57 } 58 59 func (deps *UserSyncDeps) OptOut(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { 60 optout := r.FormValue("optout") 61 rr := r.FormValue("g-recaptcha-response") 62 encoder := usersync.Base64Encoder{} 63 decoder := usersync.Base64Decoder{} 64 65 if rr == "" { 66 http.Redirect(w, r, fmt.Sprintf("%s/static/optout.html", deps.ExternalUrl), http.StatusMovedPermanently) 67 return 68 } 69 70 err := deps.VerifyRecaptcha(rr) 71 if err != nil { 72 if glog.V(2) { 73 glog.Infof("Opt Out failed recaptcha: %v", err) 74 } 75 w.WriteHeader(http.StatusUnauthorized) 76 return 77 } 78 79 // Read Cookie 80 pc := usersync.ReadCookie(r, decoder, deps.HostCookieConfig) 81 usersync.SyncHostCookie(r, pc, deps.HostCookieConfig) 82 pc.SetOptOut(optout != "") 83 84 // Write Cookie 85 encodedCookie, err := encoder.Encode(pc) 86 if err != nil { 87 w.WriteHeader(http.StatusBadRequest) 88 return 89 } 90 usersync.WriteCookie(w, encodedCookie, deps.HostCookieConfig, false) 91 92 if optout == "" { 93 http.Redirect(w, r, deps.HostCookieConfig.OptInURL, http.StatusMovedPermanently) 94 } else { 95 http.Redirect(w, r, deps.HostCookieConfig.OptOutURL, http.StatusMovedPermanently) 96 } 97 }