Пример #1
0
func GetAccountStatus(r *http.Request, db DBConnection) string {
	// the result is a simple json ack
	ack := new(SimpleMessage)

	// this function only responds to GET requests with
	// an hmac digest of the contents
	if "GET" == r.Method {
		params, paramErr := url.ParseQuery(r.URL.RawQuery)
		if paramErr != nil {
			ack.Err = paramErr
		} else {
			email := params.Get("email")
			hmacDigest := params.Get("hmac")

			if email != "" && hmacDigest != "" {
				// confirm the digest matches
				params.Del("hmac") // separate the digest from the rest
				if digest.DigestMatches(email, params.Encode(), hmacDigest) {
					// the request is valid
					statusFn := func(statements map[string]*sql.Stmt) {
						lookupStmt, lookupStmtExists := statements[barcodes.ACCOUNT_LOOKUP_BY_EMAIL]
						if lookupStmtExists {
							// see if the email corresponds to an account
							acc, accErr := barcodes.LookupAccount(lookupStmt, email, false)
							if accErr != nil {
								ack.Err = accErr
							} else {
								if acc.Id != "" {
									// this account has already been registered
									// so return its verified status in the message
									if acc.Verified {
										ack.Ack = "true"
									} else {
										ack.Ack = "false"
									}
									ack.Err = nil
								}
							}
						}
					}
					WithServerDatabase(db, statusFn)
				}
			}
		}
	}

	result, err := json.Marshal(ack)
	if err != nil {
		fmt.Println(err)
	}
	return string(result)
}
Пример #2
0
func EmailSelectedItems(r *http.Request, db DBConnection) string {
	// the result is a simple json ack
	ack := new(SimpleMessage)

	// this function only responds to POST requests
	if "POST" == r.Method {
		r.ParseForm()

		emailVal, emailValExists := r.PostForm["email"]
		items, itemsExist := r.PostForm["item"]
		hmacDigest, hmacDigestExists := r.PostForm["hmac"]

		if emailValExists && itemsExist && hmacDigestExists {
			processFn := func(statements map[string]*sql.Stmt) {
				// see if the account exists
				accountLookupStmt, accountLookupStmtExists := statements[barcodes.ACCOUNT_LOOKUP_BY_EMAIL]
				if accountLookupStmtExists {
					// see if the email is available
					acc, accErr := barcodes.LookupAccount(accountLookupStmt, emailVal[0], false)
					if accErr != nil {
						ack.Err = accErr
					} else {
						// check the hmac digest
						r.PostForm.Del("hmac") // separate the digest from the rest
						if digest.DigestMatches(acc.APICode, r.PostForm.Encode(), hmacDigest[0]) {
							// hmac is correct

							// email the list of items
							content := EmailedItems{Email: acc.Email, Items: items}
							ack.Err = SendEmailedItems(content)

							// and update this json reply
							ack.Ack = "ok"
						}
					}
				}
			}
			WithServerDatabase(db, processFn)
		}
	}

	result, err := json.Marshal(ack)
	if err != nil {
		fmt.Println(err)
	}
	return string(result)
}
Пример #3
0
func VerifyAccount(r *http.Request, db DBConnection) string {
	// accumulate the result in a simple ack struct
	ack := new(SimpleMessage)

	// this function only responds to GET requests
	if "GET" == r.Method {
		// get the verification code from the query string
		code := r.URL.Path[len("/verify/"):]

		verifyFn := func(statements map[string]*sql.Stmt) {
			lookupStmt, lookupStmtExists := statements[barcodes.ACCOUNT_LOOKUP_BY_ID]
			updateStmt, updateStmtExists := statements[barcodes.ACCOUNT_UPDATE]
			if lookupStmtExists && updateStmtExists {
				// see if the account for this code exists
				acc, accErr := barcodes.LookupAccount(lookupStmt, code, true)
				if accErr != nil {
					ack.Err = accErr
				} else {
					if acc.Id == code {
						// can proceed with the verification
						acc.Verified = true
						ack.Err = acc.Update(updateStmt)
					}
				}
			}
		}
		WithServerDatabase(db, verifyFn)
	}

	// need to return a simple html string in reply
	if ack.Err != nil {
		return ack.Err.Error()
	} else {
		return "Thank you for verifying your email address"
	}
}
Пример #4
0
func RegisterAccount(r *http.Request, db DBConnection, serverLink string) string {
	// the result is a simple json ack
	ack := new(SimpleMessage)

	// this function only responds to GET requests with
	// an hmac digest of the contents
	if "GET" == r.Method {
		params, paramErr := url.ParseQuery(r.URL.RawQuery)
		if paramErr != nil {
			ack.Err = paramErr
		} else {
			email := params.Get("email")
			apiCode := params.Get("api")
			hmacDigest := params.Get("hmac")

			if email != "" && apiCode != "" {
				// confirm the digest matches
				params.Del("hmac") // separate the digest from the rest
				if digest.DigestMatches(email, params.Encode(), hmacDigest) {
					// the request is valid
					registerFn := func(statements map[string]*sql.Stmt) {
						lookupStmt, lookupStmtExists := statements[barcodes.ACCOUNT_LOOKUP_BY_EMAIL]
						insertStmt, insertStmtExists := statements[barcodes.ACCOUNT_INSERT]
						if lookupStmtExists && insertStmtExists {
							// see if the email is available
							acc, accErr := barcodes.LookupAccount(lookupStmt, email, false)
							if accErr != nil {
								ack.Err = accErr
							} else {
								if acc.Id != "" {
									// this account has already been registered
									ack.Ack = fmt.Sprintf("exists: %s", acc.Id)

									if !acc.Verified {
										// but it has yet to be verified, so send an email
										ack.Err = SendVerificationEmail(serverLink, email, acc.Id)
									}
								} else {
									// can proceed with the registration (add this email + api combination)
									acc.Email = email
									acc.APICode = apiCode
									pk, addErr := acc.Add(insertStmt)
									if addErr != nil {
										ack.Err = accErr
									} else {
										// the account is created, but unverified

										// send an email for verfication
										ack.Err = SendVerificationEmail(serverLink, email, pk)

										// and update this json reply
										ack.Ack = fmt.Sprintf("ok: %s", pk)
									}
								}
							}
						}
					}
					WithServerDatabase(db, registerFn)
				}
			}
		}
	}

	result, err := json.Marshal(ack)
	if err != nil {
		fmt.Println(err)
	}
	return string(result)
}
Пример #5
0
func ContributeData(r *http.Request, db DBConnection) string {
	// the result is a simple json ack
	ack := new(SimpleMessage)

	// this function only responds to POST requests
	if "POST" == r.Method {
		r.ParseForm()

		emailVal, emailValExists := r.PostForm["email"]
		barcode, barcodeExists := r.PostForm["barcode"]
		hmacDigest, hmacDigestExists := r.PostForm["hmac"]

		if emailValExists && barcodeExists && hmacDigestExists {
			processFn := func(statements map[string]*sql.Stmt) {
				// see if the account exists
				accountLookupStmt, accountLookupStmtExists := statements[barcodes.ACCOUNT_LOOKUP_BY_EMAIL]
				itemInsertStmt, itemInsertStmtExists := statements[barcodes.BARCODE_INSERT]
				if accountLookupStmtExists && itemInsertStmtExists {
					// see if the email is available
					acc, accErr := barcodes.LookupAccount(accountLookupStmt, emailVal[0], false)
					if accErr != nil {
						ack.Err = accErr
					} else {
						// check the hmac digest
						r.PostForm.Del("hmac") // separate the digest from the rest
						if digest.DigestMatches(acc.APICode, r.PostForm.Encode(), hmacDigest[0]) {
							// hmac is correct

							// add the contributed barcode data
							prodName, prodNameExists := r.PostForm["prodName"]
							prodDesc, prodDescExists := r.PostForm["prodDesc"]

							item := barcodes.BARCODE{Barcode: barcode[0], GtinEdit: false}
							if prodNameExists {
								item.ProductName = prodName[0]
							}
							if prodDescExists {
								item.ProductDesc = prodDesc[0]
							}
							pk, insertErr := barcodes.ContributeBarcode(itemInsertStmt, item, acc)
							if insertErr != nil {
								ack.Err = insertErr
							} else {
								item.Uuid = pk
								ack.Ack = fmt.Sprintf("ok: %s", pk)

								// contribute the brand information, if any
								brandName, brandNameExists := r.PostForm["brandName"]
								brandUrl, brandUrlExists := r.PostForm["brandUrl"]
								if brandNameExists || brandUrlExists {
									// TO-DO: use an autocomplete/autosuggestion at the UI form,
									// so that what gets posted here is either definitely an existing BSIN or not ...
									// but instead, for now, use the name to lookup possible matches
									brandLookupStmt, brandLookupStmtExists := statements[barcodes.BRAND_NAME_LOOKUP]
									brandInsertStmt, brandInsertStmtExists := statements[barcodes.CONTRIBUTED_BRAND_INSERT]
									brandSupplementStmt, brandSuplementStmtExists := statements[barcodes.BARCODE_BRAND_INSERT]
									if brandLookupStmtExists && brandInsertStmtExists && brandSuplementStmtExists {
										// see if the brand already exists in POD
										existingBrands, existingBrandsErr := barcodes.LookupBrandByName(brandLookupStmt, brandName[0])
										if existingBrandsErr != nil {
											ack.Err = existingBrandsErr
										}
										if len(existingBrands) > 0 {
											// for now, just take the first match, and use it as the existing POD brand
											// mark the contributed barcode item as belonging to this brand
											ack.Err = barcodes.ContributeBarcodeBrand(brandSupplementStmt, item, existingBrands[0])
										} else {
											// this brand is completely unknown to POD
											brand := new(barcodes.CONTRIBUTED_BRAND)
											if brandNameExists {
												brand.Name = brandName[0]
											}
											if brandUrlExists {
												brand.URL = brandUrl[0]
											}
											ack.Err = barcodes.ContributeBrand(brandInsertStmt, brand, acc)
										}
									}
								}
							}
						}
					}
				}
			}
			WithServerDatabase(db, processFn)

		}
	}

	result, err := json.Marshal(ack)
	if err != nil {
		fmt.Println(err)
	}
	return string(result)
}