mirror of
				https://github.com/aclindsa/moneygo.git
				synced 2025-10-31 01:43:26 -04:00 
			
		
		
		
	Move to a consistent way of handling IDs in URLs
This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user