]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git/commitdiff
Add column 'status' to market_configs. v0.0.9
authorjloup <jeanloup.jamet@gmail.com>
Thu, 10 May 2018 14:22:29 +0000 (16:22 +0200)
committerjloup <jeanloup.jamet@gmail.com>
Thu, 10 May 2018 14:22:29 +0000 (16:22 +0200)
api/api.go
api/external_services.go
api/market_config.go
cmd/web/js/account.jsx
db/market_config.go
db/migrations.go
markets/poloniex.go

index ece2a26aee852a63727a56bac5fd3faac9da4ccf..79a13a5663fb5f2081458db268a0baefd7ed9731 100644 (file)
@@ -58,6 +58,9 @@ func ErrorIs(err error, code ErrorCode) bool {
 }
 
 func NewInternalError(err error) *Error {
+       if apiError, ok := err.(*Error); ok {
+               return apiError
+       }
        return &Error{InternalError, "internal error", err}
 }
 
index c467171d275002768f9fc03dbdf26880eeed9bd4..41f4d872381cfe9fd3dab1eb58992508f9ead21e 100644 (file)
@@ -7,8 +7,8 @@ import (
 )
 
 // Use this to call external services. It will handle timeout and request cancellation gracefully.
-func CallExternalService(tag string, timeout time.Duration, routine func() *Error) *Error {
-       routineDone := make(chan *Error)
+func CallExternalService(tag string, timeout time.Duration, routine func() error) error {
+       routineDone := make(chan error)
 
        go func() {
                routineDone <- routine()
index 81a92d1e6d35fb476b9ddd79ff97e6f487347122..e7b2341760f0d4a64df680767de8b0ea2afeb5ff 100644 (file)
@@ -75,11 +75,11 @@ func (q TestMarketCredentialsQuery) Run() (interface{}, *Error) {
                return nil, NewInternalError(err)
        }
 
-       if config.Config["key"] == "" || config.Config["secret"] == "" {
+       if config == nil || config.Config["key"] == "" || config.Config["secret"] == "" {
                return nil, &Error{InvalidMarketCredentials, "no market credentials", fmt.Errorf("market credentials are empty for marketId '%v'", q.In.Market)}
        }
 
-       resultErr := CallExternalService(fmt.Sprintf("'%s' GetBalanceValue", q.In.Market), EXTERNAL_SERVICE_TIMEOUT_SECONDS*time.Second, func() *Error {
+       resultErr := CallExternalService(fmt.Sprintf("'%s' TestCredentials", q.In.Market), EXTERNAL_SERVICE_TIMEOUT_SECONDS*time.Second, func() error {
                err := Poloniex.TestCredentials(config.Config["key"], config.Config["secret"])
 
                if utils.ErrIs(err, markets.InvalidCredentials) {
@@ -98,7 +98,7 @@ func (q TestMarketCredentialsQuery) Run() (interface{}, *Error) {
        })
 
        if resultErr != nil {
-               return nil, resultErr
+               return nil, NewInternalError(resultErr)
        }
 
        return nil, nil
@@ -133,7 +133,38 @@ func (q UpdateMarketConfigQuery) Run() (interface{}, *Error) {
                configMap["secret"] = q.In.Secret
        }
 
-       _, err := db.SetUserMarketConfig(q.In.User.Id, q.In.Market, configMap)
+       marketConfig, err := db.SetUserMarketConfig(q.In.User.Id, q.In.Market, configMap)
+       if err != nil {
+               return nil, NewInternalError(err)
+       }
+
+       resultErr := CallExternalService(fmt.Sprintf("'%s' TestCredentials", q.In.Market), EXTERNAL_SERVICE_TIMEOUT_SECONDS*time.Second, func() error {
+               err := Poloniex.TestCredentials(marketConfig.Config["key"], marketConfig.Config["secret"])
+
+               if utils.ErrIs(err, markets.InvalidCredentials) {
+                       return &Error{InvalidMarketCredentials, "wrong market credentials", fmt.Errorf("wrong '%v' market credentials", q.In.Market)}
+               }
+
+               if utils.ErrIs(err, markets.IPRestricted) {
+                       return &Error{IPRestrictedApiKey, "ip restricted api key", fmt.Errorf("'%v' ip restricted", q.In.Market)}
+               }
+
+               if err != nil {
+                       return NewInternalError(err)
+               }
+
+               return nil
+       })
+
+       var newStatus db.MarketConfigStatus = db.MarketConfigEnabled
+
+       if ErrorIs(resultErr, InvalidMarketCredentials) || ErrorIs(resultErr, IPRestrictedApiKey) {
+               newStatus = db.MarketConfigInvalidCredentials
+       } else if resultErr != nil {
+               return nil, NewInternalError(resultErr)
+       }
+
+       marketConfig, err = db.SetMarketConfigStatus(*marketConfig, newStatus)
        if err != nil {
                return nil, NewInternalError(err)
        }
index d30abe7e229a157a627aab99a8c55f55c33cd329..03ca117b756db7a222ddf21b5d1e76d7ecc0ff13 100644 (file)
@@ -28,9 +28,15 @@ class PoloniexConfiguration extends React.Component {
   }
 
   handleCredentialsSubmit = () => {
+    this.setState({'status': 'loading'});
     Api.Call('UPDATE_MARKET', {'key': this.state.apiKey, 'secret': this.state.apiSecret, 'name': 'poloniex'}, function(err, status, data) {
       if (err) {
         console.error(err, data);
+        if (err.code === 'invalid_market_credentials') {
+          this.setState({'status': 'invalidCredentials'});
+        } else if (err.code === 'ip_restricted_api_key') {
+          this.setState({'status': 'ipRestricted'});
+        }
         return;
       }
 
index b26c0920bf30bbfcfda36478589c4a57d19437e0..30b453877464c08255f85413bb1b5015299a72b6 100644 (file)
@@ -1,11 +1,20 @@
 package db
 
-import "github.com/go-pg/pg"
+import (
+       "github.com/go-pg/pg"
+)
+
+type MarketConfigStatus string
+
+const MarketConfigEnabled = "enabled"
+const MarketConfigDisabled = "disabled"
+const MarketConfigInvalidCredentials = "invalid_credentials"
 
 type MarketConfig struct {
        Id         int64
-       MarketName string `sql:",notnull"`
-       UserId     int64  `sql:",notnull"`
+       MarketName string
+       UserId     int64
+       Status     MarketConfigStatus
        Config     map[string]string
 }
 
@@ -43,3 +52,13 @@ func SetUserMarketConfig(userId int64, market string, newConfig map[string]strin
 
        return &config, err
 }
+
+func SetMarketConfigStatus(marketConfig MarketConfig, status MarketConfigStatus) (*MarketConfig, error) {
+       marketConfig.Status = status
+       _, err := DB.Model(&marketConfig).
+               OnConflict("(user_id, market_name) DO UPDATE").
+               Set("status = ?", status).
+               Insert()
+
+       return &marketConfig, err
+}
index f6ecb601bce9ee31c3b31bebd624647eb29ac884..f0df49c6b9c4339965f783abd24c6111f85e7164 100644 (file)
@@ -78,4 +78,15 @@ var migrations []Migration = []Migration{
                },
                Down: []string{"DROP VIEW view_balances", "DROP INDEX checkpoints_idx"},
        },
+       {
+               Version: 201805101000,
+               Up: []string{
+                       "CREATE TYPE market_config_status AS ENUM ('enabled', 'disabled', 'invalid_credentials')",
+                       "ALTER TABLE market_configs ADD status market_config_status NOT NULL DEFAULT 'disabled'",
+               },
+               Down: []string{
+                       "ALTER TABLE market_configs DROP COLUMN status",
+                       "DROP TYPE market_config_status",
+               },
+       },
 }
index 58645b2b2a23750c4adae2633e7c7297bfb71d19..cadc8295c2464c6dedbab9306671eeea4ae7a031 100644 (file)
@@ -20,7 +20,7 @@ func poloniexInvalidCredentialsError(err error) bool {
        if err == nil {
                return false
        }
-       return strings.Contains(err.Error(), "Invalid API key/secret pair")
+       return strings.Contains(err.Error(), "Invalid API key/secret pair") || strings.Contains(err.Error(), "Set the API KEY and API SECRET")
 }
 
 func poloniexRestrictedIPError(err error) bool {
@@ -65,7 +65,7 @@ func (p *Poloniex) TestCredentials(apiKey, apiSecret string) error {
                return utils.Error{IPRestricted, "IP restricted api key"}
        }
 
-       return nil
+       return err
 }
 
 func (p *Poloniex) GetBalance(apiKey, apiSecret string) (Summary, error) {