예제 #1
0
func storeDepositInfo(c appengine.Context, r *http.Request, participant string) (err error) {
	// Important: checking (and invalidating) the nonce must be the first thing we do!
	err = checkNonce(c, r.FormValue("nonce"))
	if CfgRequireValidNonce && err != nil {
		return fmt.Errorf("Error in checkNonce: %v", err)
	}

	m := bitwrk.DepositAddressMessage{}
	m.FromValues(r.Form)

	if m.Participant != participant {
		return fmt.Errorf("Participant must be %#v", participant)
	}

	if m.Signer != CfgTrustedAccount {
		return fmt.Errorf("Signer must be %#v", CfgTrustedAccount)
	}

	// Bitcoin addresses must have the right network id
	if err := checkBitcoinAddress(m.DepositAddress); err != nil {
		return err
	}

	// Verify that the message was indeed signed by the trusted account
	if CfgRequireValidSignature {
		if err := m.VerifyWith(CfgTrustedAccount); err != nil {
			return err
		}
	}

	f := func(c appengine.Context) error {
		dao := db.NewGaeAccountingDao(c, true)
		if account, err := dao.GetAccount(participant); err != nil {
			return err
		} else {
			if account.DepositInfo != "" {
				c.Infof("Replacing old deposit info: %v", account.DepositInfo)
			}
			v := url.Values{}
			m.ToValues(v)
			account.DepositInfo = v.Encode()
			account.LastDepositInfo = time.Now()
			account.DepositAddressRequest = ""
			c.Infof("New deposit info: %v", account.DepositInfo)
			if err := dao.SaveAccount(&account); err != nil {
				return err
			}
		}
		return dao.Flush()
	}

	if err := datastore.RunInTransaction(c, f, &datastore.TransactionOptions{XG: true}); err != nil {
		// Transaction failed
		c.Errorf("Transaction failed: %v", err)
		return err
	}

	return
}
예제 #2
0
func serveInternal(workerManager *client.WorkerManager, exit chan<- error) {
	mux := http.NewServeMux()
	s := &http.Server{
		Addr:    fmt.Sprintf("%v:%v", InternalIface, InternalPort),
		Handler: mux,
		// No timeouts!
	}
	relay := NewHttpRelay("/", protocol.BitwrkUrl, protocol.NewClient(&http.Transport{}))
	mux.Handle("/account/", relay)
	mux.Handle("/bid/", relay)
	mux.Handle("/deposit/", relay)
	mux.Handle("/tx/", relay)
	mux.Handle("/motd", relay)

	accountFilter := func(data []byte) ([]byte, error) {
		var account bitwrk.ParticipantAccount
		if err := json.Unmarshal(data, &account); err != nil {
			return data, nil
		} else {
			// Pass data about validation results into the template so it doesn't
			// have to be done in JavaScript.
			type result struct {
				Account             bitwrk.ParticipantAccount
				Updated             time.Time
				TrustedAccount      string
				DepositAddress      string
				DepositAddressValid bool
			}
			r := result{account, time.Now(), TrustedAccount, "", false}
			if v, err := url.ParseQuery(account.DepositInfo); err == nil {
				m := bitwrk.DepositAddressMessage{}
				m.FromValues(v)
				if m.VerifyWith(TrustedAccount) == nil {
					r.DepositAddress = m.DepositAddress
					r.DepositAddressValid = true
				}
			}
			return json.Marshal(r)
		}
	}
	myAccountUrl := fmt.Sprintf("%saccount/%s", protocol.BitwrkUrl, BitcoinIdentity.GetAddress())
	myAccountRelay := NewHttpRelay("/myaccount", myAccountUrl, relay.client).WithFilterFunc(accountFilter)
	mux.Handle("/myaccount", myAccountRelay)

	resource := http.FileServer(http.Dir(path.Join(ResourceDir, "htroot")))
	mux.Handle("/js/", resource)
	mux.Handle("/css/", resource)
	mux.Handle("/img/", resource)

	mux.HandleFunc("/buy/", handleBuy)
	mux.HandleFunc("/file/", handleFile)
	mux.HandleFunc("/", handleHome)
	mux.HandleFunc("/ui/", handleHome)
	mux.HandleFunc("/activities", handleActivities)
	if ExternalPort > 0 {
		mux.HandleFunc("/registerworker", func(w http.ResponseWriter, r *http.Request) {
			handleRegisterWorker(workerManager, w, r)
		})
	} else {
		mux.HandleFunc("/registerworker", http.NotFound)
	}
	mux.HandleFunc("/unregisterworker", func(w http.ResponseWriter, r *http.Request) {
		handleUnregisterWorker(workerManager, w, r)
	})
	mux.HandleFunc("/workers", func(w http.ResponseWriter, r *http.Request) {
		handleWorkers(workerManager, w, r)
	})
	mux.HandleFunc("/mandates", func(w http.ResponseWriter, r *http.Request) {
		handleMandates(client.GetActivityManager(), w, r)
	})
	mux.HandleFunc("/revokemandate", func(w http.ResponseWriter, r *http.Request) {
		if err := handleRevokeMandate(r); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	})
	mux.HandleFunc("/requestdepositaddress", func(w http.ResponseWriter, r *http.Request) {
		if err := handleRequestDepositAddress(r); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		} else {
			// Account information is now stale
			myAccountRelay.InvalidateCache()
		}
	})
	mux.HandleFunc("/id", handleId)
	mux.HandleFunc("/version", handleVersion)
	mux.HandleFunc("/cafsdebug", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/html")
		client.GetActivityManager().GetStorage().DumpStatistics(cafs.NewWriterPrinter(w))
	})
	mux.HandleFunc("/stackdump", func(w http.ResponseWriter, r *http.Request) {
		name := r.FormValue("name")
		if len(name) == 0 {
			name = "goroutine"
		}
		profile := pprof.Lookup(name)
		if profile == nil {
			w.Write([]byte("No such profile"))
			return
		}
		err := profile.WriteTo(w, 1)
		if err != nil {
			log.Printf("Error in profile.WriteTo: %v\n", err)
		}
	})
	exit <- s.ListenAndServe()
}