Exemplo n.º 1
0
// InputUnknownItem handles the form for user contributions of unknown
// barcode scans: a GET presents the form, and a POST responds to the
// user-contributed input
func InputUnknownItem(w http.ResponseWriter, r *http.Request, dbCoords database.ConnCoordinates, opts ...interface{}) {
	// attempt to connect to the db
	db, err := database.InitializeDB(dbCoords)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer db.Close()

	// get the Account for this request
	acc, accErr := database.GetDesignatedAccount(db)
	if accErr != nil {
		http.Error(w, accErr.Error(), http.StatusInternalServerError)
		return
	}

	// get the api server + port from the optional parameters
	apiHost, apiHostOk := opts[0].(string)
	if !apiHostOk {
		http.Error(w, BAD_REQUEST, http.StatusInternalServerError)
		return
	}

	// prepare the html page response
	form := &ItemForm{Title: "Contribute Product Information",
		CancelUrl:    HOME_URL,
		Unregistered: (acc.Email == database.ANONYMOUS_EMAIL)}

	//lookup the item from the request id
	// and show the input form (if a GET)
	// or process it (if a POST)
	if "GET" == r.Method {
		// derive the item id from the url path
		urlPaths := strings.Split(r.URL.Path[1:], "/")
		if len(urlPaths) >= 2 {
			itemId, itemIdErr := strconv.ParseInt(urlPaths[1], 10, 64)
			if itemIdErr == nil {
				item, itemErr := database.GetSingleItem(db, acc, itemId)
				if itemErr == nil {
					if item.Id != database.BAD_PK && item.Desc == "" {
						// requested item has been found and is valid
						form.Item = item
					}
				}
			}
		}

		if form.Item == nil {
			// no matching item was found
			http.Error(w, BAD_REQUEST, http.StatusInternalServerError)
			return
		}

	} else if "POST" == r.Method {
		// get the item id from the posted data
		r.ParseForm()
		idVal, idExists := r.PostForm["item"]
		barcodeVal, barcodeExists := r.PostForm["barcode"]
		prodNameVal, prodNameExists := r.PostForm["prodName"]
		if idExists && barcodeExists && prodNameExists {
			itemId, itemIdErr := strconv.ParseInt(idVal[0], 10, 64)
			if itemIdErr != nil {
				form.FormError = itemIdErr.Error()
			} else {
				item, itemErr := database.GetSingleItem(db, acc, itemId)
				if itemErr != nil {
					form.FormError = itemErr.Error()
				} else {
					// the hidden barcode value must match the retrieved item
					if item.Barcode == barcodeVal[0] {
						// update the item in the local client db
						item.Desc = prodNameVal[0]
						item.UserContributed = true
						item.Update(db)

						// also need to mark the contribution to POD in the server
						if acc.Email != database.ANONYMOUS_EMAIL {
							// get the form's prodDesc, brandName, brandUrl data
							prodDesc, prodDescExists := r.PostForm["prodDesc"]
							brandName, brandNameExists := r.PostForm["brandName"]
							brandUrl, brandUrlExists := r.PostForm["brandUrl"]

							// ping the server with the contribution data
							ping := func() {
								v := url.Values{}
								v.Set("email", acc.Email)
								v.Set("barcode", barcodeVal[0])
								v.Set("prodName", prodNameVal[0])
								if prodDescExists {
									v.Set("prodDesc", prodDesc[0])
								}
								if brandNameExists {
									v.Set("brandName", brandName[0])
								}
								if brandUrlExists {
									v.Set("brandUrl", brandUrl[0])
								}

								// use the account api code as the digest key
								hmac := digest.GenerateDigest(acc.APICode, v.Encode())
								v.Set("hmac", hmac)

								res, err := http.PostForm(strings.Join([]string{apiHost, "/contribute/"}, ""), v)
								if err == nil {
									res.Body.Close()
								}
							}

							go ping() // do not wait for the server to reply

						}

						// return success
						http.Redirect(w, r, HOME_URL, http.StatusFound)
						return
					} else {
						// bad form post: the hidden barcode value does not match the retrieved item
						form.FormError = BAD_POST
					}
				}
			}
		} else {
			// required form parameters are missing
			form.FormError = BAD_POST
		}
	}

	renderItemEditTemplate(w, form)
}
Exemplo n.º 2
0
// ConfirmServerAccount responds to the ajax request from the client to
// lookup and return the status of the given account
func ConfirmServerAccount(r *http.Request, dbCoords database.ConnCoordinates, opts ...interface{}) string {
	// prepare the ajax reply object
	ack := AjaxAck{Message: "", Error: ""}

	// attempt to connect to the db
	db, err := database.InitializeDB(dbCoords)
	if err != nil {
		ack.Error = err.Error()
	}
	defer db.Close()

	// get the api server + port from the optional parameters
	apiHost, apiHostOk := opts[0].(string)
	if !apiHostOk {
		ack.Error = BAD_REQUEST
	}

	if ack.Error == "" {
		// get the Account for this request
		acc, accErr := database.GetDesignatedAccount(db)
		if accErr != nil {
			ack.Error = accErr.Error()
		}

		// get the account from the POST values
		if "POST" == r.Method {
			r.ParseForm()
			if accVal, exists := r.PostForm["account"]; exists {
				if len(accVal) > 0 {
					id, idErr := strconv.ParseInt(accVal[0], 10, 64)
					if idErr != nil {
						ack.Error = idErr.Error()
					} else {
						if acc.Id != id {
							ack.Error = BAD_REQUEST
						} else {
							// prepare the API Server request
							v := url.Values{}
							v.Set("email", acc.Email)

							// use the email address as the digest key
							hmac := digest.GenerateDigest(acc.Email, v.Encode())
							v.Set("hmac", hmac)

							// ping the API Server for the status of this account
							res, resErr := http.Get(strings.Join([]string{apiHost, "/status?", v.Encode()}, ""))
							defer res.Body.Close()
							if resErr != nil {
								ack.Error = resErr.Error()
							} else {
								// read and parse the json message from the API Server
								m := new(api.SimpleMessage)
								dec := json.NewDecoder(res.Body)
								dec.Decode(&m)

								// assign the json ack accordingly
								if m.Err != nil {
									ack.Error = m.Err.Error()
								} else {
									ack.Message = m.Ack
								}
							}
						}
					}
				} else {
					ack.Error = "Missing account id"
				}
			} else {
				ack.Error = BAD_POST
			}
		} else {
			ack.Error = BAD_REQUEST
		}
	}

	// convert the ajax reply object to json
	ackObj, ackObjErr := json.Marshal(ack)
	if ackObjErr != nil {
		return ackObjErr.Error()
	}
	return string(ackObj)
}
Exemplo n.º 3
0
// EditAccount presents the form for editing Account information (in
// response to a GET request) and handles to add/updates (in response to
// a POST request)
func EditAccount(w http.ResponseWriter, r *http.Request, dbCoords database.ConnCoordinates, opts ...interface{}) {
	// attempt to connect to the db
	db, err := database.InitializeDB(dbCoords)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer db.Close()

	// get the Account for this request
	acc, accErr := database.GetDesignatedAccount(db)
	if accErr != nil {
		http.Error(w, accErr.Error(), http.StatusInternalServerError)
		return
	}

	// get the api server + port from the optional parameters
	apiHost, apiHostOk := opts[0].(string)
	if !apiHostOk {
		http.Error(w, BAD_REQUEST, http.StatusInternalServerError)
		return
	}

	// prepare the html page response
	regStatus := (acc.Email == database.ANONYMOUS_EMAIL)
	cancelUrl := HOME_URL
	if !regStatus {
		cancelUrl = ACCOUNT_URL
	}

	form := &AccountForm{Title: "My Account",
		ActiveTab:    &ActiveTab{Scanned: false, Favorites: false, Account: true, ShowTabs: true},
		Account:      acc,
		CancelUrl:    cancelUrl,
		Unregistered: regStatus}

	if "POST" == r.Method {
		form.FormError = BAD_POST // in event of problems

		// get the item id from the posted data
		r.ParseForm()
		accVal, accExists := r.PostForm["account"]
		emailVal, emailExists := r.PostForm["accountEmail"]
		if accExists && emailExists {
			// make sure the hidden account id value matches the Account
			accId, accIdErr := strconv.ParseInt(accVal[0], 10, 64)
			if accIdErr != nil {
				form.FormError = accIdErr.Error()
			} else {
				if acc.Id == accId {
					// update the account email address in the local client db
					updateErr := acc.Update(db, emailVal[0], acc.APICode)
					if updateErr != nil {
						form.FormError = updateErr.Error()
					} else {
						// ping the server with the api code and email for verification
						ping := func() {
							v := url.Values{}
							v.Set("email", emailVal[0])
							v.Set("api", acc.APICode)

							// use the email address as the digest key
							hmac := digest.GenerateDigest(emailVal[0], v.Encode())
							v.Set("hmac", hmac)

							res, err := http.Get(strings.Join([]string{apiHost, "/register?", v.Encode()}, ""))
							if err == nil {
								res.Body.Close()
							}
						}

						go ping() // do not wait for the server to reply

						// return success
						http.Redirect(w, r, ACCOUNT_URL, http.StatusFound)
						return
					}
				}
			}
		}
	}

	renderAccountEditTemplate(w, form)
}
Exemplo n.º 4
0
// EmailItems handles the client form post, to send a list of the selected
// items via email to the given user
func EmailItems(w http.ResponseWriter, r *http.Request, dbCoords database.ConnCoordinates, opts ...interface{}) {
	// attempt to connect to the db
	db, err := database.InitializeDB(dbCoords)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer db.Close()

	// get the api server + port from the optional parameters
	apiHost, apiHostOk := opts[0].(string)
	if !apiHostOk {
		http.Error(w, BAD_REQUEST, http.StatusInternalServerError)
		return
	}

	// get the Account for this request
	acc, accErr := database.GetDesignatedAccount(db)
	if accErr != nil {
		http.Error(w, accErr.Error(), http.StatusInternalServerError)
		return
	}

	// get the account from the POST values
	if "POST" == r.Method {
		r.ParseForm()

		// make sure the form sent the required params
		accVal, accExists := r.PostForm["account"]
		items, itemsExist := r.PostForm["item"]

		if itemsExist && accExists {
			if len(accVal) > 0 {
				// check the submitted account info
				id, idErr := strconv.ParseInt(accVal[0], 10, 64)
				if idErr != nil {
					http.Error(w, idErr.Error(), http.StatusInternalServerError)
					return
				} else {
					if acc.Id != id {
						http.Error(w, BAD_REQUEST, http.StatusInternalServerError)
						return
					} else {
						// proceed with the send only if registered
						if acc.Email != database.ANONYMOUS_EMAIL {
							// lookup all the items for this account
							accountItems, accountItemsErr := database.GetItems(db, acc)

							if accountItemsErr == nil {
								// ping the server with the selected item data
								ping := func() {
									v := url.Values{}
									v.Set("email", acc.Email)

									// attach the list of descriptions for the selected items
									for _, accItem := range accountItems {
										for _, item := range items {
											if strconv.FormatInt(accItem.Id, 10) == item {
												v.Add("item", accItem.Desc)
												break
											}
										}
									}

									// use the account api code as the digest key
									hmac := digest.GenerateDigest(acc.APICode, v.Encode())
									v.Set("hmac", hmac)

									res, err := http.PostForm(strings.Join([]string{apiHost, "/email/"}, ""), v)
									if err == nil {
										res.Body.Close()
									}
								}

								go ping() // do not wait for the server to reply
							}
						}
					}
				}
			} else {
				http.Error(w, "Missing account id", http.StatusInternalServerError)
				return
			}
		} else {
			http.Error(w, BAD_POST, http.StatusInternalServerError)
			return
		}
	} else {
		http.Error(w, BAD_REQUEST, http.StatusInternalServerError)
		return
	}

	// finally, return home, to the scanned items list with an ack message
	http.Redirect(w, r, HOME_URL+"?ack=email", http.StatusFound)

}