Skip to content
This repository has been archived by the owner on Sep 12, 2019. It is now read-only.

Commit

Permalink
Merge pull request #82 from stellar/auth-response-errors
Browse files Browse the repository at this point in the history
Auth response errors
  • Loading branch information
bartekn authored Nov 14, 2017
2 parents d3f973b + 5fd07b4 commit cb47973
Show file tree
Hide file tree
Showing 457 changed files with 54,372 additions and 512 deletions.
12 changes: 9 additions & 3 deletions readme_compliance.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,14 @@ The customer information that is exchanged between FIs is flexible but the typic
Respond with one of the following status codes:
* `200 OK` when sender/receiver is allowed and the payment should be processed,
* `202 Accepted` when your callback needs some time for processing,
* `400 Bad Request` when sender info is invalid.
* `403 Forbidden` when sender/receiver is denied.

Any other status code will be considered an error.

When `202 Accepted` is returned the response body should contain JSON object with a `pending` field which represents the estimated number of seconds needed for processing. For example, the following response means to try the payment again in an hour.
When `202 Accepted` is returned the response body should contain JSON object with `pending` field which represents the estimated number of seconds needed for processing. For example, the following response means to try the payment again in an hour.

When `400 Bad Request` is returned the response body should contain JSON object with `error` field with error string.

