Skip to content

Commit

Permalink
Removed fiber in favor of default http server (#6)
Browse files Browse the repository at this point in the history
* Removed fiber in favor of default http server

* Fix sonar cloud issues

* Fix sonar cloud issues again
  • Loading branch information
jlucaspains authored Sep 10, 2023
1 parent 8aabc49 commit 7146cdf
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 120 deletions.
4 changes: 3 additions & 1 deletion backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ build
.env
coverage
tmp
*.exe
*.exe
*.crt
*.key
12 changes: 1 addition & 11 deletions backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,18 @@ go 1.20

require (
github.com/go-playground/validator/v10 v10.15.3
github.com/gofiber/fiber/v2 v2.49.1
github.com/gorilla/mux v1.8.0
github.com/joho/godotenv v1.5.1
github.com/stretchr/testify v1.8.4
)

require (
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.49.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.11.0 // indirect
Expand Down
27 changes: 2 additions & 25 deletions backend/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -12,27 +10,14 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.15.3 h1:S+sSpunYjNPDuXkWbK+x+bA7iXiW296KG4dL3X7xUZo=
github.com/go-playground/validator/v10 v10.15.3/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/gofiber/fiber/v2 v2.49.1 h1:0W2DRWevSirc8pJl4o8r8QejDR8TV6ZUCawHxwbIdOk=
github.com/gofiber/fiber/v2 v2.49.1/go.mod h1:nPUeEBUeeYGgwbDm59Gp7vS8MDyScL6ezr/Np9A13WU=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
Expand All @@ -41,18 +26,10 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.49.0 h1:9FdvCpmxB74LH4dPb7IJ1cOSsluR07XG3I1txXWwJpE=
github.com/valyala/fasthttp v1.49.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
Expand Down
30 changes: 13 additions & 17 deletions backend/handlers/certCheckHandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,32 @@ import (
"strings"
"time"

"github.com/gofiber/fiber/v2"
"github.com/jlucaspains/sharp-cert-checker/models"
)

func (h Handlers) GetSiteList(c *fiber.Ctx) error {
func (h Handlers) GetSiteList(w http.ResponseWriter, r *http.Request) {
regx := regexp.MustCompile(`https?:\/\/`)
siteList := []models.CheckListResult{}
for _, url := range h.SiteList {
hostName := regx.ReplaceAllString(url, "")
siteList = append(siteList, models.CheckListResult{Name: hostName, Url: url})
}

c.JSON(siteList)

return nil
h.JSON(w, http.StatusOK, siteList)
}

func (h Handlers) CheckStatus(c *fiber.Ctx) error {
func (h Handlers) CheckStatus(w http.ResponseWriter, r *http.Request) {
params := &models.CertCheckParams{}
params.Url = c.Query("url")

log.Println("Received message for URL: " + params.Url)
params.Url, _ = h.getQueryParam(r, "url")

if params.Url == "" {
c.Status(http.StatusBadRequest)
c.JSON(&fiber.Map{"error": "Missing URL parameter"})
return nil
h.JSON(w, http.StatusBadRequest, &models.ErrorResult{Errors: []string{"Url is required"}})
return
}

log.Println("Received message for URL: " + params.Url)

client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
Expand All @@ -52,16 +49,17 @@ func (h Handlers) CheckStatus(c *fiber.Ctx) error {
resp, err := client.Get(params.Url)

if err != nil {
return err
h.JSON(w, http.StatusBadRequest, &models.ErrorResult{Errors: []string{"Could not load provided URL"}})
return
}

hostName := strings.Split(params.Url, ":")[1]
hostName = strings.Trim(hostName, "/")

if resp.TLS == nil {
result := &models.CertCheckResult{Hostname: hostName, CertStartDate: time.Time{}, CertEndDate: time.Time{}, CertDnsNames: []string{}, IsValid: false}
c.JSON(result)
return nil
h.JSON(w, http.StatusOK, result)
return
}

certStartDate := resp.TLS.PeerCertificates[0].NotBefore
Expand All @@ -83,9 +81,7 @@ func (h Handlers) CheckStatus(c *fiber.Ctx) error {
ValidationIssues: errors,
}

c.JSON(result)

return nil
h.JSON(w, http.StatusOK, result)
}

func validate(cert *x509.Certificate, hostName string) (isValid bool, errors []string) {
Expand Down
80 changes: 27 additions & 53 deletions backend/handlers/certCheckHandlers_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package handlers

import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"

"github.com/gofiber/fiber/v2"
"github.com/gorilla/mux"
"github.com/jlucaspains/sharp-cert-checker/models"
"github.com/joho/godotenv"
"github.com/stretchr/testify/assert"
Expand All @@ -20,70 +18,67 @@ func TestGetSiteList(t *testing.T) {
godotenv.Load("../.test.env")
handlers := new(Handlers)
handlers.SiteList = handlers.GetConfigSites()
app := fiber.New()
defer app.Shutdown()
app.Get("/site-list", handlers.GetSiteList)
router := mux.NewRouter()
router.HandleFunc("/site-list", handlers.GetSiteList).Methods("GET")

code, respBody, err := getJsonTestRequestResponse[[]models.CertCheckResult](app, "GET", "/site-list", nil)
code, body, err := makeRequest[[]models.CheckListResult](router, "GET", "/site-list", nil)

assert.Nil(t, err)
assert.Equal(t, 200, code)
assert.Equal(t, 1, len(respBody))
assert.Equal(t, 1, len(*body))
}

func TestGetCheckStatus(t *testing.T) {
handlers := new(Handlers)
app := fiber.New()
defer app.Shutdown()

app.Get("/check-status", handlers.CheckStatus)
router := mux.NewRouter()
router.HandleFunc("/check-status", handlers.CheckStatus).Methods("GET")

url := fmt.Sprintf("/check-status?url=%s", "https://blog.lpains.net")
code, respBody, err := getJsonTestRequestResponse[models.CertCheckResult](app, "GET", url, nil)
code, body, err := makeRequest[models.CertCheckResult](router, "GET", url, nil)

assert.Nil(t, err)
assert.Equal(t, 200, code)
assert.True(t, respBody.IsValid)
assert.LessOrEqual(t, respBody.CertStartDate, time.Now())
assert.GreaterOrEqual(t, respBody.CertEndDate, time.Now())
assert.Contains(t, respBody.Hostname, "blog.lpains.net")
assert.Contains(t, respBody.CertDnsNames, "blog.lpains.net")
assert.True(t, body.IsValid)
assert.LessOrEqual(t, body.CertStartDate, time.Now())
assert.GreaterOrEqual(t, body.CertEndDate, time.Now())
assert.Contains(t, body.Hostname, "blog.lpains.net")
assert.Contains(t, body.CertDnsNames, "blog.lpains.net")
}

func TestGetCheckStatusNoUrl(t *testing.T) {
handlers := new(Handlers)
app := fiber.New()
defer app.Shutdown()

app.Get("/check-status", handlers.CheckStatus)
router := mux.NewRouter()
router.HandleFunc("/check-status", handlers.CheckStatus).Methods("GET")

url := "/check-status"
code, respBody, err := getJsonTestRequestResponse[map[string]string](app, "GET", url, nil)
code, body, err := makeRequest[models.ErrorResult](router, "GET", url, nil)

assert.Nil(t, err)
assert.Equal(t, 400, code)
assert.Equal(t, respBody["error"], "Missing URL parameter")
assert.Equal(t, "Url is required", body.Errors[0])
}

func TestGetCheckStatusHttp(t *testing.T) {
handlers := new(Handlers)
app := fiber.New()
defer app.Shutdown()

app.Get("/check-status", handlers.CheckStatus)
router := mux.NewRouter()
router.HandleFunc("/check-status", handlers.CheckStatus).Methods("GET")

url := fmt.Sprintf("/check-status?url=%s", "http://blog.lpains.net")
code, respBody, err := getJsonTestRequestResponse[models.CertCheckResult](app, "GET", url, nil)
code, body, err := makeRequest[models.CertCheckResult](router, "GET", url, nil)

assert.Nil(t, err)
assert.Equal(t, 200, code)
assert.False(t, respBody.IsValid)
assert.False(t, body.IsValid)
}

func TestGetCheckStatusAllValidations(t *testing.T) {
handlers := new(Handlers)
app := fiber.New()
defer app.Shutdown()

router := mux.NewRouter()
router.HandleFunc("/check-status", handlers.CheckStatus).Methods("GET")

mux := http.NewServeMux()
ts := httptest.NewUnstartedServer(mux)
Expand Down Expand Up @@ -147,32 +142,11 @@ yjbTOuy8KoxNb15g3Ysesbw=
ts.StartTLS()
defer ts.Close()

app.Get("/check-status", handlers.CheckStatus)

url := fmt.Sprintf("/check-status?url=%s", ts.URL)
code, respBody, err := getJsonTestRequestResponse[models.CertCheckResult](app, "GET", url, nil)
code, body, err := makeRequest[models.CertCheckResult](router, "GET", url, nil)

assert.Nil(t, err)
assert.Equal(t, 200, code)
assert.False(t, respBody.IsValid)
assert.Equal(t, []string{"Hostname is not valid", "Certificate is not valid yet or expired", "SHA1 is not a secure signature algorithm"}, respBody.ValidationIssues)
}

func getJsonTestRequestResponse[K any | []any](app *fiber.App, method string, url string, reqBody any) (code int, respBody K, err error) {
bodyJson, _ := json.Marshal(reqBody)
req, _ := http.NewRequest(method, url, bytes.NewReader(bodyJson))
resp, err := app.Test(req, 1000)
// If error we're done
if err != nil {
return
}
code = resp.StatusCode
// If no body content, we're done
if resp.ContentLength == 0 {
return
}
bodyData := make([]byte, resp.ContentLength)
_, _ = resp.Body.Read(bodyData)
err = json.Unmarshal(bodyData, &respBody)
return
assert.False(t, body.IsValid)
assert.Equal(t, []string{"Hostname is not valid", "Certificate is not valid yet or expired", "SHA1 is not a secure signature algorithm"}, body.ValidationIssues)
}
17 changes: 17 additions & 0 deletions backend/handlers/handlers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package handlers

import (
"encoding/json"
"fmt"
"net/http"
"os"
Expand All @@ -13,6 +14,22 @@ type Handlers struct {
SiteList []string
}

func (h Handlers) JSON(w http.ResponseWriter, statusCode int, data interface{}) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)
// convert data to json
result, _ := json.Marshal(data)
w.Write(result)
}

func (h Handlers) getQueryParam(r *http.Request, key string) (string, error) {
if param := r.URL.Query()[key]; param != nil {
return param[0], nil
}

return "", fmt.Errorf("%s not found", key)
}

func (h Handlers) GetConfigSites() []string {
siteList := []string{}
for i := 1; true; i++ {
Expand Down
22 changes: 22 additions & 0 deletions backend/handlers/handlers_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package handlers

import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/go-playground/validator/v10"
"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
)

Expand All @@ -31,3 +35,21 @@ func TestErrorTranslationSuccess(t *testing.T) {
assert.Len(t, result.Errors, 1)
assert.Equal(t, "Tagline2 should be greater than 1", result.Errors[0])
}

func makeRequest[K any | []any](router *mux.Router, method string, url string, body any) (code int, respBody *K, err error) {
inputBody := ""

if body != nil {
inputBodyJson, _ := json.Marshal(body)
inputBody = string(inputBodyJson)
}

req, _ := http.NewRequest(method, url, bytes.NewReader([]byte(inputBody)))
rr := httptest.NewRecorder()
router.ServeHTTP(rr, req)

result := new(K)
err = json.Unmarshal(rr.Body.Bytes(), &result)

return rr.Code, result, err
}
Loading

0 comments on commit 7146cdf

Please sign in to comment.