Commit e1fbb41f916dcaa9b5440a16cb5a0268a43ca18c

Authored by Marko Tikvić
1 parent c2ed249111
Exists in master and in 1 other branch v2

added comments

... ... @@ -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, "%")
... ...
... ... @@ -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." },
... ...
... ... @@ -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 }
... ...
... ... @@ -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
... ...
... ... @@ -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
... ...
... ... @@ -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 }
... ...