mirror of
https://github.com/aclindsa/moneygo.git
synced 2024-12-26 23:42:29 -05:00
Move to a consistent way of handling IDs in URLs
This commit is contained in:
parent
e99abfe866
commit
9624f0c5bc
@ -5,7 +5,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -100,14 +99,6 @@ type AccountList struct {
|
|||||||
Accounts *[]Account `json:"accounts"`
|
Accounts *[]Account `json:"accounts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var accountTransactionsRE *regexp.Regexp
|
|
||||||
var accountImportRE *regexp.Regexp
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
accountTransactionsRE = regexp.MustCompile(`^/v1/accounts/[0-9]+/transactions/?$`)
|
|
||||||
accountImportRE = regexp.MustCompile(`^/v1/accounts/[0-9]+/imports/[a-z]+/?$`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Account) Write(w http.ResponseWriter) error {
|
func (a *Account) Write(w http.ResponseWriter) error {
|
||||||
enc := json.NewEncoder(w)
|
enc := json.NewEncoder(w)
|
||||||
return enc.Encode(a)
|
return enc.Encode(a)
|
||||||
@ -384,18 +375,12 @@ func AccountHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r.Method == "POST" {
|
if r.Method == "POST" {
|
||||||
// if URL looks like /v1/accounts/[0-9]+/imports, use the account
|
if !context.LastLevel() {
|
||||||
// import handler
|
accountid, err := context.NextID()
|
||||||
if accountImportRE.MatchString(r.URL.Path) {
|
if err != nil || context.NextLevel() != "imports" {
|
||||||
var accountid int64
|
return NewError(3 /*Invalid Request*/)
|
||||||
var importtype string
|
|
||||||
n, err := GetURLPieces(r.URL.Path, "/v1/accounts/%d/imports/%s", &accountid, &importtype)
|
|
||||||
|
|
||||||
if err != nil || n != 2 {
|
|
||||||
log.Print(err)
|
|
||||||
return NewError(999 /*Internal Error*/)
|
|
||||||
}
|
}
|
||||||
return AccountImportHandler(context, r, user, accountid, importtype)
|
return AccountImportHandler(context, r, user, accountid)
|
||||||
}
|
}
|
||||||
|
|
||||||
account_json := r.PostFormValue("account")
|
account_json := r.PostFormValue("account")
|
||||||
@ -433,10 +418,7 @@ func AccountHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
|
|
||||||
return ResponseWrapper{201, &account}
|
return ResponseWrapper{201, &account}
|
||||||
} else if r.Method == "GET" {
|
} else if r.Method == "GET" {
|
||||||
var accountid int64
|
if context.LastLevel() {
|
||||||
n, err := GetURLPieces(r.URL.Path, "/v1/accounts/%d", &accountid)
|
|
||||||
|
|
||||||
if err != nil || n != 1 {
|
|
||||||
//Return all Accounts
|
//Return all Accounts
|
||||||
var al AccountList
|
var al AccountList
|
||||||
accounts, err := GetAccounts(context.Tx, user.UserId)
|
accounts, err := GetAccounts(context.Tx, user.UserId)
|
||||||
@ -446,13 +428,14 @@ func AccountHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
}
|
}
|
||||||
al.Accounts = accounts
|
al.Accounts = accounts
|
||||||
return &al
|
return &al
|
||||||
} else {
|
}
|
||||||
// if URL looks like /account/[0-9]+/transactions, use the account
|
|
||||||
// transaction handler
|
|
||||||
if accountTransactionsRE.MatchString(r.URL.Path) {
|
|
||||||
return AccountTransactionsHandler(context, r, user, accountid)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
accountid, err := context.NextID()
|
||||||
|
if err != nil {
|
||||||
|
return NewError(3 /*Invalid Request*/)
|
||||||
|
}
|
||||||
|
|
||||||
|
if context.LastLevel() {
|
||||||
// Return Account with this Id
|
// Return Account with this Id
|
||||||
account, err := GetAccount(context.Tx, accountid, user.UserId)
|
account, err := GetAccount(context.Tx, accountid, user.UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -460,9 +443,11 @@ func AccountHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return account
|
return account
|
||||||
|
} else if context.NextLevel() == "transactions" {
|
||||||
|
return AccountTransactionsHandler(context, r, user, accountid)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
accountid, err := GetURLID(r.URL.Path)
|
accountid, err := context.NextID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(3 /*Invalid Request*/)
|
return NewError(3 /*Invalid Request*/)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,6 +36,14 @@ func (c *Context) NextLevel() string {
|
|||||||
return split[0]
|
return split[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Context) NextID() (int64, error) {
|
||||||
|
return strconv.ParseInt(c.NextLevel(), 0, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) LastLevel() bool {
|
||||||
|
return len(c.remainingURL) == 0
|
||||||
|
}
|
||||||
|
|
||||||
type Handler func(*http.Request, *Context) ResponseWriterWriter
|
type Handler func(*http.Request, *Context) ResponseWriterWriter
|
||||||
|
|
||||||
type APIHandler struct {
|
type APIHandler struct {
|
||||||
|
@ -335,9 +335,10 @@ func OFXFileImportHandler(context *Context, r *http.Request, user *User, account
|
|||||||
/*
|
/*
|
||||||
* Assumes the User is a valid, signed-in user, but accountid has not yet been validated
|
* Assumes the User is a valid, signed-in user, but accountid has not yet been validated
|
||||||
*/
|
*/
|
||||||
func AccountImportHandler(context *Context, r *http.Request, user *User, accountid int64, importtype string) ResponseWriterWriter {
|
func AccountImportHandler(context *Context, r *http.Request, user *User, accountid int64) ResponseWriterWriter {
|
||||||
|
|
||||||
switch importtype {
|
importType := context.NextLevel()
|
||||||
|
switch importType {
|
||||||
case "ofx":
|
case "ofx":
|
||||||
return OFXImportHandler(context, r, user, accountid)
|
return OFXImportHandler(context, r, user, accountid)
|
||||||
case "ofxfile":
|
case "ofxfile":
|
||||||
|
@ -165,10 +165,7 @@ func PriceHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
|
|
||||||
return ResponseWrapper{201, &price}
|
return ResponseWrapper{201, &price}
|
||||||
} else if r.Method == "GET" {
|
} else if r.Method == "GET" {
|
||||||
var priceid int64
|
if context.LastLevel() {
|
||||||
n, err := GetURLPieces(r.URL.Path, "/v1/prices/%d", &priceid)
|
|
||||||
|
|
||||||
if err != nil || n != 1 {
|
|
||||||
//Return all prices
|
//Return all prices
|
||||||
var pl PriceList
|
var pl PriceList
|
||||||
|
|
||||||
@ -180,16 +177,21 @@ func PriceHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
|
|
||||||
pl.Prices = prices
|
pl.Prices = prices
|
||||||
return &pl
|
return &pl
|
||||||
} else {
|
|
||||||
price, err := GetPrice(context.Tx, priceid, user.UserId)
|
|
||||||
if err != nil {
|
|
||||||
return NewError(3 /*Invalid Request*/)
|
|
||||||
}
|
|
||||||
|
|
||||||
return price
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priceid, err := context.NextID()
|
||||||
|
if err != nil {
|
||||||
|
return NewError(3 /*Invalid Request*/)
|
||||||
|
}
|
||||||
|
|
||||||
|
price, err := GetPrice(context.Tx, priceid, user.UserId)
|
||||||
|
if err != nil {
|
||||||
|
return NewError(3 /*Invalid Request*/)
|
||||||
|
}
|
||||||
|
|
||||||
|
return price
|
||||||
} else {
|
} else {
|
||||||
priceid, err := GetURLID(r.URL.Path)
|
priceid, err := context.NextID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(3 /*Invalid Request*/)
|
return NewError(3 /*Invalid Request*/)
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,10 @@ import (
|
|||||||
"github.com/yuin/gopher-lua"
|
"github.com/yuin/gopher-lua"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var reportTabulationRE *regexp.Regexp
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
reportTabulationRE = regexp.MustCompile(`^/v1/reports/[0-9]+/tabulations/?$`)
|
|
||||||
}
|
|
||||||
|
|
||||||
//type and value to store user in lua's Context
|
//type and value to store user in lua's Context
|
||||||
type key int
|
type key int
|
||||||
|
|
||||||
@ -255,19 +248,7 @@ func ReportHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
|
|
||||||
return ResponseWrapper{201, &report}
|
return ResponseWrapper{201, &report}
|
||||||
} else if r.Method == "GET" {
|
} else if r.Method == "GET" {
|
||||||
if reportTabulationRE.MatchString(r.URL.Path) {
|
if context.LastLevel() {
|
||||||
var reportid int64
|
|
||||||
n, err := GetURLPieces(r.URL.Path, "/v1/reports/%d/tabulations", &reportid)
|
|
||||||
if err != nil || n != 1 {
|
|
||||||
log.Print(err)
|
|
||||||
return NewError(999 /*InternalError*/)
|
|
||||||
}
|
|
||||||
return ReportTabulationHandler(context.Tx, r, user, reportid)
|
|
||||||
}
|
|
||||||
|
|
||||||
var reportid int64
|
|
||||||
n, err := GetURLPieces(r.URL.Path, "/v1/reports/%d", &reportid)
|
|
||||||
if err != nil || n != 1 {
|
|
||||||
//Return all Reports
|
//Return all Reports
|
||||||
var rl ReportList
|
var rl ReportList
|
||||||
reports, err := GetReports(context.Tx, user.UserId)
|
reports, err := GetReports(context.Tx, user.UserId)
|
||||||
@ -277,6 +258,15 @@ func ReportHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
}
|
}
|
||||||
rl.Reports = reports
|
rl.Reports = reports
|
||||||
return &rl
|
return &rl
|
||||||
|
}
|
||||||
|
|
||||||
|
reportid, err := context.NextID()
|
||||||
|
if err != nil {
|
||||||
|
return NewError(3 /*Invalid Request*/)
|
||||||
|
}
|
||||||
|
|
||||||
|
if context.NextLevel() == "tabulations" {
|
||||||
|
return ReportTabulationHandler(context.Tx, r, user, reportid)
|
||||||
} else {
|
} else {
|
||||||
// Return Report with this Id
|
// Return Report with this Id
|
||||||
report, err := GetReport(context.Tx, reportid, user.UserId)
|
report, err := GetReport(context.Tx, reportid, user.UserId)
|
||||||
@ -287,7 +277,7 @@ func ReportHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
return report
|
return report
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reportid, err := GetURLID(r.URL.Path)
|
reportid, err := context.NextID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(3 /*Invalid Request*/)
|
return NewError(3 /*Invalid Request*/)
|
||||||
}
|
}
|
||||||
|
@ -274,10 +274,7 @@ func SecurityHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
|
|
||||||
return ResponseWrapper{201, &security}
|
return ResponseWrapper{201, &security}
|
||||||
} else if r.Method == "GET" {
|
} else if r.Method == "GET" {
|
||||||
var securityid int64
|
if context.LastLevel() {
|
||||||
n, err := GetURLPieces(r.URL.Path, "/v1/securities/%d", &securityid)
|
|
||||||
|
|
||||||
if err != nil || n != 1 {
|
|
||||||
//Return all securities
|
//Return all securities
|
||||||
var sl SecurityList
|
var sl SecurityList
|
||||||
|
|
||||||
@ -290,6 +287,10 @@ func SecurityHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
sl.Securities = securities
|
sl.Securities = securities
|
||||||
return &sl
|
return &sl
|
||||||
} else {
|
} else {
|
||||||
|
securityid, err := context.NextID()
|
||||||
|
if err != nil {
|
||||||
|
return NewError(3 /*Invalid Request*/)
|
||||||
|
}
|
||||||
security, err := GetSecurity(context.Tx, securityid, user.UserId)
|
security, err := GetSecurity(context.Tx, securityid, user.UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(3 /*Invalid Request*/)
|
return NewError(3 /*Invalid Request*/)
|
||||||
@ -298,7 +299,7 @@ func SecurityHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
return security
|
return security
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
securityid, err := GetURLID(r.URL.Path)
|
securityid, err := context.NextID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(3 /*Invalid Request*/)
|
return NewError(3 /*Invalid Request*/)
|
||||||
}
|
}
|
||||||
|
@ -452,9 +452,7 @@ func TransactionHandler(r *http.Request, context *Context) ResponseWriterWriter
|
|||||||
|
|
||||||
return &transaction
|
return &transaction
|
||||||
} else if r.Method == "GET" {
|
} else if r.Method == "GET" {
|
||||||
transactionid, err := GetURLID(r.URL.Path)
|
if context.LastLevel() {
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
//Return all Transactions
|
//Return all Transactions
|
||||||
var al TransactionList
|
var al TransactionList
|
||||||
transactions, err := GetTransactions(context.Tx, user.UserId)
|
transactions, err := GetTransactions(context.Tx, user.UserId)
|
||||||
@ -466,6 +464,10 @@ func TransactionHandler(r *http.Request, context *Context) ResponseWriterWriter
|
|||||||
return &al
|
return &al
|
||||||
} else {
|
} else {
|
||||||
//Return Transaction with this Id
|
//Return Transaction with this Id
|
||||||
|
transactionid, err := context.NextID()
|
||||||
|
if err != nil {
|
||||||
|
return NewError(3 /*Invalid Request*/)
|
||||||
|
}
|
||||||
transaction, err := GetTransaction(context.Tx, transactionid, user.UserId)
|
transaction, err := GetTransaction(context.Tx, transactionid, user.UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(3 /*Invalid Request*/)
|
return NewError(3 /*Invalid Request*/)
|
||||||
@ -473,7 +475,7 @@ func TransactionHandler(r *http.Request, context *Context) ResponseWriterWriter
|
|||||||
return transaction
|
return transaction
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
transactionid, err := GetURLID(r.URL.Path)
|
transactionid, err := context.NextID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(3 /*Invalid Request*/)
|
return NewError(3 /*Invalid Request*/)
|
||||||
}
|
}
|
||||||
@ -518,11 +520,6 @@ func TransactionHandler(r *http.Request, context *Context) ResponseWriterWriter
|
|||||||
|
|
||||||
return &transaction
|
return &transaction
|
||||||
} else if r.Method == "DELETE" {
|
} else if r.Method == "DELETE" {
|
||||||
transactionid, err := GetURLID(r.URL.Path)
|
|
||||||
if err != nil {
|
|
||||||
return NewError(3 /*Invalid Request*/)
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction, err := GetTransaction(context.Tx, transactionid, user.UserId)
|
transaction, err := GetTransaction(context.Tx, transactionid, user.UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(3 /*Invalid Request*/)
|
return NewError(3 /*Invalid Request*/)
|
||||||
|
@ -207,7 +207,7 @@ func UserHandler(r *http.Request, context *Context) ResponseWriterWriter {
|
|||||||
return NewError(1 /*Not Signed In*/)
|
return NewError(1 /*Not Signed In*/)
|
||||||
}
|
}
|
||||||
|
|
||||||
userid, err := GetURLID(r.URL.Path)
|
userid, err := context.NextID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewError(3 /*Invalid Request*/)
|
return NewError(3 /*Invalid Request*/)
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,8 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetURLID(url string) (int64, error) {
|
|
||||||
pieces := strings.Split(strings.Trim(url, "/"), "/")
|
|
||||||
return strconv.ParseInt(pieces[len(pieces)-1], 10, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetURLPieces(url string, format string, a ...interface{}) (int, error) {
|
|
||||||
url = strings.Replace(url, "/", " ", -1)
|
|
||||||
format = strings.Replace(format, "/", " ", -1)
|
|
||||||
return fmt.Sscanf(url, format, a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResponseWrapper struct {
|
type ResponseWrapper struct {
|
||||||
Code int
|
Code int
|
||||||
Writer ResponseWriterWriter
|
Writer ResponseWriterWriter
|
||||||
|
Loading…
Reference in New Issue
Block a user