```json
{"pending": 3600}
Expand Down Expand Up @@ -212,11 +215,14 @@ The customer information (`sender`) that is exchanged between FIs is flexible bu
Respond with one of the following status codes:
* `200 OK` when your customer has allowed sharing his/her compliance information with the requesting FI.
* `202 Accepted` when your callback needs some time for processing, ie to ask the customer.
* `400 Bad Request` when request data is invalid.
* `403 Forbidden` when your customer has denied sharing his/her compliance information with the requesting FI.

Any other status code will be considered an error.

When `202 Accepted` is returned the response body should contain JSON object with `pending` field which represents estimated number of seconds needed for processing. For example, the following response means to try the payment again in an hour:
When `202 Accepted` is returned the response body should contain JSON object with `pending` field which represents estimated number of seconds needed for processing. For example, the following response means to try the payment again in an hour.

When `400 Bad Request` is returned the response body should contain JSON object with `error` field with error string.

```json
{"pending": 3600}
Expand Down Expand Up @@ -244,7 +250,7 @@ This callback should return `200 OK` status code and JSON object with the custom
}
```
### `callbacks.tx_status`
This callback should return the status of a transaction as explained in [`SEP-0001`](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md).
This callback should return the status of a transaction as explained in [`SEP-0004`](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0004.md).

#### Request

Expand Down
2 changes: 1 addition & 1 deletion src/github.com/stellar/gateway/bridge/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"errors"
"flag"
"fmt"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"net/http"
"net/http/httputil"
"net/url"
Expand Down
18 changes: 9 additions & 9 deletions src/github.com/stellar/gateway/bridge/gui/bindata.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,10 @@ func AssetNames() []string {

// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
"app.js": appJs,
"app.js.map": appJsMap,
"index.html": indexHtml,
"vendor.js": vendorJs,
"app.js": appJs,
"app.js.map": appJsMap,
"index.html": indexHtml,
"vendor.js": vendorJs,
"vendor.js.map": vendorJsMap,
}

Expand Down Expand Up @@ -270,11 +270,12 @@ type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
}

var _bintree = &bintree{nil, map[string]*bintree{
"app.js": &bintree{appJs, map[string]*bintree{}},
"app.js.map": &bintree{appJsMap, map[string]*bintree{}},
"index.html": &bintree{indexHtml, map[string]*bintree{}},
"vendor.js": &bintree{vendorJs, map[string]*bintree{}},
"app.js": &bintree{appJs, map[string]*bintree{}},
"app.js.map": &bintree{appJsMap, map[string]*bintree{}},
"index.html": &bintree{indexHtml, map[string]*bintree{}},
"vendor.js": &bintree{vendorJs, map[string]*bintree{}},
"vendor.js.map": &bintree{vendorJsMap, map[string]*bintree{}},
}}

Expand Down Expand Up @@ -324,4 +325,3 @@ func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"net/url"
"strconv"

log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/stellar/gateway/db/entities"
"github.com/stellar/gateway/horizon"
"github.com/stellar/gateway/protocols"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package handlers

import (
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"net/http"

"github.com/stellar/gateway/protocols"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package handlers

import (
"encoding/json"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"net/http"
"strconv"

Expand Down Expand Up @@ -49,7 +49,7 @@ func (rh *RequestHandler) Builder(w http.ResponseWriter, r *http.Request) {
return
}
sequenceNumber, err = strconv.ParseUint(accountResponse.SequenceNumber, 10, 64)
}else{
} else {
sequenceNumber, err = strconv.ParseUint(request.SequenceNumber, 10, 64)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package handlers

import (
"encoding/json"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"net/http"

"github.com/stellar/gateway/protocols"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"io/ioutil"
"net/http"
"strconv"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package handlers
import (
"net/http"

log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"github.com/stellar/gateway/protocols"
"github.com/stellar/gateway/protocols/bridge"
"github.com/stellar/gateway/server"
Expand Down
2 changes: 1 addition & 1 deletion src/github.com/stellar/gateway/cmd/bridge/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package main

import (
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"runtime"

"github.com/spf13/cobra"
Expand Down
2 changes: 1 addition & 1 deletion src/github.com/stellar/gateway/cmd/compliance/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package main
import (
"runtime"

log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"

"github.com/spf13/cobra"
"github.com/spf13/viper"
Expand Down
2 changes: 1 addition & 1 deletion src/github.com/stellar/gateway/compliance/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"os"
"time"

log "github.com/Sirupsen/logrus"
"github.com/goji/httpauth"
log "github.com/sirupsen/logrus"

"github.com/facebookgo/inject"
"github.com/stellar/gateway/compliance/config"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package handlers

import (
log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"
"net/http"
"time"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"strings"
"time"

log "github.com/Sirupsen/logrus"
log "github.com/sirupsen/logrus"

"github.com/stellar/gateway/db/entities"
"github.com/stellar/gateway/protocols"
Expand Down Expand Up @@ -182,15 +182,26 @@ func (rh *RequestHandler) HandlerAuth(c web.C, w http.ResponseWriter, r *http.Re
case http.StatusAccepted: // AuthStatusPending
response.TxStatus = compliance.AuthStatusPending

pendingResponse := struct {
Pending int `json:"pending"`
}{}
err := json.Unmarshal(body, &pendingResponse)
callbackResponse := callback.CallbackResponse{}
err := json.Unmarshal(body, &callbackResponse)
if err != nil {
// Set default value
response.Pending = 600
} else {
response.Pending = pendingResponse.Pending
response.Pending = callbackResponse.Pending
}
case http.StatusBadRequest: // AuthStatusError
response.TxStatus = compliance.AuthStatusError

callbackResponse := callback.CallbackResponse{}
err := json.Unmarshal(body, &callbackResponse)
if err != nil {
log.WithFields(log.Fields{
"status": resp.StatusCode,
"body": string(body),
}).Error("Error response from sanctions server")
} else {
response.Error = callbackResponse.Error
}
case http.StatusForbidden: // AuthStatusDenied
response.TxStatus = compliance.AuthStatusDenied
Expand Down Expand Up @@ -296,15 +307,26 @@ func (rh *RequestHandler) HandlerAuth(c web.C, w http.ResponseWriter, r *http.Re
case http.StatusAccepted: // AuthStatusPending
response.InfoStatus = compliance.AuthStatusPending

pendingResponse := struct {
Pending int `json:"pending"`
}{}
err := json.Unmarshal(body, &pendingResponse)
callbackResponse := callback.CallbackResponse{}
err := json.Unmarshal(body, &callbackResponse)
if err != nil {
// Set default value
response.Pending = 600
} else {
response.Pending = pendingResponse.Pending
response.Pending = callbackResponse.Pending
}
case http.StatusBadRequest: // AuthStatusError
response.InfoStatus = compliance.AuthStatusError

callbackResponse := callback.CallbackResponse{}
err := json.Unmarshal(body, &callbackResponse)
if err != nil {
log.WithFields(log.Fields{
"status": resp.StatusCode,
"body": string(body),
}).Error("Error response from sanctions server")
} else {
response.Error = callbackResponse.Error
}
case http.StatusForbidden: // AuthStatusDenied
response.InfoStatus = compliance.AuthStatusDenied
Expand Down Expand Up @@ -362,6 +384,7 @@ func (rh *RequestHandler) HandlerAuth(c web.C, w http.ResponseWriter, r *http.Re
}

if response.TxStatus == compliance.AuthStatusOk && response.InfoStatus == compliance.AuthStatusOk {
w.WriteHeader(http.StatusOK)
authorizedTransaction := &entities.AuthorizedTransaction{
TransactionID: hex.EncodeToString(transactionHash[:]),
Memo: base64.StdEncoding.EncodeToString(memoBytes[:]),
Expand All @@ -375,6 +398,12 @@ func (rh *RequestHandler) HandlerAuth(c web.C, w http.ResponseWriter, r *http.Re
server.Write(w, protocols.InternalServerError)
return
}
} else if response.TxStatus == compliance.AuthStatusDenied || response.InfoStatus == compliance.AuthStatusDenied {
w.WriteHeader(http.StatusForbidden)
} else if response.TxStatus == compliance.AuthStatusError || response.InfoStatus == compliance.AuthStatusError {
w.WriteHeader(http.StatusBadRequest)
} else if response.TxStatus == compliance.AuthStatusPending || response.InfoStatus == compliance.AuthStatusPending {
w.WriteHeader(http.StatusAccepted)
}

responseBody, err := response.Marshal()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,14 +387,35 @@ func TestRequestHandlerAuth(t *testing.T) {

statusCode, response := net.GetResponse(testServer, params)
responseString := strings.TrimSpace(string(response))
assert.Equal(t, 200, statusCode)
assert.Equal(t, 403, statusCode)
expected := test.StringToJSONMap(`{
"info_status": "ok",
"tx_status": "denied"
}`)
assert.Equal(t, expected, test.StringToJSONMap(responseString))
})

Convey("when sanctions server returns bad request it returns tx_status `error`", func() {
mockHTTPClient.On(
"PostForm",
"http://sanctions",
url.Values{"sender": {string(senderInfoJSON)}},
).Return(
net.BuildHTTPResponse(400, "{\"error\": \"Invalid name\"}"),
nil,
).Once()

statusCode, response := net.GetResponse(testServer, params)
responseString := strings.TrimSpace(string(response))
assert.Equal(t, 400, statusCode)
expected := test.StringToJSONMap(`{
"info_status": "ok",
"tx_status": "error",
"error": "Invalid name"
}`)
assert.Equal(t, expected, test.StringToJSONMap(responseString))
})

Convey("when sanctions server returns accepted it returns tx_status `pending`", func() {
mockHTTPClient.On(
"PostForm",
Expand All @@ -407,7 +428,7 @@ func TestRequestHandlerAuth(t *testing.T) {

statusCode, response := net.GetResponse(testServer, params)
responseString := strings.TrimSpace(string(response))
assert.Equal(t, 200, statusCode)
assert.Equal(t, 202, statusCode)
expected := test.StringToJSONMap(`{
"info_status": "ok",
"tx_status": "pending",
Expand Down Expand Up @@ -516,14 +537,41 @@ func TestRequestHandlerAuth(t *testing.T) {

statusCode, response := net.GetResponse(testServer, params)
responseString := strings.TrimSpace(string(response))
assert.Equal(t, 200, statusCode)
assert.Equal(t, 403, statusCode)
expected := test.StringToJSONMap(`{
"info_status": "denied",
"tx_status": "ok"
}`)
assert.Equal(t, expected, test.StringToJSONMap(responseString))
})

