Commit c2ed2491115cb8a87f81c2c7f782fb817a473582
Exists in
master
and in
1 other branch
restutility -> webutility
Showing
7 changed files
Show diff stats
auth_utility.go
1 | -package restutility | |
1 | +package webutility | |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "errors" |
... | ... | @@ -27,24 +27,22 @@ type CredentialsStruct struct { |
27 | 27 | Password string `json:"password"` |
28 | 28 | } |
29 | 29 | |
30 | -func GenerateSalt() (string, error) { | |
31 | - salt := "" | |
30 | +func generateSalt() (salt string, err error) { | |
32 | 31 | rawsalt := make([]byte, saltSize) |
33 | - _, err := rand.Read(rawsalt) | |
32 | + | |
33 | + _, err = rand.Read(rawsalt) | |
34 | 34 | if err != nil { |
35 | 35 | return "", err |
36 | 36 | } |
37 | + | |
37 | 38 | salt = hex.EncodeToString(rawsalt) |
38 | 39 | return salt, nil |
39 | 40 | } |
40 | 41 | |
41 | -func HashMessage(message string, presalt string) (string, string, error) { | |
42 | - hash, salt := "", "" | |
43 | - var err error | |
44 | - | |
42 | +func HashString(str string, presalt string) (hash, salt string, err error) { | |
45 | 43 | // chech if message is presalted |
46 | 44 | if presalt == "" { |
47 | - salt, err = GenerateSalt() | |
45 | + salt, err = generateSalt() | |
48 | 46 | if err != nil { |
49 | 47 | return "", "", err |
50 | 48 | } |
... | ... | @@ -53,24 +51,26 @@ func HashMessage(message string, presalt string) (string, string, error) { |
53 | 51 | } |
54 | 52 | |
55 | 53 | // convert strings to raw byte slices |
56 | - rawmessage := []byte(message) | |
54 | + rawstr := []byte(str) | |
57 | 55 | rawsalt, err := hex.DecodeString(salt) |
58 | 56 | if err != nil { |
59 | 57 | return "", "", err |
60 | 58 | } |
61 | - rawdata := make([]byte, len(rawmessage) + len(rawsalt)) | |
62 | - rawdata = append(rawdata, rawmessage...) | |
59 | + | |
60 | + rawdata := make([]byte, len(rawstr) + len(rawsalt)) | |
61 | + rawdata = append(rawdata, rawstr...) | |
63 | 62 | rawdata = append(rawdata, rawsalt...) |
64 | 63 | |
65 | 64 | // hash message + salt |
66 | 65 | hasher := sha256.New() |
67 | 66 | hasher.Write(rawdata) |
68 | 67 | rawhash := hasher.Sum(nil) |
68 | + | |
69 | 69 | hash = hex.EncodeToString(rawhash) |
70 | 70 | return hash, salt, nil |
71 | 71 | } |
72 | 72 | |
73 | -func IssueAPIToken(username, role string) (string, error) { | |
73 | +func CreateAPIToken(username, role string) (string, error) { | |
74 | 74 | var apiToken string |
75 | 75 | var err error |
76 | 76 | ... | ... |
format_utility.go
1 | -package restutility | |
1 | +package webutility | |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "time" |
5 | + "fmt" | |
5 | 6 | ) |
6 | 7 | |
7 | -func UnixToDate(input int64) time.Time { | |
8 | - return time.Unix(input, 0) | |
8 | +func UnixToDate(unix int64) time.Time { | |
9 | + return time.Unix(unix, 0) | |
9 | 10 | } |
10 | 11 | |
11 | -func DateToUnix(input interface{}) int64 { | |
12 | - if input != nil { | |
13 | - t := input.(time.Time) | |
12 | +func DateToUnix(date interface{}) int64 { | |
13 | + if date != nil { | |
14 | + t := date.(time.Time) | |
14 | 15 | return t.Unix() |
15 | 16 | |
16 | 17 | } |
17 | 18 | return 0 |
18 | 19 | } |
19 | 20 | |
20 | -func EqualQuotes(input string) string { | |
21 | - if input != "" { | |
22 | - return " = '" + input + "'" | |
21 | +func EqualQuotes(stmt string) string { | |
22 | + if stmt != "" { | |
23 | + stmt = fmt.Sprintf(" = '%s'", stmt) | |
23 | 24 | } |
24 | - return "" | |
25 | + return stmt | |
25 | 26 | } |
26 | 27 | |
27 | -func LikeQuotes(input string) string { | |
28 | - if input != "" { | |
29 | - return " LIKE UPPER('%" + input + "%')" | |
28 | +func LikeQuotes(stmt string) string { | |
29 | + if stmt != "" { | |
30 | + stmt = fmt.Sprintf(" LIKE UPPER('%s%s%s')", "%", stmt, "%") | |
30 | 31 | } |
31 | - return "" | |
32 | + return stmt | |
32 | 33 | } |
33 | 34 | ... | ... |
http_utility.go
1 | -package restutility | |
1 | +package webutility | |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "net/http" |
5 | 5 | "encoding/json" |
6 | 6 | ) |
7 | 7 | |
8 | -var _apiVersion = "/api/v1" | |
9 | -var _authEndPoint = "/token" | |
10 | - | |
11 | -func SetApiVersion(ver string) string { | |
12 | - _apiVersion = ver | |
13 | - return _apiVersion | |
14 | -} | |
15 | - | |
16 | -func SetAuthEndpoint(ep string) { | |
17 | - _authEndPoint = ep | |
18 | -} | |
19 | - | |
20 | 8 | const templateHttpErr500_EN = "An internal server error has occurred." |
21 | 9 | const templateHttpErr500_RS = "Došlo je do greške na serveru." |
22 | 10 | const templateHttpErr400_EN = "Bad request: invalid request body." |
23 | 11 | const templateHttpErr400_RS = "Neispravan zahtev." |
12 | +const templateHttpErr401_EN = "Unauthorized request." | |
13 | +const templateHttpErr401_RS = "Neautorizovan zahtev." | |
24 | 14 | |
25 | -type HttpError struct { | |
15 | +type httpError struct { | |
26 | 16 | Error []HttpErrorDesc `json:"error"` |
27 | 17 | Request string `json:"request"` |
28 | 18 | } |
... | ... | @@ -32,81 +22,63 @@ type HttpErrorDesc struct { |
32 | 22 | Desc string `json:"description"` |
33 | 23 | } |
34 | 24 | |
35 | -func RespondWithHttpError(w http.ResponseWriter, | |
36 | - req *http.Request, | |
37 | - code int, | |
38 | - httpErr []HttpErrorDesc) { | |
39 | - | |
40 | - err := HttpError{ | |
41 | - Error: httpErr, | |
42 | - Request: req.Method + " " + req.URL.Path, | |
43 | - } | |
25 | +func ErrorResponse(w http.ResponseWriter, r *http.Request, code int, desc []HttpErrorDesc) { | |
26 | + err := httpError{ desc, r.Method + " " + r.URL.Path } | |
44 | 27 | w.WriteHeader(code) |
45 | 28 | json.NewEncoder(w).Encode(err) |
46 | 29 | } |
47 | 30 | |
48 | -func RespondWithHttpError400(w http.ResponseWriter, req *http.Request) { | |
49 | - RespondWithHttpError(w, req, http.StatusBadRequest, []HttpErrorDesc{ | |
50 | - {Lang: "en", Desc: templateHttpErr400_EN}, | |
51 | - {Lang: "rs", Desc: templateHttpErr400_RS}, | |
31 | +func BadRequestResponse(w http.ResponseWriter, req *http.Request) { | |
32 | + ErrorResponse(w, req, http.StatusBadRequest, []HttpErrorDesc{ | |
33 | + { "en", templateHttpErr400_EN }, | |
34 | + { "rs", templateHttpErr400_RS }, | |
52 | 35 | }) |
53 | 36 | } |
54 | 37 | |
55 | -func RespondWithHttpError500(w http.ResponseWriter, req *http.Request) { | |
56 | - RespondWithHttpError(w, req, http.StatusInternalServerError, []HttpErrorDesc{ | |
57 | - {Lang: "en", Desc: templateHttpErr500_EN}, | |
58 | - {Lang: "rs", Desc: templateHttpErr500_RS}, | |
38 | +func InternalServerErrorResponse(w http.ResponseWriter, req *http.Request) { | |
39 | + ErrorResponse(w, req, http.StatusInternalServerError, []HttpErrorDesc{ | |
40 | + { "en", templateHttpErr500_EN }, | |
41 | + { "rs", templateHttpErr500_RS }, | |
59 | 42 | }) |
60 | 43 | } |
61 | 44 | |
62 | -//TODO: Add parameters to enable/disable roles authorization checks | |
45 | +func UnauthorizedResponse(w http.ResponseWriter, req *http.Request) { | |
46 | + ErrorResponse(w, req, http.StatusUnauthorized, []HttpErrorDesc{ | |
47 | + { "en", templateHttpErr500_EN }, | |
48 | + { "rs", templateHttpErr500_RS }, | |
49 | + }) | |
50 | +} | |
51 | + | |
52 | +// TODO: Check for content type | |
63 | 53 | // Sets common headers and checks for token validity. |
64 | -func HttpPreProc(handlerFunc http.HandlerFunc, authEnabled bool) http.HandlerFunc { | |
54 | +func WrapHandler(handlerFunc http.HandlerFunc, auth bool) http.HandlerFunc { | |
65 | 55 | return func(w http.ResponseWriter, req *http.Request) { |
66 | -// @TODO: check Content-type header (must be application/json) | |
67 | -// ctype := w.Header.Get("Content-Type") | |
68 | -// if req.Method != "GET" && ctype != "application/json" { | |
69 | -// replyWithHttpError(w, req, http.StatusBadRequest, | |
70 | -// "Not a supported content type: " + ctype) | |
71 | -// } | |
72 | - | |
73 | 56 | w.Header().Set("Access-Control-Allow-Origin", "*") |
57 | + | |
74 | 58 | w.Header().Set("Access-Control-Allow-Methods", |
75 | - `POST, | |
76 | - GET, | |
77 | - PUT, | |
78 | - DELETE, | |
79 | - OPTIONS`) | |
59 | + "POST, GET, PUT, DELETE, OPTIONS") | |
60 | + | |
80 | 61 | w.Header().Set("Access-Control-Allow-Headers", |
81 | - `Accept, | |
82 | - Content-Type, | |
83 | - Content-Length, | |
84 | - Accept-Encoding, | |
85 | - X-CSRF-Token, | |
86 | - Authorization`) | |
62 | + `Accept, Content-Type, Content-Length, | |
63 | + Accept-Encoding, X-CSRF-Token, Authorization`) | |
64 | + | |
87 | 65 | w.Header().Set("Content-Type", "application/json; charset=utf-8") |
88 | 66 | |
89 | 67 | if req.Method == "OPTIONS" { |
90 | 68 | return |
91 | 69 | } |
92 | 70 | |
93 | - if authEnabled { | |
94 | - if req.URL.Path != _apiVersion + _authEndPoint { | |
95 | - token := req.Header.Get("Authorization") | |
96 | - if _, err := ParseAPIToken(token); err != nil { | |
97 | - RespondWithHttpError(w, req, http.StatusUnauthorized, | |
98 | - []HttpErrorDesc{ | |
99 | - {Lang: "en", Desc: "Unauthorized request."}, | |
100 | - {Lang: "rs", Desc: "Neautorizovani zahtev."}, | |
101 | - }) | |
102 | - return | |
103 | - } | |
71 | + if auth { | |
72 | + token := req.Header.Get("Authorization") | |
73 | + if _, err := ParseAPIToken(token); err != nil { | |
74 | + UnauthorizedResponse(w, req) | |
75 | + return | |
104 | 76 | } |
105 | 77 | } |
106 | 78 | |
107 | 79 | err := req.ParseForm() |
108 | 80 | if err != nil { |
109 | - RespondWithHttpError400(w, req) | |
81 | + BadRequestResponse(w, req) | |
110 | 82 | return |
111 | 83 | } |
112 | 84 | |
... | ... | @@ -116,8 +88,8 @@ func HttpPreProc(handlerFunc http.HandlerFunc, authEnabled bool) http.HandlerFun |
116 | 88 | } |
117 | 89 | |
118 | 90 | func NotFoundHandler(w http.ResponseWriter, req *http.Request) { |
119 | - RespondWithHttpError(w, req, http.StatusNotFound, []HttpErrorDesc{ | |
120 | - {Lang: "en", Desc: "Not found."}, | |
121 | - {Lang: "rs", Desc: "Traženi resurs ne postoji."}, | |
91 | + ErrorResponse(w, req, http.StatusNotFound, []HttpErrorDesc{ | |
92 | + { "en", "Not found." }, | |
93 | + { "rs", "Traženi resurs ne postoji." }, | |
122 | 94 | }) |
123 | 95 | } | ... | ... |
json_utility.go
1 | -package restutility | |
1 | +package webutility | |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "net/http" |
... | ... | @@ -7,8 +7,10 @@ import ( |
7 | 7 | "gopkg.in/rana/ora.v3" |
8 | 8 | "io" |
9 | 9 | "io/ioutil" |
10 | + "sync" | |
10 | 11 | ) |
11 | 12 | |
13 | +var mu = &sync.Mutex{} | |
12 | 14 | var allPayloads []payloadBuff |
13 | 15 | |
14 | 16 | type LangMap map[string]map[string]string |
... | ... | @@ -134,6 +136,8 @@ func loadCorrelations(id string) []CorrelationField { |
134 | 136 | |
135 | 137 | func InitTables(db *ora.Ses, project string) error { |
136 | 138 | jsonbuf, _ := fetchJSON(db, EqualQuotes(project)) |
139 | + mu.Lock() | |
140 | + defer mu.Unlock() | |
137 | 141 | json.Unmarshal(jsonbuf, &allPayloads) |
138 | 142 | if len(allPayloads) == 0 { |
139 | 143 | return errors.New("tables config is corrupt") |
... | ... | @@ -171,3 +175,6 @@ func fetchJSON(db *ora.Ses, project string) ([]byte, error) { |
171 | 175 | return bytes, nil |
172 | 176 | } |
173 | 177 | |
178 | +func DecodeJSON(r io.Reader, v interface{}) error { | |
179 | + return json.NewDecoder(r).Decode(v) | |
180 | +} | ... | ... |
list_config.go
select_config.go
1 | -package restutility | |
1 | +package webutility | |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "gopkg.in/rana/ora.v3" |
... | ... | @@ -24,8 +24,7 @@ func GetSelectConfig(db *ora.Ses, otype string) ([]SelectConfig, error) { |
24 | 24 | AND b.LIST_TYPE = a.LIST_OBJECT_TYPE |
25 | 25 | AND b.OBJECT_TYPE = a.OBJECT_TYPE` |
26 | 26 | |
27 | - stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S, | |
28 | - ora.S) | |
27 | + stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S, ora.S) | |
29 | 28 | defer stmt.Close() |
30 | 29 | if err != nil { |
31 | 30 | return nil, err |
... | ... | @@ -50,5 +49,4 @@ func GetSelectConfig(db *ora.Ses, otype string) ([]SelectConfig, error) { |
50 | 49 | } |
51 | 50 | |
52 | 51 | return resp, nil |
53 | - | |
54 | 52 | } | ... | ... |
sql_sequrity.go
1 | -package restutility | |
1 | +package webutility | |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "strings" |
5 | 5 | ) |
6 | 6 | |
7 | -func SQLProtect(in string) string { | |
8 | - patern := "\"';&*<>=\\`:" | |
7 | +var patern string = "\"';&*<>=\\`:" | |
8 | + | |
9 | +func SQLSafeString(s string) string { | |
9 | 10 | for _, c := range patern { |
10 | - in = strings.Replace(in, string(c), "", -1) | |
11 | + s = strings.Replace(s, string(c), "", -1) | |
11 | 12 | } |
12 | - return in | |
13 | + return s | |
13 | 14 | } | ... | ... |