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.
168 lines
4.3 KiB
168 lines
4.3 KiB
11 months ago
|
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
|
||
|
}
|
||
|
}
|