]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git/blame - api/api.go
Error flags.
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git] / api / api.go
CommitLineData
7a9e5112 1package api
2
3import (
4 "net/http"
5 "unicode"
6
7 "github.com/gin-gonic/gin"
4495b984 8 "github.com/jloup/utils"
7a9e5112 9)
10
85545aba 11var CONFIG Config
2da5b12c 12var MAIL_CONFIG MailConfig
13
14type MailConfig struct {
15 IsEnabled bool
16 SmtpAddress string `toml:"smtp_address"`
17 AddressFrom string `toml:"address_from"`
18 Login string `toml:"login"`
19 Password string `toml:"password"`
20}
85545aba 21
22type Config struct {
2da5b12c 23 Domain string `toml:"domain"`
85545aba 24 JwtSecret string `toml:"jwt_secret"`
25 PasswordResetSecret string `toml:"password_reset_secret"`
26 FreeSMSUser string `toml:"free_sms_user"`
27 FreeSMSPass string `toml:"free_sms_pass"`
28}
29
30func SetConfig(config Config) {
31 CONFIG = config
32
33 JWT_SECRET = []byte(config.JwtSecret)
34 PASSWORD_RESET_SECRET = []byte(config.PasswordResetSecret)
35}
36
2da5b12c 37func SetMailConfig(config MailConfig) {
38 MAIL_CONFIG = config
39
40 if config.Login != "" && config.AddressFrom != "" && config.Password != "" && config.SmtpAddress != "" {
41 MAIL_CONFIG.IsEnabled = true
42 ConfigureMailTemplateEngine()
43 }
44}
45
7a9e5112 46type Error struct {
4495b984 47 Code utils.Flag
7a9e5112 48 UserMessage string
49 err error
50}
51
4495b984 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}
7a9e5112 71func (e Error) Err() error {
72 if e.err != nil {
73 return e
74 }
75
76 return nil
77}
78
79func (e Error) Error() string {
80 if e.err != nil {
81 return e.err.Error()
82 }
83
84 return ""
85}
86
4495b984 87func ErrorIs(err error, code utils.Flag) bool {
24e47979 88 if err == nil {
89 return false
90 }
91
92 if apiError, ok := err.(*Error); !ok {
93 return false
94 } else {
4495b984 95 return utils.Intersect(apiError.Code, code) && apiError.Code.String() == code.String()
24e47979 96 }
97}
98
7a9e5112 99func NewInternalError(err error) *Error {
299b6b6d 100 if apiError, ok := err.(*Error); ok {
101 return apiError
102 }
7a9e5112 103 return &Error{InternalError, "internal error", err}
104}
105
106func ToSnake(in string) string {
107 runes := []rune(in)
108 length := len(runes)
109
110 var out []rune
111 for i := 0; i < length; i++ {
112 if i > 0 && unicode.IsUpper(runes[i]) && ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) {
113 out = append(out, '_')
114 }
115 out = append(out, unicode.ToLower(runes[i]))
116 }
117
118 return string(out)
119}
120
121type Response struct {
4495b984 122 StatusCode Status `json:"-"`
123 ErrorCode utils.Flag `json:"-"`
7a9e5112 124
125 Status string `json:"status"`
126 Code string `json:"code,omitempty"`
127 Response interface{} `json:"response,omitempty"`
128 Message string `json:"message,omitempty"`
129}
130
131func (r Response) populateStatus() Response {
132 r.Status = ToSnake(r.StatusCode.String())
4495b984 133 r.Code = ToSnake(r.ErrorCode.String())
7a9e5112 134
135 return r
136}
137
4495b984 138func ErrorResponse(code utils.Flag, message string) Response {
7a9e5112 139 return Response{
140 StatusCode: NOK,
141 ErrorCode: code,
142 Message: message,
143 }
144}
145
146func SuccessResponse(data interface{}) Response {
147 return Response{
148 StatusCode: OK,
149 Response: data,
150 }
151}
152
153func WriteJsonResponse(response Response, c *gin.Context) {
154 response = response.populateStatus()
155
156 c.JSON(StatusToHttpCode(response.StatusCode, response.ErrorCode), response)
157}
158
159func WriteBinary(contentType string, b []byte, c *gin.Context) {
160 c.Data(http.StatusOK, contentType, b)
161}
162
163type Middleware func(*gin.Context) *Error
164
165func M(handler Middleware) gin.HandlerFunc {
166 return func(c *gin.Context) {
167 err := handler(c)
168
169 if err != nil {
4495b984 170 WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c)
7a9e5112 171 c.Error(err)
172 c.Abort()
173 } else {
174 c.Next()
175 }
176 }
177}
178
179type Query interface {
180 ValidateParams() *Error
181 Run() (interface{}, *Error)
182}
183
184func RunQuery(query Query, c *gin.Context) {
185 if err := query.ValidateParams(); err != nil {
4495b984 186 WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c)
7a9e5112 187 c.Error(err)
188 return
189 }
190
191 if out, err := query.Run(); err != nil {
4495b984 192 WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c)
7a9e5112 193 c.Error(err)
194 } else {
195 WriteJsonResponse(SuccessResponse(out), c)
196 }
197}