Convey("when ask_user server returns bad request it returns info_status `error`", func() {
mockHTTPClient.On(
"PostForm",
"http://ask_user",
url.Values{
"sender": {string(senderInfoJSON)},
"note": {attachment.Transaction.Note},
"amount": {"20.0000000"},
"asset_code": {"USD"},
"asset_issuer": {"GAMVF7G4GJC4A7JMFJWLUAEIBFQD5RT3DCB5DC5TJDEKQBBACQ4JZVEE"},
},
).Return(
net.BuildHTTPResponse(400, "{\"error\": \"Invalid name\"}"),
nil,
).Once()

statusCode, response := net.GetResponse(testServer, params)
responseString := strings.TrimSpace(string(response))
assert.Equal(t, 400, statusCode)
expected := test.StringToJSONMap(`{
"info_status": "error",
"tx_status": "ok",
"error": "Invalid name"
}`)
assert.Equal(t, expected, test.StringToJSONMap(responseString))
})

Convey("when ask_user server returns pending it returns info_status `pending`", func() {
mockHTTPClient.On(
"PostForm",
Expand All @@ -542,7 +590,7 @@ func TestRequestHandlerAuth(t *testing.T) {

statusCode, response := net.GetResponse(testServer, params)
responseString := strings.TrimSpace(string(response))
assert.Equal(t, 200, statusCode)
assert.Equal(t, 202, statusCode)
expected := test.StringToJSONMap(`{
"info_status": "pending",
"tx_status": "ok",
Expand All @@ -569,7 +617,7 @@ func TestRequestHandlerAuth(t *testing.T) {

statusCode, response := net.GetResponse(testServer, params)
responseString := strings.TrimSpace(string(response))
assert.Equal(t, 200, statusCode)
assert.Equal(t, 202, statusCode)
expected := test.StringToJSONMap(`{
"info_status": "pending",
"tx_status": "ok",
Expand Down Expand Up @@ -761,7 +809,7 @@ func TestRequestHandlerAuth(t *testing.T) {

statusCode, response := net.GetResponse(testServer, params)
responseString := strings.TrimSpace(string(response))
assert.Equal(t, 200, statusCode)
assert.Equal(t, 403, statusCode)
expected := test.StringToJSONMap(`{
"info_status": "denied",
"tx_status": "ok"
Expand Down
Loading

0 comments on commit cb47973

Please sign in to comment.