backend for moffas 5 based login
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

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
}
}