Commit e1fbb41f916dcaa9b5440a16cb5a0268a43ca18c
1 parent
c2ed249111
Exists in
master
and in
1 other branch
added comments
Showing
7 changed files
with
65 additions
and
26 deletions
Show diff stats
auth_utility.go
... | ... | @@ -27,6 +27,7 @@ type CredentialsStruct struct { |
27 | 27 | Password string `json:"password"` |
28 | 28 | } |
29 | 29 | |
30 | +// generateSalt returns a random string of 'saltSize' length to be used for hashing. | |
30 | 31 | func generateSalt() (salt string, err error) { |
31 | 32 | rawsalt := make([]byte, saltSize) |
32 | 33 | |
... | ... | @@ -39,6 +40,8 @@ func generateSalt() (salt string, err error) { |
39 | 40 | return salt, nil |
40 | 41 | } |
41 | 42 | |
43 | +// HashString hashes input string with SHA256 algorithm. | |
44 | +// If the presalt parameter is not provided HashString will generate new salt string. | |
42 | 45 | func HashString(str string, presalt string) (hash, salt string, err error) { |
43 | 46 | // chech if message is presalted |
44 | 47 | if presalt == "" { |
... | ... | @@ -70,6 +73,8 @@ func HashString(str string, presalt string) (hash, salt string, err error) { |
70 | 73 | return hash, salt, nil |
71 | 74 | } |
72 | 75 | |
76 | +// CreateAPIToken creates JWT token encoding username, role, | |
77 | +// expiration date and issuer claims in it. | |
73 | 78 | func CreateAPIToken(username, role string) (string, error) { |
74 | 79 | var apiToken string |
75 | 80 | var err error |
... | ... | @@ -95,10 +100,11 @@ func CreateAPIToken(username, role string) (string, error) { |
95 | 100 | return apiToken, nil |
96 | 101 | } |
97 | 102 | |
103 | +// RefreshAPIToken prolongs JWT token's expiration date. | |
98 | 104 | func RefreshAPIToken(tokenString string) (string, error) { |
99 | 105 | var newToken string |
100 | 106 | tokenString = strings.TrimPrefix(tokenString, "Bearer ") |
101 | - token, err := parseTokenFunc(tokenString) | |
107 | + token, err := jwt.ParseWithClaims(tokenString, &TokenClaims{}, secretFunc) | |
102 | 108 | if err != nil { |
103 | 109 | return "", err |
104 | 110 | } |
... | ... | @@ -120,14 +126,15 @@ func RefreshAPIToken(tokenString string) (string, error) { |
120 | 126 | return newToken, nil |
121 | 127 | } |
122 | 128 | |
129 | +// ParseAPIToken parses JWT token claims. | |
123 | 130 | func ParseAPIToken(tokenString string) (*TokenClaims, error) { |
124 | - if ok := strings.HasPrefix(tokenString, "Bearer"); ok { | |
131 | + if ok := strings.HasPrefix(tokenString, "Bearer "); ok { | |
125 | 132 | tokenString = strings.TrimPrefix(tokenString, "Bearer ") |
126 | 133 | } else { |
127 | 134 | return &TokenClaims{}, errors.New("Authorization header is incomplete") |
128 | 135 | } |
129 | 136 | |
130 | - token, err := parseTokenFunc(tokenString) | |
137 | + token, err := jwt.ParseWithClaims(tokenString, &TokenClaims{}, secretFunc) | |
131 | 138 | if err != nil { |
132 | 139 | return &TokenClaims{}, err |
133 | 140 | } |
... | ... | @@ -140,12 +147,7 @@ func ParseAPIToken(tokenString string) (*TokenClaims, error) { |
140 | 147 | return claims, nil |
141 | 148 | } |
142 | 149 | |
143 | -func parseTokenFunc(tokenString string) (*jwt.Token, error) { | |
144 | - token, err := jwt.ParseWithClaims(tokenString, | |
145 | - &TokenClaims{}, | |
146 | - func(token *jwt.Token) (interface{}, error) { | |
147 | - return []byte(secret), nil | |
148 | - }, | |
149 | - ) | |
150 | - return token, err | |
150 | +// secretFunc returns byte slice of 'secret'. | |
151 | +func secretFunc(token *jwt.Token) (interface{}, error) { | |
152 | + return []byte(secret), nil | |
151 | 153 | } | ... | ... |
format_utility.go
... | ... | @@ -5,10 +5,13 @@ import ( |
5 | 5 | "fmt" |
6 | 6 | ) |
7 | 7 | |
8 | +// UnixToDate converts given Unix time to local time in format and returns result: | |
9 | +// YYYY-MM-DD hh:mm:ss +zzzz UTC | |
8 | 10 | func UnixToDate(unix int64) time.Time { |
9 | 11 | return time.Unix(unix, 0) |
10 | 12 | } |
11 | 13 | |
14 | +// DateToUnix converts given date in Unix timestamp. | |
12 | 15 | func DateToUnix(date interface{}) int64 { |
13 | 16 | if date != nil { |
14 | 17 | t := date.(time.Time) |
... | ... | @@ -18,6 +21,8 @@ func DateToUnix(date interface{}) int64 { |
18 | 21 | return 0 |
19 | 22 | } |
20 | 23 | |
24 | +// EqualQuotes encapsulates given string in SQL 'equal' statement and returns result. | |
25 | +// Example: "hello" -> " = 'hello'" | |
21 | 26 | func EqualQuotes(stmt string) string { |
22 | 27 | if stmt != "" { |
23 | 28 | stmt = fmt.Sprintf(" = '%s'", stmt) |
... | ... | @@ -25,6 +30,8 @@ func EqualQuotes(stmt string) string { |
25 | 30 | return stmt |
26 | 31 | } |
27 | 32 | |
33 | +// LikeQuotes encapsulates given string in SQL 'like' statement and returns result. | |
34 | +// Example: "hello" -> " LIKE UPPER('%hello%')" | |
28 | 35 | func LikeQuotes(stmt string) string { |
29 | 36 | if stmt != "" { |
30 | 37 | stmt = fmt.Sprintf(" LIKE UPPER('%s%s%s')", "%", stmt, "%") | ... | ... |
http_utility.go
... | ... | @@ -22,12 +22,14 @@ type HttpErrorDesc struct { |
22 | 22 | Desc string `json:"description"` |
23 | 23 | } |
24 | 24 | |
25 | +// ErrorResponse writes HTTP error to w. | |
25 | 26 | func ErrorResponse(w http.ResponseWriter, r *http.Request, code int, desc []HttpErrorDesc) { |
26 | 27 | err := httpError{ desc, r.Method + " " + r.URL.Path } |
27 | 28 | w.WriteHeader(code) |
28 | 29 | json.NewEncoder(w).Encode(err) |
29 | 30 | } |
30 | 31 | |
32 | +// BadRequestResponse writes HTTP error 400 to w. | |
31 | 33 | func BadRequestResponse(w http.ResponseWriter, req *http.Request) { |
32 | 34 | ErrorResponse(w, req, http.StatusBadRequest, []HttpErrorDesc{ |
33 | 35 | { "en", templateHttpErr400_EN }, |
... | ... | @@ -35,6 +37,7 @@ func BadRequestResponse(w http.ResponseWriter, req *http.Request) { |
35 | 37 | }) |
36 | 38 | } |
37 | 39 | |
40 | +// InternalSeverErrorResponse writes HTTP error 500 to w. | |
38 | 41 | func InternalServerErrorResponse(w http.ResponseWriter, req *http.Request) { |
39 | 42 | ErrorResponse(w, req, http.StatusInternalServerError, []HttpErrorDesc{ |
40 | 43 | { "en", templateHttpErr500_EN }, |
... | ... | @@ -42,6 +45,7 @@ func InternalServerErrorResponse(w http.ResponseWriter, req *http.Request) { |
42 | 45 | }) |
43 | 46 | } |
44 | 47 | |
48 | +// UnauthorizedError writes HTTP error 401 to w. | |
45 | 49 | func UnauthorizedResponse(w http.ResponseWriter, req *http.Request) { |
46 | 50 | ErrorResponse(w, req, http.StatusUnauthorized, []HttpErrorDesc{ |
47 | 51 | { "en", templateHttpErr500_EN }, |
... | ... | @@ -50,7 +54,7 @@ func UnauthorizedResponse(w http.ResponseWriter, req *http.Request) { |
50 | 54 | } |
51 | 55 | |
52 | 56 | // TODO: Check for content type |
53 | -// Sets common headers and checks for token validity. | |
57 | +// Sets common headers, checks for token validity and performs access control. | |
54 | 58 | func WrapHandler(handlerFunc http.HandlerFunc, auth bool) http.HandlerFunc { |
55 | 59 | return func(w http.ResponseWriter, req *http.Request) { |
56 | 60 | w.Header().Set("Access-Control-Allow-Origin", "*") |
... | ... | @@ -87,6 +91,7 @@ func WrapHandler(handlerFunc http.HandlerFunc, auth bool) http.HandlerFunc { |
87 | 91 | } |
88 | 92 | } |
89 | 93 | |
94 | +// NotFoundHandler writes HTTP error 404 to w. | |
90 | 95 | func NotFoundHandler(w http.ResponseWriter, req *http.Request) { |
91 | 96 | ErrorResponse(w, req, http.StatusNotFound, []HttpErrorDesc{ |
92 | 97 | { "en", "Not found." }, | ... | ... |
json_utility.go
... | ... | @@ -33,8 +33,6 @@ type Translation struct { |
33 | 33 | FieldsLabels map[string]string `json:"fieldsLabels"` |
34 | 34 | } |
35 | 35 | |
36 | -// Field 'Type' is not required in payload. | |
37 | -// 'payloadBuff' type is only a bridge between ORACLE CLOB and 'Payload' type. | |
38 | 36 | type payloadBuff struct { |
39 | 37 | Type string `json:"tableType"` |
40 | 38 | Method string `json:"method"` |
... | ... | @@ -54,15 +52,16 @@ type Payload struct { |
54 | 52 | Fields []Field `json:"fields"` |
55 | 53 | Correlations []CorrelationField `json:"correlationFields"` |
56 | 54 | IdField string `json:"idField"` |
55 | + | |
57 | 56 | // Data can only hold slices of any type. It can't be used for itteration |
58 | 57 | Data interface{} `json:"data"` |
59 | 58 | } |
60 | 59 | |
60 | +// NewPayload returs payload for provided table. | |
61 | 61 | func NewPayload(r *http.Request, table string) Payload { |
62 | 62 | var pload Payload |
63 | 63 | |
64 | 64 | pload.Method = r.Method + " " + r.URL.Path |
65 | - | |
66 | 65 | if table != "" { |
67 | 66 | pload.Params = make(map[string]string, 0) |
68 | 67 | pload.Lang = loadTranslations(table) |
... | ... | @@ -70,15 +69,16 @@ func NewPayload(r *http.Request, table string) Payload { |
70 | 69 | pload.IdField = loadIdField(table) |
71 | 70 | pload.Correlations = loadCorrelations(table) |
72 | 71 | } |
73 | - | |
74 | 72 | return pload |
75 | 73 | } |
76 | 74 | |
75 | +// DeliverPayload writes payload to w. | |
77 | 76 | func DeliverPayload(w http.ResponseWriter, payload Payload) { |
78 | 77 | json.NewEncoder(w).Encode(payload) |
79 | 78 | payload.Data = nil |
80 | 79 | } |
81 | 80 | |
81 | +// loadTranslations loads translations for a payload of the given data type. | |
82 | 82 | func loadTranslations(id string) []Translation { |
83 | 83 | translations := make([]Translation, 0) |
84 | 84 | |
... | ... | @@ -97,6 +97,7 @@ func loadTranslations(id string) []Translation { |
97 | 97 | return translations |
98 | 98 | } |
99 | 99 | |
100 | +// loadFields loads fields for a payload of the given data type. | |
100 | 101 | func loadFields(id string) []Field { |
101 | 102 | fields := make([]Field, 0) |
102 | 103 | |
... | ... | @@ -111,6 +112,7 @@ func loadFields(id string) []Field { |
111 | 112 | return fields |
112 | 113 | } |
113 | 114 | |
115 | +// loadIdField loads ID field for a payload of the given data type. | |
114 | 116 | func loadIdField(id string) string { |
115 | 117 | for _, pload := range allPayloads { |
116 | 118 | if pload.Type == id { |
... | ... | @@ -120,6 +122,7 @@ func loadIdField(id string) string { |
120 | 122 | return "" |
121 | 123 | } |
122 | 124 | |
125 | +// loadCorrelations loads correlations field for a payload of the given data type. | |
123 | 126 | func loadCorrelations(id string) []CorrelationField { |
124 | 127 | resp := make([]CorrelationField, 0) |
125 | 128 | |
... | ... | @@ -134,6 +137,7 @@ func loadCorrelations(id string) []CorrelationField { |
134 | 137 | return resp |
135 | 138 | } |
136 | 139 | |
140 | +// InitTables loads all payloads in the memory. | |
137 | 141 | func InitTables(db *ora.Ses, project string) error { |
138 | 142 | jsonbuf, _ := fetchJSON(db, EqualQuotes(project)) |
139 | 143 | mu.Lock() |
... | ... | @@ -145,6 +149,7 @@ func InitTables(db *ora.Ses, project string) error { |
145 | 149 | return nil |
146 | 150 | } |
147 | 151 | |
152 | +// fetchJSON fetches JSON configuration file from TABLES_CONFIG table. | |
148 | 153 | func fetchJSON(db *ora.Ses, project string) ([]byte, error) { |
149 | 154 | stmt, err := db.Prep(`SELECT |
150 | 155 | JSON_CLOB |
... | ... | @@ -175,6 +180,8 @@ func fetchJSON(db *ora.Ses, project string) ([]byte, error) { |
175 | 180 | return bytes, nil |
176 | 181 | } |
177 | 182 | |
183 | +// DecodeJSON decodes JSON data from r to v and returns any error | |
184 | +// that happens during decoding process. | |
178 | 185 | func DecodeJSON(r io.Reader, v interface{}) error { |
179 | 186 | return json.NewDecoder(r).Decode(v) |
180 | 187 | } | ... | ... |
list_config.go
... | ... | @@ -28,7 +28,7 @@ type ListFilter struct { |
28 | 28 | type Dropdown struct { |
29 | 29 | ObjectType string `json:"objectType"` |
30 | 30 | FiltersField string `json:"filtersField"` |
31 | - IdField string `json:"idField"` | |
31 | + IDField string `json:"idField"` | |
32 | 32 | LabelField string `json:"labelField"` |
33 | 33 | |
34 | 34 | } |
... | ... | @@ -55,7 +55,7 @@ type ListNavNode struct { |
55 | 55 | LabelField string `json:"label"` |
56 | 56 | Icon string `json:"icon"` |
57 | 57 | ParentObjectType string `json:"parentObjectType"` |
58 | - ParentIdField string `json:"parentIdField"` | |
58 | + ParentIDField string `json:"parentIdField"` | |
59 | 59 | } |
60 | 60 | |
61 | 61 | type ListParentNode struct { |
... | ... | @@ -93,8 +93,9 @@ type ListConfig struct { |
93 | 93 | Details ListDetails `json:"details"` |
94 | 94 | } |
95 | 95 | |
96 | +// GetListConfig returns list configuration for the given object type for the front-end application. | |
96 | 97 | func GetListConfig(db *ora.Ses, objType string) (ListConfig, error) { |
97 | - resp := NewDefaultList(objType) | |
98 | + resp := newDefaultList(objType) | |
98 | 99 | var err error |
99 | 100 | |
100 | 101 | err = setListParams(db, &resp, objType) |
... | ... | @@ -114,7 +115,8 @@ func GetListConfig(db *ora.Ses, objType string) (ListConfig, error) { |
114 | 115 | return resp, nil |
115 | 116 | } |
116 | 117 | |
117 | -func GetListConfigObjectIdField(db *ora.Ses, otype string) string { | |
118 | +// GetListConfigObjectIDField returns ID field for the given object type. | |
119 | +func GetListConfigObjectIDField(db *ora.Ses, otype string) string { | |
118 | 120 | var resp string |
119 | 121 | var err error |
120 | 122 | var stmt *ora.Stmt |
... | ... | @@ -143,7 +145,8 @@ func GetListConfigObjectIdField(db *ora.Ses, otype string) string { |
143 | 145 | return resp |
144 | 146 | } |
145 | 147 | |
146 | -func NewDefaultList(objType string) ListConfig { | |
148 | +// newDefaultList returns default configuration for the given object type. | |
149 | +func newDefaultList(objType string) ListConfig { | |
147 | 150 | list := ListConfig{ |
148 | 151 | ObjectType: objType, |
149 | 152 | Title: objType, |
... | ... | @@ -171,6 +174,7 @@ func NewDefaultList(objType string) ListConfig { |
171 | 174 | return list |
172 | 175 | } |
173 | 176 | |
177 | +// setListParams sets the default parameters of the provided configuration list for the given object type. | |
174 | 178 | func setListParams(db *ora.Ses, list *ListConfig, objType string) error { |
175 | 179 | var err error |
176 | 180 | var stmt *ora.Stmt |
... | ... | @@ -208,6 +212,7 @@ func setListParams(db *ora.Ses, list *ListConfig, objType string) error { |
208 | 212 | return nil |
209 | 213 | } |
210 | 214 | |
215 | +// getListNavigation returns list navigation node slice for the given objectType. | |
211 | 216 | func getListNavigation(db *ora.Ses, listObjType string) ([]ListNavNode, error) { |
212 | 217 | resp := make([]ListNavNode, 0) |
213 | 218 | var err error |
... | ... | @@ -235,7 +240,7 @@ func getListNavigation(db *ora.Ses, listObjType string) ([]ListNavNode, error) { |
235 | 240 | ParentObjectType: rset.Row[1].(string), |
236 | 241 | LabelField: rset.Row[2].(string), |
237 | 242 | Icon: rset.Row[3].(string), |
238 | - ParentIdField: rset.Row[4].(string), | |
243 | + ParentIDField: rset.Row[4].(string), | |
239 | 244 | }) |
240 | 245 | } |
241 | 246 | if rset.Err != nil { |
... | ... | @@ -245,6 +250,7 @@ func getListNavigation(db *ora.Ses, listObjType string) ([]ListNavNode, error) { |
245 | 250 | return resp, nil |
246 | 251 | } |
247 | 252 | |
253 | +// getListActions returns list actions for the given objectType. | |
248 | 254 | func getListActions(db *ora.Ses, objType string) (ListActions, error) { |
249 | 255 | var resp ListActions |
250 | 256 | var err error |
... | ... | @@ -280,6 +286,7 @@ func getListActions(db *ora.Ses, objType string) (ListActions, error) { |
280 | 286 | return resp, nil |
281 | 287 | } |
282 | 288 | |
289 | +// getListFiters returns list filter slice for the given object type. | |
283 | 290 | func getListFilters(db *ora.Ses, objType string) ([]ListFilter, error) { |
284 | 291 | resp := make([]ListFilter, 0) |
285 | 292 | filtersFields, err := getFilterFieldsAndPosition(db, objType) |
... | ... | @@ -311,6 +318,7 @@ func getListFilters(db *ora.Ses, objType string) ([]ListFilter, error) { |
311 | 318 | return resp, nil |
312 | 319 | } |
313 | 320 | |
321 | +// getFilterFieldsAndPosition returns a map of filter fields and their respective position in the menu. | |
314 | 322 | func getFilterFieldsAndPosition(db *ora.Ses, objType string) (map[string]uint32, error) { |
315 | 323 | filtersField := make(map[string]uint32, 0) |
316 | 324 | var err error |
... | ... | @@ -345,6 +353,7 @@ type _filter struct { |
345 | 353 | Type string |
346 | 354 | } |
347 | 355 | |
356 | +// getFiltersByFilterField returns filter slice for the given filter field. | |
348 | 357 | func getFiltersByFilterField(db *ora.Ses, filtersField string) ([]_filter, error) { |
349 | 358 | resp := make([]_filter, 0) |
350 | 359 | var err error |
... | ... | @@ -377,6 +386,7 @@ func getFiltersByFilterField(db *ora.Ses, filtersField string) ([]_filter, error |
377 | 386 | return resp, nil |
378 | 387 | } |
379 | 388 | |
389 | +// getFilterDropdownConfig returns dropdown menu for the given filter field. | |
380 | 390 | func getFilterDropdownConfig(db *ora.Ses, filtersField string) (Dropdown, error) { |
381 | 391 | var resp Dropdown |
382 | 392 | var err error |
... | ... | @@ -399,7 +409,7 @@ func getFilterDropdownConfig(db *ora.Ses, filtersField string) (Dropdown, error) |
399 | 409 | if rset.Next() { |
400 | 410 | resp.FiltersField = rset.Row[0].(string) |
401 | 411 | resp.ObjectType = rset.Row[1].(string) |
402 | - resp.IdField = rset.Row[2].(string) | |
412 | + resp.IDField = rset.Row[2].(string) | |
403 | 413 | resp.LabelField = rset.Row[3].(string) |
404 | 414 | } |
405 | 415 | if rset.Err != nil { |
... | ... | @@ -408,6 +418,7 @@ func getFilterDropdownConfig(db *ora.Ses, filtersField string) (Dropdown, error) |
408 | 418 | return resp, nil |
409 | 419 | } |
410 | 420 | |
421 | +// sortFilters bubble sorts provided filters slice by position field. | |
411 | 422 | func sortFilters(filters []ListFilter) { |
412 | 423 | done := false |
413 | 424 | var temp ListFilter |
... | ... | @@ -424,6 +435,7 @@ func sortFilters(filters []ListFilter) { |
424 | 435 | } |
425 | 436 | } |
426 | 437 | |
438 | +// getListGraph return list graph slice for the given object type. | |
427 | 439 | func getListGraph(db *ora.Ses, objType string) ([]ListGraph, error) { |
428 | 440 | resp := make([]ListGraph, 0) |
429 | 441 | var err error |
... | ... | @@ -458,6 +470,7 @@ func getListGraph(db *ora.Ses, objType string) ([]ListGraph, error) { |
458 | 470 | return resp, nil |
459 | 471 | } |
460 | 472 | |
473 | +// getListOptions returns list options for the given object type. | |
461 | 474 | func getListOptions(db *ora.Ses, objType string) (ListOptions, error) { |
462 | 475 | var resp ListOptions |
463 | 476 | var err error |
... | ... | @@ -495,6 +508,7 @@ func getListOptions(db *ora.Ses, objType string) (ListOptions, error) { |
495 | 508 | return resp, nil |
496 | 509 | } |
497 | 510 | |
511 | +// getListParent returns list parent node slice for the given object type. | |
498 | 512 | func getListParent(db *ora.Ses, objType string) ([]ListParentNode, error) { |
499 | 513 | resp := make([]ListParentNode, 0) |
500 | 514 | var err error |
... | ... | @@ -528,6 +542,7 @@ func getListParent(db *ora.Ses, objType string) ([]ListParentNode, error) { |
528 | 542 | return resp, nil |
529 | 543 | } |
530 | 544 | |
545 | +// getListPivot list pivot slice for the given object type. | |
531 | 546 | func getListPivot(db *ora.Ses, objType string) ([]ListPivot, error) { |
532 | 547 | resp := make([]ListPivot, 0) |
533 | 548 | var err error |
... | ... | @@ -562,6 +577,7 @@ func getListPivot(db *ora.Ses, objType string) ([]ListPivot, error) { |
562 | 577 | return resp, nil |
563 | 578 | } |
564 | 579 | |
580 | +// getListDetails returns list details for the given object type. | |
565 | 581 | func getListDetails(db *ora.Ses, objType string) (ListDetails, error) { |
566 | 582 | var resp ListDetails |
567 | 583 | var err error | ... | ... |
select_config.go
... | ... | @@ -13,6 +13,7 @@ type SelectConfig struct { |
13 | 13 | ValueField string `json:"valueField"` |
14 | 14 | } |
15 | 15 | |
16 | +// GetSelectConfig returns select configuration slice for the given object type. | |
16 | 17 | func GetSelectConfig(db *ora.Ses, otype string) ([]SelectConfig, error) { |
17 | 18 | resp := make([]SelectConfig, 0) |
18 | 19 | var err error | ... | ... |
sql_sequrity.go
... | ... | @@ -6,9 +6,10 @@ import ( |
6 | 6 | |
7 | 7 | var patern string = "\"';&*<>=\\`:" |
8 | 8 | |
9 | -func SQLSafeString(s string) string { | |
9 | +// SQLSafeString removes characters from s found in patern and returns new modified string. | |
10 | +func SQLSafeString(s string) (safe string) { | |
10 | 11 | for _, c := range patern { |
11 | - s = strings.Replace(s, string(c), "", -1) | |
12 | + safe = strings.Replace(s, string(c), "", -1) | |
12 | 13 | } |
13 | - return s | |
14 | + return safe | |
14 | 15 | } | ... | ... |