aboutsummaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/api.go43
-rw-r--r--api/const.go74
-rw-r--r--api/const_string.go14
-rw-r--r--api/logger.go12
-rw-r--r--api/market_config.go19
-rw-r--r--api/routes.go2
6 files changed, 96 insertions, 68 deletions
diff --git a/api/api.go b/api/api.go
index e011811..f921301 100644
--- a/api/api.go
+++ b/api/api.go
@@ -5,6 +5,7 @@ import (
5 "unicode" 5 "unicode"
6 6
7 "github.com/gin-gonic/gin" 7 "github.com/gin-gonic/gin"
8 "github.com/jloup/utils"
8) 9)
9 10
10var CONFIG Config 11var CONFIG Config
@@ -43,11 +44,30 @@ func SetMailConfig(config MailConfig) {
43} 44}
44 45
45type Error struct { 46type Error struct {
46 Code ErrorCode 47 Code utils.Flag
47 UserMessage string 48 UserMessage string
48 err error 49 err error
49} 50}
50 51
52func (e Error) FlagString() string {
53 return e.Code.String()
54}
55
56func (e Error) Flag() utils.Flag {
57 return e.Code
58}
59
60func (e Error) Msg() string {
61 return e.UserMessage
62}
63
64func (e Error) ErrorWithCode(f utils.Flag) utils.ErrorFlagged {
65 if utils.Intersect(e.Code, f) {
66 return e
67 }
68
69 return nil
70}
51func (e Error) Err() error { 71func (e Error) Err() error {
52 if e.err != nil { 72 if e.err != nil {
53 return e 73 return e
@@ -64,7 +84,7 @@ func (e Error) Error() string {
64 return "" 84 return ""
65} 85}
66 86
67func ErrorIs(err error, code ErrorCode) bool { 87func ErrorIs(err error, code utils.Flag) bool {
68 if err == nil { 88 if err == nil {
69 return false 89 return false
70 } 90 }
@@ -72,7 +92,7 @@ func ErrorIs(err error, code ErrorCode) bool {
72 if apiError, ok := err.(*Error); !ok { 92 if apiError, ok := err.(*Error); !ok {
73 return false 93 return false
74 } else { 94 } else {
75 return apiError.Code == code 95 return utils.Intersect(apiError.Code, code) && apiError.Code.String() == code.String()
76 } 96 }
77} 97}
78 98
@@ -99,8 +119,8 @@ func ToSnake(in string) string {
99} 119}
100 120
101type Response struct { 121type Response struct {
102 StatusCode Status `json:"-"` 122 StatusCode Status `json:"-"`
103 ErrorCode ErrorCode `json:"-"` 123 ErrorCode utils.Flag `json:"-"`
104 124
105 Status string `json:"status"` 125 Status string `json:"status"`
106 Code string `json:"code,omitempty"` 126 Code string `json:"code,omitempty"`
@@ -110,15 +130,12 @@ type Response struct {
110 130
111func (r Response) populateStatus() Response { 131func (r Response) populateStatus() Response {
112 r.Status = ToSnake(r.StatusCode.String()) 132 r.Status = ToSnake(r.StatusCode.String())
113 133 r.Code = ToSnake(r.ErrorCode.String())
114 if r.ErrorCode != 0 {
115 r.Code = ToSnake(r.ErrorCode.String())
116 }
117 134
118 return r 135 return r
119} 136}
120 137
121func ErrorResponse(code ErrorCode, message string) Response { 138func ErrorResponse(code utils.Flag, message string) Response {
122 return Response{ 139 return Response{
123 StatusCode: NOK, 140 StatusCode: NOK,
124 ErrorCode: code, 141 ErrorCode: code,
@@ -150,7 +167,7 @@ func M(handler Middleware) gin.HandlerFunc {
150 err := handler(c) 167 err := handler(c)
151 168
152 if err != nil { 169 if err != nil {
153 WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c) 170 WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c)
154 c.Error(err) 171 c.Error(err)
155 c.Abort() 172 c.Abort()
156 } else { 173 } else {
@@ -166,13 +183,13 @@ type Query interface {
166 183
167func RunQuery(query Query, c *gin.Context) { 184func RunQuery(query Query, c *gin.Context) {
168 if err := query.ValidateParams(); err != nil { 185 if err := query.ValidateParams(); err != nil {
169 WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c) 186 WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c)
170 c.Error(err) 187 c.Error(err)
171 return 188 return
172 } 189 }
173 190
174 if out, err := query.Run(); err != nil { 191 if out, err := query.Run(); err != nil {
175 WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c) 192 WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c)
176 c.Error(err) 193 c.Error(err)
177 } else { 194 } else {
178 WriteJsonResponse(SuccessResponse(out), c) 195 WriteJsonResponse(SuccessResponse(out), c)
diff --git a/api/const.go b/api/const.go
index 2ad4d61..4f608d5 100644
--- a/api/const.go
+++ b/api/const.go
@@ -1,58 +1,66 @@
1package api 1package api
2 2
3import "net/http" 3import (
4 "net/http"
4 5
5//go:generate stringer -type=Status,ErrorCode -output const_string.go 6 "github.com/jloup/utils"
7)
8
9//go:generate stringer -type=Status -output const_string.go
6type Status uint32 10type Status uint32
7type ErrorCode uint32
8 11
9const EXTERNAL_SERVICE_TIMEOUT_SECONDS = 20 12const EXTERNAL_SERVICE_TIMEOUT_SECONDS = 20
10 13
11const ( 14const (
12 OK Status = iota 15 OK Status = iota
13 NOK 16 NOK
17)
14 18
15 BadRequest ErrorCode = iota + 1 19var (
16 EmailExists 20 errorFlagCounter utils.Counter = 0
17 ExternalServiceTimeout 21 BadRequest utils.Flag = utils.InitFlag(&errorFlagCounter, "BadRequest")
18 InternalError 22 EmailExists utils.Flag = utils.InitFlag(&errorFlagCounter, "EmailExists")
19 InvalidCredentials 23 ExternalServiceTimeout utils.Flag = utils.InitFlag(&errorFlagCounter, "ExternalServiceTimeout")
20 InvalidEmail 24 InternalError utils.Flag = utils.InitFlag(&errorFlagCounter, "InternalError")
21 InvalidMarketCredentials 25 InvalidCredentials utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidCredentials")
22 MarketCredentialsNotConfigured 26 InvalidEmail utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidEmail")
23 IPRestrictedApiKey 27 InvalidMarketCredentials utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidMarketCredentials")
24 InvalidOtp 28 MarketCredentialsNotConfigured utils.Flag = utils.InitFlag(&errorFlagCounter, "MarketCredentialsNotConfigured")
25 InvalidPassword 29 IPRestrictedApiKey utils.Flag = utils.InitFlag(&errorFlagCounter, "IPRestrictedApiKey")
26 NeedOtpValidation 30 InvalidOtp utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidOtp")
27 NotAuthorized 31 InvalidPassword utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidPassword")
28 NotFound 32 NeedOtpValidation utils.Flag = utils.InitFlag(&errorFlagCounter, "NeedOtpValidation")
29 OtpAlreadySetup 33 NotAuthorized utils.Flag = utils.InitFlag(&errorFlagCounter, "NotAuthorized")
30 OtpNotSetup 34 NotFound utils.Flag = utils.InitFlag(&errorFlagCounter, "NotFound")
31 UserNotConfirmed 35 OtpAlreadySetup utils.Flag = utils.InitFlag(&errorFlagCounter, "OtpAlreadySetup")
36 OtpNotSetup utils.Flag = utils.InitFlag(&errorFlagCounter, "OtpNotSetup")
37 UserNotConfirmed utils.Flag = utils.InitFlag(&errorFlagCounter, "UserNotConfirmed")
38
39 StatusBadRequest utils.Flag = utils.Join("BadRequest", BadRequest, InvalidPassword, InvalidEmail, InvalidMarketCredentials, IPRestrictedApiKey, MarketCredentialsNotConfigured)
40 StatusUnauthorized utils.Flag = utils.Join("Unauthorized", InvalidCredentials, InvalidOtp)
41 StatusForbidden utils.Flag = utils.Join("Forbidden", UserNotConfirmed, NotAuthorized, OtpAlreadySetup, OtpNotSetup, NeedOtpValidation)
42 StatusConflicts utils.Flag = utils.Join("Conflicts", EmailExists)
43 StatusNotFound utils.Flag = utils.Join("NotFound", NotFound)
44 StatusGatewayTimeout utils.Flag = utils.Join("GatewayTimeout", ExternalServiceTimeout)
32) 45)
33 46
34func StatusToHttpCode(status Status, code ErrorCode) int { 47func StatusToHttpCode(status Status, code utils.Flag) int {
35 if status == OK { 48 if status == OK {
36 return http.StatusOK 49 return http.StatusOK
37 } 50 }
38 51
39 switch code { 52 switch {
40 case BadRequest, InvalidPassword, InvalidEmail, InvalidMarketCredentials, IPRestrictedApiKey, MarketCredentialsNotConfigured: 53 case utils.Intersect(code, StatusBadRequest):
41 return http.StatusBadRequest 54 return http.StatusBadRequest
42 55 case utils.Intersect(code, StatusUnauthorized):
43 case InvalidCredentials, InvalidOtp:
44 return http.StatusUnauthorized 56 return http.StatusUnauthorized
45 57 case utils.Intersect(code, StatusForbidden):
46 case UserNotConfirmed, NotAuthorized, OtpAlreadySetup, OtpNotSetup, NeedOtpValidation:
47 return http.StatusForbidden 58 return http.StatusForbidden
48 59 case utils.Intersect(code, StatusConflicts):
49 case EmailExists:
50 return http.StatusConflict 60 return http.StatusConflict
51 61 case utils.Intersect(code, StatusNotFound):
52 case NotFound:
53 return http.StatusNotFound 62 return http.StatusNotFound
54 63 case utils.Intersect(code, StatusGatewayTimeout):
55 case ExternalServiceTimeout:
56 return http.StatusGatewayTimeout 64 return http.StatusGatewayTimeout
57 } 65 }
58 66
diff --git a/api/const_string.go b/api/const_string.go
index 5af7574..c22d1ae 100644
--- a/api/const_string.go
+++ b/api/const_string.go
@@ -1,4 +1,4 @@
1// Code generated by "stringer -type=Status,ErrorCode -output const_string.go"; DO NOT EDIT. 1// Code generated by "stringer -type=Status -output const_string.go"; DO NOT EDIT.
2 2
3package api 3package api
4 4
@@ -14,15 +14,3 @@ func (i Status) String() string {
14 } 14 }
15 return _Status_name[_Status_index[i]:_Status_index[i+1]] 15 return _Status_name[_Status_index[i]:_Status_index[i+1]]
16} 16}
17
18const _ErrorCode_name = "BadRequestEmailExistsExternalServiceTimeoutInternalErrorInvalidCredentialsInvalidEmailInvalidMarketCredentialsMarketCredentialsNotConfiguredIPRestrictedApiKeyInvalidOtpInvalidPasswordNeedOtpValidationNotAuthorizedNotFoundOtpAlreadySetupOtpNotSetupUserNotConfirmed"
19
20var _ErrorCode_index = [...]uint16{0, 10, 21, 43, 56, 74, 86, 110, 140, 158, 168, 183, 200, 213, 221, 236, 247, 263}
21
22func (i ErrorCode) String() string {
23 i -= 3
24 if i >= ErrorCode(len(_ErrorCode_index)-1) {
25 return "ErrorCode(" + strconv.FormatInt(int64(i+3), 10) + ")"
26 }
27 return _ErrorCode_name[_ErrorCode_index[i]:_ErrorCode_index[i+1]]
28}
diff --git a/api/logger.go b/api/logger.go
index a24e08a..5f49d29 100644
--- a/api/logger.go
+++ b/api/logger.go
@@ -2,7 +2,6 @@ package api
2 2
3import ( 3import (
4 "fmt" 4 "fmt"
5 "strings"
6 "time" 5 "time"
7 6
8 "github.com/Sirupsen/logrus" 7 "github.com/Sirupsen/logrus"
@@ -51,11 +50,14 @@ func Logger() gin.HandlerFunc {
51 level = logrus.ErrorLevel 50 level = logrus.ErrorLevel
52 } 51 }
53 52
54 comment := c.Errors.ByType(gin.ErrorTypePrivate).String() 53 errors := c.Errors.ByType(gin.ErrorTypePrivate)
55 if comment != "" { 54
56 msgLog = fmt.Sprintf("%s: %s", msgLog, strings.TrimSpace(comment)) 55 for _, err := range errors {
56 l.Logf(level, "%s: %s", msgLog, err.Err)
57 } 57 }
58 58
59 l.Logf(level, msgLog) 59 if errors == nil {
60 l.Logf(level, msgLog)
61 }
60 } 62 }
61} 63}
diff --git a/api/market_config.go b/api/market_config.go
index e02c3ba..c7e2e15 100644
--- a/api/market_config.go
+++ b/api/market_config.go
@@ -5,9 +5,9 @@ import (
5 "strings" 5 "strings"
6 "time" 6 "time"
7 7
8 "github.com/jloup/utils"
9 "git.immae.eu/Cryptoportfolio/Front.git/db" 8 "git.immae.eu/Cryptoportfolio/Front.git/db"
10 "git.immae.eu/Cryptoportfolio/Front.git/markets" 9 "git.immae.eu/Cryptoportfolio/Front.git/markets"
10 "github.com/jloup/utils"
11) 11)
12 12
13type MarketConfigQuery struct { 13type MarketConfigQuery struct {
@@ -97,10 +97,23 @@ func (q TestMarketCredentialsQuery) Run() (interface{}, *Error) {
97 return nil 97 return nil
98 }) 98 })
99 99
100 if resultErr != nil { 100 var newStatus db.MarketConfigStatus = config.Status
101
102 if ErrorIs(resultErr, InvalidMarketCredentials) || ErrorIs(resultErr, IPRestrictedApiKey) || ErrorIs(resultErr, MarketCredentialsNotConfigured) {
103 newStatus = db.MarketConfigInvalidCredentials
104 } else if resultErr != nil {
105 return nil, NewInternalError(resultErr)
106 } else if resultErr != nil {
101 return nil, NewInternalError(resultErr) 107 return nil, NewInternalError(resultErr)
102 } 108 }
103 109
110 if newStatus != config.Status {
111 config, err = db.SetMarketConfigStatus(*config, newStatus)
112 if err != nil {
113 return nil, NewInternalError(err)
114 }
115 }
116
104 return nil, nil 117 return nil, nil
105} 118}
106 119
@@ -158,7 +171,7 @@ func (q UpdateMarketConfigQuery) Run() (interface{}, *Error) {
158 171
159 var newStatus db.MarketConfigStatus = db.MarketConfigEnabled 172 var newStatus db.MarketConfigStatus = db.MarketConfigEnabled
160 173
161 if ErrorIs(resultErr, InvalidMarketCredentials) || ErrorIs(resultErr, IPRestrictedApiKey) { 174 if ErrorIs(resultErr, InvalidMarketCredentials) || ErrorIs(resultErr, IPRestrictedApiKey) || ErrorIs(resultErr, MarketCredentialsNotConfigured) {
162 newStatus = db.MarketConfigInvalidCredentials 175 newStatus = db.MarketConfigInvalidCredentials
163 } else if resultErr != nil { 176 } else if resultErr != nil {
164 return nil, NewInternalError(resultErr) 177 return nil, NewInternalError(resultErr)
diff --git a/api/routes.go b/api/routes.go
index a102419..671d22e 100644
--- a/api/routes.go
+++ b/api/routes.go
@@ -99,7 +99,7 @@ func OtpEnrollment(c *gin.Context) {
99 99
100 qrPng, secret, err := query.Run() 100 qrPng, secret, err := query.Run()
101 if err != nil { 101 if err != nil {
102 WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c) 102 WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c)
103 c.Error(err) 103 c.Error(err)
104 return 104 return
105 } 105 }