diff --git a/auth_utility.go b/auth_utility.go index 3526f80..1d5448c 100644 --- a/auth_utility.go +++ b/auth_utility.go @@ -27,24 +27,22 @@ type CredentialsStruct struct { Password string `json:"password"` } -func GenerateSalt() (string, error) { - salt := "" +func generateSalt() (salt string, error) { rawsalt := make([]byte, saltSize) + _, err := rand.Read(rawsalt) if err != nil { return "", err } + salt = hex.EncodeToString(rawsalt) return salt, nil } -func HashMessage(message string, presalt string) (string, string, error) { - hash, salt := "", "" - var err error - +func HashString(str string, presalt string) (hash, salt string, err error) { // chech if message is presalted if presalt == "" { - salt, err = GenerateSalt() + salt, err = generateSalt() if err != nil { return "", "", err } @@ -53,24 +51,26 @@ func HashMessage(message string, presalt string) (string, string, error) { } // convert strings to raw byte slices - rawmessage := []byte(message) + rawstr := []byte(str) rawsalt, err := hex.DecodeString(salt) if err != nil { return "", "", err } - rawdata := make([]byte, len(rawmessage) + len(rawsalt)) - rawdata = append(rawdata, rawmessage...) + + rawdata := make([]byte, len(rawstr) + len(rawsalt)) + rawdata = append(rawdata, rawstr...) rawdata = append(rawdata, rawsalt...) // hash message + salt hasher := sha256.New() hasher.Write(rawdata) rawhash := hasher.Sum(nil) + hash = hex.EncodeToString(rawhash) return hash, salt, nil } -func IssueAPIToken(username, role string) (string, error) { +func CreateAPIToken(username, role string) (string, error) { var apiToken string var err error diff --git a/format_utility.go b/format_utility.go index 9dc625c..79611a3 100644 --- a/format_utility.go +++ b/format_utility.go @@ -4,30 +4,30 @@ import ( "time" ) -func UnixToDate(input int64) time.Time { - return time.Unix(input, 0) +func UnixToDate(unix int64) time.Time { + return time.Unix(unix, 0) } -func DateToUnix(input interface{}) int64 { - if input != nil { - t := input.(time.Time) +func DateToUnix(date interface{}) int64 { + if date != nil { + t := date.(time.Time) return t.Unix() } return 0 } -func EqualQuotes(input string) string { - if input != "" { - return " = '" + input + "'" +func EqualQuotes(stmt string) string { + if stmt != "" { + stmt = " = '" + stmt + "'" } - return "" + return stmt } -func LikeQuotes(input string) string { - if input != "" { - return " LIKE UPPER('%" + input + "%')" +func LikeQuotes(stmt string) string { + if stmt != "" { + stmt " LIKE UPPER('%" + stmt + "%')" } - return "" + return stmt } diff --git a/http_utility.go b/http_utility.go index cf812e1..e6aafe7 100644 --- a/http_utility.go +++ b/http_utility.go @@ -5,24 +5,14 @@ import ( "encoding/json" ) -var _apiVersion = "/api/v1" -var _authEndPoint = "/token" - -func SetApiVersion(ver string) string { - _apiVersion = ver - return _apiVersion -} - -func SetAuthEndpoint(ep string) { - _authEndPoint = ep -} - const templateHttpErr500_EN = "An internal server error has occurred." const templateHttpErr500_RS = "Došlo je do greške na serveru." const templateHttpErr400_EN = "Bad request: invalid request body." const templateHttpErr400_RS = "Neispravan zahtev." +const templateHttpErr401_EN = "Unauthorized request." +const templateHttpErr401_RS = "Neautorizovan zahtev." -type HttpError struct { +type httpError struct { Error []HttpErrorDesc `json:"error"` Request string `json:"request"` } @@ -32,81 +22,64 @@ type HttpErrorDesc struct { Desc string `json:"description"` } -func RespondWithHttpError(w http.ResponseWriter, - req *http.Request, - code int, - httpErr []HttpErrorDesc) { - - err := HttpError{ - Error: httpErr, - Request: req.Method + " " + req.URL.Path, - } +func ErrorResponse(w http.ResponseWriter, r *http.Request, code int, desc []HttpErrorDesc) { + err := httpError{ desc, r.Method + " " + r.URL.Path } w.WriteHeader(code) json.NewEncoder(w).Encode(err) } -func RespondWithHttpError400(w http.ResponseWriter, req *http.Request) { - RespondWithHttpError(w, req, http.StatusBadRequest, []HttpErrorDesc{ - {Lang: "en", Desc: templateHttpErr400_EN}, - {Lang: "rs", Desc: templateHttpErr400_RS}, +func BadRequestResponse(w http.ResponseWriter, req *http.Request) { + ErrorResponse(w, req, http.StatusBadRequest, []HttpErrorDesc{ + { "en", templateHttpErr400_EN }, + { "rs", templateHttpErr400_RS }, }) } -func RespondWithHttpError500(w http.ResponseWriter, req *http.Request) { - RespondWithHttpError(w, req, http.StatusInternalServerError, []HttpErrorDesc{ - {Lang: "en", Desc: templateHttpErr500_EN}, - {Lang: "rs", Desc: templateHttpErr500_RS}, +func InternalServerErrorResponse(w http.ResponseWriter, req *http.Request) { + ErrorResponse(w, req, http.StatusInternalServerError, []HttpErrorDesc{ + { "en", templateHttpErr500_EN }, + { "rs", templateHttpErr500_RS }, }) } -//TODO: Add parameters to enable/disable roles authorization checks +func UnauthorizedResponse(w http.ResponseWriter, req *http.Request) { + ErrorResponse(w, req, http.StatusUnauthorized, []HttpErrorDesc{ + { "en", templateHttpErr500_EN }, + { "rs", templateHttpErr500_RS }, + }) +} + +// TODO: Add parameters to enable/disable roles authorization checks +// TODO: Check for content type // Sets common headers and checks for token validity. -func HttpPreProc(handlerFunc http.HandlerFunc, authEnabled bool) http.HandlerFunc { +func WrapHandler(handlerFunc http.HandlerFunc, needauth bool) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { -// @TODO: check Content-type header (must be application/json) -// ctype := w.Header.Get("Content-Type") -// if req.Method != "GET" && ctype != "application/json" { -// replyWithHttpError(w, req, http.StatusBadRequest, -// "Not a supported content type: " + ctype) -// } - w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", - `POST, - GET, - PUT, - DELETE, - OPTIONS`) + "POST, GET, PUT, DELETE, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", - `Accept, - Content-Type, - Content-Length, - Accept-Encoding, - X-CSRF-Token, - Authorization`) + "Accept, Content-Type, Content-Length, " + "Accept-Encoding, X-CSRF-Token, Authorization") + w.Header().Set("Content-Type", "application/json; charset=utf-8") if req.Method == "OPTIONS" { return } - if authEnabled { - if req.URL.Path != _apiVersion + _authEndPoint { - token := req.Header.Get("Authorization") - if _, err := ParseAPIToken(token); err != nil { - RespondWithHttpError(w, req, http.StatusUnauthorized, - []HttpErrorDesc{ - {Lang: "en", Desc: "Unauthorized request."}, - {Lang: "rs", Desc: "Neautorizovani zahtev."}, - }) - return - } + if needauth { + token := req.Header.Get("Authorization") + if _, err := ParseAPIToken(token); err != nil { + UnathorizedResponse(w, req, http.StatusUnauthorized) + return } } err := req.ParseForm() if err != nil { - RespondWithHttpError400(w, req) + BadRequestResponse(w, req) return } @@ -116,8 +89,8 @@ func HttpPreProc(handlerFunc http.HandlerFunc, authEnabled bool) http.HandlerFun } func NotFoundHandler(w http.ResponseWriter, req *http.Request) { - RespondWithHttpError(w, req, http.StatusNotFound, []HttpErrorDesc{ - {Lang: "en", Desc: "Not found."}, - {Lang: "rs", Desc: "Traženi resurs ne postoji."}, + ErrorResponse(w, req, http.StatusNotFound, []HttpErrorDesc{ + { "en", "Not found." }, + { "rs", "Traženi resurs ne postoji." }, }) } diff --git a/select_config.go b/select_config.go index c9af7d0..3b99462 100644 --- a/select_config.go +++ b/select_config.go @@ -24,8 +24,7 @@ func GetSelectConfig(db *ora.Ses, otype string) ([]SelectConfig, error) { AND b.LIST_TYPE = a.LIST_OBJECT_TYPE AND b.OBJECT_TYPE = a.OBJECT_TYPE` - stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S, - ora.S) + stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S, ora.S) defer stmt.Close() if err != nil { return nil, err @@ -50,5 +49,4 @@ func GetSelectConfig(db *ora.Ses, otype string) ([]SelectConfig, error) { } return resp, nil - }