Example #1
0
func (ps *PaymentService) getPaymentAddr(req *msg.OcReq) (*msg.OcResp, error) {
	if len(req.Args) > 1 {
		return msg.NewRespError(msg.INVALID_ARGUMENTS), nil
	}
	reqCurrency := string(msg.BTC)
	if len(req.Args) == 1 {
		reqCurrency = strings.ToUpper(req.Args[0])
	}
	p, err := peer.NewPeerFromReq(req, ps.BitcoindConf)
	if err != nil {
		return msg.NewRespError(msg.SERVER_ERROR), nil
	}
	switch reqCurrency {
	case string(msg.BTC):
		if ps.BitcoindConf == nil {
			return msg.NewRespError(msg.SERVER_ERROR), nil
		}
		// TODO(ortutay): smarter handling to map request ID to address
		btcAddr, err := p.PaymentAddr(ADDRS_PER_ID, ps.BitcoindConf)
		if err != nil {
			return msg.NewRespError(msg.SERVER_ERROR), nil
		}
		payAddr := msg.PaymentAddr{Currency: msg.BTC, Addr: btcAddr}
		return msg.NewRespOk([]byte(payAddr.String())), nil
	default:
		return msg.NewRespError(msg.CURRENCY_UNSUPPORTED), nil
	}
}
Example #2
0
func (ps *PaymentService) balance(req *msg.OcReq) (*msg.OcResp, error) {
	p, err := peer.NewPeerFromReq(req, ps.BitcoindConf)
	if err != nil {
		return msg.NewRespError(msg.SERVER_ERROR), nil
	}
	balance, err := p.Balance(0, ps.BitcoindConf)
	if err != nil {
		return msg.NewRespError(msg.SERVER_ERROR), nil
	}
	maxBalanceConf, err := ps.Conf.PolicyForCmd(conf.MAX_BALANCE)
	if err != nil {
		// TODO(ortutay): handle more configuration around max balance
		panic(err)
	}
	maxBalance := maxBalanceConf.Args[0].(*msg.PaymentValue)
	btcAddr, err := p.PaymentAddr(ADDRS_PER_ID, ps.BitcoindConf)
	if err != nil {
		return msg.NewRespError(msg.SERVER_ERROR), nil
	}
	resp := BalanceResponse{
		Balance:    balance,
		MaxBalance: maxBalance,
		Addr:       btcAddr,
	}
	body, err := json.Marshal(&resp)
	if err != nil {
		return msg.NewRespError(msg.SERVER_ERROR), nil
	}
	return msg.NewRespOk(body), nil
}
Example #3
0
func (s *Server) Serve(listener net.Listener) error {
	conn, err := listener.Accept()
	if err != nil {
		return err
	}
	go (func(conn net.Conn) {
		println("get req")
		req, err := msg.ReadOcReq(bufio.NewReader(conn))
		defer conn.Close()
		defer fmt.Fprintf(conn, "\n")
		if err != nil {
			msg.NewRespError(msg.BAD_REQUEST).Write(conn)
			return
		}

		fmt.Printf("Got request: %v\n", req)

		// TODO(ortutay): implement additional request validation
		// - validate sigs
		// - check nonce
		// - check service available
		// - check method available

		p, err := peer.NewPeerFromReq(req, s.BtcConf)
		if err != nil {
			log.Printf("error generating peer: %v\n", err)
			if err == peer.INVALID_SIGNATURE {
				msg.NewRespError(msg.INVALID_SIGNATURE).Write(conn)
			} else if err == peer.COIN_REUSE {
				msg.NewRespError(msg.COIN_REUSE).Write(conn)
			} else {
				msg.NewRespError(msg.SERVER_ERROR).Write(conn)
			}
			return
		}

		// TODO(ortutay): more configuration options around allowed balance
		balanceDueResp := s.checkBalance(p)
		if balanceDueResp != nil && req.Service != "payment" {
			balanceDueResp.Write(conn)
			return
		}

		if ok, status := s.isAllowedByPolicy(p, req); !ok {
			if status == msg.OK {
				panic("expected error status")
			}
			fmt.Printf("not allowed: %v %v\n", ok, status)
			msg.NewRespError(status).Write(conn)
			return
		}

		fmt.Printf("passing off to handler...\n")
		resp, err := s.Handler.Handle(req)
		if err != nil || resp == nil {
			fmt.Printf("server error: %v\n", err)
			msg.NewRespError(msg.SERVER_ERROR).Write(conn)
		} else {
			fmt.Printf("sending response: %v\n", resp)
			resp.Write(conn)
		}
		return
	})(conn)
	return nil
}