From a94ba130f641e25bcd308eb082e7e3a591439797 Mon Sep 17 00:00:00 2001 From: Gosuke Miyashita Date: Mon, 27 Aug 2018 16:54:43 +0900 Subject: [PATCH] Modify how to return server response When failing to get Apple Root Certificate, nolmandy-server returns a response like this: ``` {"status":21100,"is-retryable":true} ``` When failing to parse receipt data, nolmandy-server returns a response like this: ``` {"status":21002} ``` --- receipt/receipt.go | 18 +++++++++++++----- server/server.go | 39 +++++++++++++++++++++++++-------------- server/server_test.go | 36 +++++++++++++++++++++++++----------- 3 files changed, 63 insertions(+), 30 deletions(-) diff --git a/receipt/receipt.go b/receipt/receipt.go index b082400..d5e3488 100644 --- a/receipt/receipt.go +++ b/receipt/receipt.go @@ -15,15 +15,14 @@ import ( // Result is the validation result type Result struct { Status int `json:"status"` - Environment string `json:"environment"` - Receipt *Receipt `json:"receipt"` + Environment string `json:"environment,omitempty"` + Receipt *Receipt `json:"receipt,omitempty"` LatestReceiptInfo []InApp `json:"latest_receipt_info,omitempty"` LatestReceipt string `json:"latest_receipt,omitempty"` IsRetryable bool `json:"is-retryable,omitempty"` } -// ParseWithAppleRootCert parses base 64 encoded receipt data with Apple Inc Root Certificate -func ParseWithAppleRootCert(data string) (*Receipt, error) { +func GetAppleRootCert() (*x509.Certificate, error) { statikFS, err := fs.New() if err != nil { return nil, err @@ -44,7 +43,16 @@ func ParseWithAppleRootCert(data string) (*Receipt, error) { return nil, err } - return Parse(rootCert, data) + return rootCert, nil +} + +// ParseWithAppleRootCert parses base 64 encoded receipt data with Apple Inc Root Certificate +func ParseWithAppleRootCert(data string) (*Receipt, error) { + cert, err := GetAppleRootCert() + if err != nil { + return nil, err + } + return Parse(cert, data) } // Parse parsed base 64 encoded receipt data with a given certificate diff --git a/server/server.go b/server/server.go index 50ce653..a2393e2 100644 --- a/server/server.go +++ b/server/server.go @@ -29,29 +29,40 @@ func Parse(cert *x509.Certificate) func(http.ResponseWriter, *http.Request) { json.NewDecoder(r.Body).Decode(&request) var rcpt *receipt.Receipt + var result receipt.Result var err error if cert == nil { - rcpt, err = receipt.ParseWithAppleRootCert(request.ReceiptData) - } else { - rcpt, err = receipt.Parse(cert, request.ReceiptData) - } - - if err != nil { - log.Print(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return + cert, err = receipt.GetAppleRootCert() + if err != nil { + log.Print(err) + result.Status = 21100 + result.IsRetryable = true + writeResult(w, result) + return + } } - result, err := rcpt.Validate() + rcpt, err = receipt.Parse(cert, request.ReceiptData) - resultBody, err := json.Marshal(result) if err != nil { log.Print(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return + result.Status = 21002 + } else { + result, err = rcpt.Validate() } - w.Write(resultBody) + writeResult(w, result) } } + +func writeResult(w http.ResponseWriter, result receipt.Result) { + resultBody, err := json.Marshal(result) + if err != nil { + log.Print(err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Write(resultBody) +} diff --git a/server/server_test.go b/server/server_test.go index 527c2cd..5859b18 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -13,7 +13,29 @@ import ( "github.com/aktsk/nolmandy/receipt" ) -func TestServer(t *testing.T) { +func TestInvalidReceipt(t *testing.T) { + result := request(t, "invalid receipt") + + if result.Status != 21002 { + t.Fatalf("Status should be 21002, not %d", result.Status) + } +} + +func TestValidReceipt(t *testing.T) { + result := request(t, receiptData) + + if result.Status != 0 { + t.Fatalf("Status should be 0, not %d", result.Status) + } + + rcpt := result.Receipt + + if rcpt.ReceiptType != "ProductionSandbox" { + t.Fatalf("Wrong receipt_type: %s", rcpt.ReceiptType) + } +} + +func request(t *testing.T, data string) receipt.Result { certDER, _ := pem.Decode([]byte(certificate)) cert, err := x509.ParseCertificate(certDER.Bytes) if err != nil { @@ -23,7 +45,7 @@ func TestServer(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(Parse(cert))) defer s.Close() - req := Request{ReceiptData: receiptData} + req := Request{ReceiptData: data} reqBody, err := json.Marshal(req) if err != nil { t.Fatal(err) @@ -42,15 +64,7 @@ func TestServer(t *testing.T) { var result receipt.Result json.Unmarshal(respBody, &result) - if result.Status != 0 { - t.Fatal("Status is not 0") - } - - rcpt := result.Receipt - - if rcpt.ReceiptType != "ProductionSandbox" { - t.Fatalf("Wrong receipt_type: %s", rcpt.ReceiptType) - } + return result } var receiptData = `