You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
4.3 KiB
167 lines
4.3 KiB
package handlers |
|
|
|
import ( |
|
"encoding/json" |
|
"fmt" |
|
"io" |
|
"moffas_go/helper" |
|
"moffas_go/logger" |
|
"net/http" |
|
"net/url" |
|
"strconv" |
|
"strings" |
|
) |
|
|
|
type HTTPContextKey string |
|
|
|
func Greeting(w http.ResponseWriter, r *http.Request) { |
|
// GENERATE RANDOMIZED reference_id TO IDENTIFY REQUESTS UNIQUELY |
|
var err error |
|
var res string |
|
type reqStruct struct { |
|
Name string `json:"name"` |
|
Password string `json:"password"` |
|
Salt string `json:"salt"` |
|
Iterations int `json:"iterations"` |
|
} |
|
|
|
var req reqStruct = reqStruct{} |
|
|
|
var ctxkey HTTPContextKey = "requsetID" |
|
reference_id := r.Context().Value(ctxkey).(string) |
|
|
|
defer func() { |
|
logger.Info(reference_id, "Response body: ", res) |
|
}() |
|
|
|
// SET THE RESPONSE TYPE TO application/json |
|
w.Header().Set("Content-Type", "application/json") |
|
response := map[string]any{ |
|
"error_code": "000000000", |
|
"error_message": "", |
|
} |
|
|
|
// GET THE REQUEST QUERY PARAMS AND THE RAW QUERY STRING |
|
var queryString string = string(r.URL.RawQuery) |
|
var query url.Values = r.URL.Query() |
|
if r.Method == http.MethodGet { |
|
// GET NAME FROM QUERY PARAMS |
|
names := query["name"] |
|
req.Name = strings.Join(names, "") |
|
|
|
// PREPARE THE RESPONSE |
|
if req.Name == "" { |
|
response["message"] = "Hello!" |
|
} else { |
|
response["message"] = "Hello, " + req.Name + "!" |
|
} |
|
response["reference_id"] = reference_id |
|
response["query_string"] = queryString |
|
req.Password = query["password"][0] |
|
req.Salt = query["salt"][0] |
|
req.Iterations, _ = strconv.Atoi(query["iterations"][0]) |
|
|
|
if req.Password == "" { |
|
req.Password = "rahasia" |
|
} |
|
response["password"] = req.Password |
|
|
|
if req.Salt == "" { |
|
req.Salt, _ = helper.GenerateRandomString(16) |
|
} |
|
response["salt"] = req.Salt |
|
|
|
if req.Iterations <= 0 { |
|
req.Iterations = 10000 |
|
} |
|
response["iterations"] = req.Iterations |
|
response["salted_password"] = helper.PBKDF2_SHA256(req.Password, req.Salt, req.Iterations) |
|
|
|
// SEND THE RESPONSE AS JSON |
|
res, _ = helper.JSONencode(response) |
|
fmt.Fprint(w, res) |
|
return |
|
|
|
} else if r.Method == http.MethodPost { |
|
// THE RECEIVED REQUEST METHOD IS POST |
|
logger.Info(reference_id, "Request Method: POST") |
|
|
|
// VERIFY THE CONTENT IS JSON |
|
if contentType := r.Header.Get("Content-Type"); contentType != "application/json" { |
|
// NOT JSON |
|
logger.Error(reference_id, "Invalid content-type: ", contentType) |
|
response["error_code"] = "400000001" |
|
response["error_message"] = "Bad Request. Not JSON" |
|
res, _ = helper.JSONencode(response) |
|
http.Error(w, res, http.StatusBadRequest) |
|
return |
|
} |
|
|
|
// READ THE POST BODY |
|
var body []byte |
|
body, err = io.ReadAll(r.Body) |
|
if err != nil { |
|
// FAILED TO READ BODY |
|
logger.Error(reference_id, err) |
|
response["error_code"] = "400000002" |
|
response["error_message"] = "Bad Request. Can't read POST body" |
|
// logger.E("ERROR : ", err) |
|
res, _ = helper.JSONencode(response) |
|
http.Error(w, res, http.StatusBadRequest) |
|
return |
|
} |
|
bodyString := string(body) |
|
logger.Info(reference_id, "POST BODY: ", bodyString) |
|
|
|
// EXTRACT DATA FROM JSON BODY |
|
err = json.Unmarshal(body, &req) |
|
if err != nil { |
|
// FAILED TO DECODE JSON |
|
logger.Error(reference_id, err) |
|
response["error_code"] = "400000003" |
|
response["error_message"] = "Bad Request. Invalid JSON" |
|
// logger.E("ERROR : ", err) |
|
res, _ = helper.JSONencode(response) |
|
http.Error(w, res, http.StatusBadRequest) |
|
return |
|
} |
|
|
|
if req.Password == "" { |
|
req.Password = "rahasia" |
|
} |
|
response["password"] = req.Password |
|
|
|
if req.Salt == "" { |
|
req.Salt, _ = helper.GenerateRandomString(16) |
|
} |
|
response["salt"] = req.Salt |
|
|
|
if req.Iterations <= 0 { |
|
req.Iterations = 10000 |
|
} |
|
response["iterations"] = req.Iterations |
|
response["salted_password"] = helper.PBKDF2_SHA256(req.Password, req.Salt, req.Iterations) |
|
|
|
// PREPARE THE RESPONSE |
|
if req.Name == "" { |
|
response["message"] = "Hello!" |
|
} else { |
|
response["message"] = "Hello, " + req.Name + "!" |
|
} |
|
response["reference_id"] = reference_id |
|
response["query_string"] = queryString |
|
|
|
// SEND THE RESPONSE AS JSON |
|
res, _ = helper.JSONencode(response) |
|
fmt.Fprint(w, res) |
|
return |
|
|
|
} else { |
|
// METHOD NOT ALLOWED (not GET or POST) |
|
response["error_code"] = "405000001" |
|
response["error_message"] = "Method Not Allowed" |
|
res, _ = helper.JSONencode(response) |
|
http.Error(w, res, http.StatusMethodNotAllowed) |
|
return |
|
} |
|
}
|
|
|