wip: add api auth and /resume endpoint
This commit is contained in:
parent
22e2f6005f
commit
aaec8ec08d
23 changed files with 1244 additions and 271 deletions
25
internal/delivery/http/v1/handler.go
Normal file
25
internal/delivery/http/v1/handler.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"git.roboces.dev/catalin/cvvvvv/internal/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
services *service.Services
|
||||
}
|
||||
|
||||
func NewHandler(services *service.Services) *Handler {
|
||||
return &Handler{
|
||||
services: services,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) Init(api *gin.RouterGroup) {
|
||||
v1 := api.Group("/v1")
|
||||
{
|
||||
v1.GET("/usage", h.getUsage)
|
||||
v1.GET("/ping", h.getPing)
|
||||
v1.GET("/resume", h.getResume)
|
||||
}
|
||||
}
|
||||
30
internal/delivery/http/v1/middleware.go
Normal file
30
internal/delivery/http/v1/middleware.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func containsValue(m map[string]string, value string) (string, error) {
|
||||
for _, v := range m {
|
||||
if v == value {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return value, errors.New("value is not in the provided map")
|
||||
}
|
||||
|
||||
func (h *Handler) VerifyAuthentication(ctx *gin.Context) (string, error) {
|
||||
header := ctx.GetHeader("X-API-KEY")
|
||||
if header != "" {
|
||||
return containsValue(h.services.Config.Auth.ApiKeys, header)
|
||||
}
|
||||
|
||||
key := ctx.Query("api_key")
|
||||
if key != "" {
|
||||
return containsValue(h.services.Config.Auth.ApiKeys, key)
|
||||
}
|
||||
|
||||
return "", errors.New("Missing API key")
|
||||
}
|
||||
12
internal/delivery/http/v1/ping.go
Normal file
12
internal/delivery/http/v1/ping.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (h *Handler) getPing(c *gin.Context) {
|
||||
c.Writer.Header().Set("Content-Type", "text/plain")
|
||||
c.String(http.StatusOK, "pong")
|
||||
}
|
||||
19
internal/delivery/http/v1/response.go
Normal file
19
internal/delivery/http/v1/response.go
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"git.roboces.dev/catalin/cvvvvv/pkg/logger"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type dataResponse struct {
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func newResponse(c *gin.Context, statusCode int, message string) {
|
||||
logger.Error(message)
|
||||
c.AbortWithStatusJSON(statusCode, response{message})
|
||||
}
|
||||
24
internal/delivery/http/v1/resume.go
Normal file
24
internal/delivery/http/v1/resume.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.roboces.dev/catalin/cvvvvv/internal/domain"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ResumeResponse struct {
|
||||
Resume domain.Resume `json:"resume"`
|
||||
}
|
||||
|
||||
func (h *Handler) getResume(ctx *gin.Context) {
|
||||
|
||||
_, err := h.VerifyAuthentication(ctx)
|
||||
if err != nil {
|
||||
newResponse(ctx, http.StatusUnauthorized, "Api key not provided or invalid")
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, ResumeResponse{
|
||||
Resume: h.services.Resumes.Get(),
|
||||
})
|
||||
}
|
||||
25
internal/delivery/http/v1/usage.go
Normal file
25
internal/delivery/http/v1/usage.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (h *Handler) getUsage(c *gin.Context) {
|
||||
c.Writer.Header().Set("Content-Type", "text/plain")
|
||||
message := fmt.Sprintf(`
|
||||
Hello! If you're seeing this message it means you are authorized to view my CV.
|
||||
You should have been provided an api key in order to query the different endpoints,
|
||||
which are not public. You can put the key into a X-API-KEY header or use it
|
||||
as a query param. Examples:
|
||||
|
||||
curl %s/api/v1/usage -H "X-API-KEY: verysecret"
|
||||
|
||||
curl %s/api/v1/usage?api_key=verysecret
|
||||
|
||||
`, c.Request.Host, c.Request.Host)
|
||||
|
||||
c.String(http.StatusOK, message)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue