first commit

This commit is contained in:
2020-12-31 17:49:54 +01:00
commit 2240985aa1
120 changed files with 11574 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
package auth
import (
"context"
"encoding/base64"
"encoding/json"
"github.com/gin-gonic/gin"
"github.com/gissleh/stufflog/internal/slerrors"
"net/http"
"strings"
)
var contextKey = struct{}{}
func UserID(ctx context.Context) string {
if c, ok := ctx.(*gin.Context); ok {
return UserID(c.Request.Context())
}
return ctx.Value(&contextKey).(string)
}
func DummyMiddleware(uuid string) gin.HandlerFunc {
return func(c *gin.Context) {
c.Request = c.Request.WithContext(
context.WithValue(c.Request.Context(), &contextKey, uuid),
)
}
}
func abortRequest(c *gin.Context) {
c.AbortWithStatusJSON(http.StatusUnauthorized, slerrors.ErrorResponse{
Code: http.StatusUnauthorized,
Message: "You're not supposed to be here!",
})
}
// TrustingJwtParserMiddleware is meant to be put behind an AWS API gateway that has already
// verified this token.
func TrustingJwtParserMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
auth := c.GetHeader("Authorization")
split := strings.Split(auth, ".")
if len(split) >= 3 {
data, err := base64.RawStdEncoding.DecodeString(split[1])
if err != nil {
abortRequest(c)
return
}
fields := make(map[string]interface{})
err = json.Unmarshal(data, &fields)
if err != nil {
abortRequest(c)
return
}
if sub, ok := fields["sub"].(string); ok {
c.Request = c.Request.WithContext(
context.WithValue(c.Request.Context(), &contextKey, sub),
)
} else {
abortRequest(c)
return
}
} else {
abortRequest(c)
}
}
}
+52
View File
@@ -0,0 +1,52 @@
package generate
import (
"crypto/rand"
"encoding/hex"
"log"
"strings"
)
func id(prefix string, length int) string {
var id [16]byte
var buffer [32]byte
builder := strings.Builder{}
builder.Grow(length + 31)
builder.WriteString(prefix)
for builder.Len() < length {
_, err := rand.Read(id[:])
if err != nil {
log.Panicln("generate.id: failed to use OS random:", err)
}
hex.Encode(buffer[:], id[:])
builder.Write(buffer[:])
}
return builder.String()[:length]
}
func GroupID() string {
return id("G", 16)
}
func ItemID() string {
return id("I", 16)
}
func ProjectID() string {
return id("P", 16)
}
func TaskID() string {
return id("T", 16)
}
func LogID() string {
return id("L", 16)
}
func GoalID() string {
return id("A", 16)
}
+18
View File
@@ -0,0 +1,18 @@
package slerrors
type badRequestError struct {
Text string
}
func (err *badRequestError) Error() string {
return "validation failed: " + err.Text
}
func BadRequest(text string) error {
return &badRequestError{Text: text}
}
func IsBadRequest(err error) bool {
_, ok := err.(*badRequestError)
return ok
}
+22
View File
@@ -0,0 +1,22 @@
package slerrors
type forbiddenError struct {
Message string
}
func (e *forbiddenError) Error() string {
return e.Message
}
func Forbidden(message string) error {
return &forbiddenError{Message: message}
}
func IsForbidden(err error) bool {
if err == nil {
return false
}
_, ok := err.(*forbiddenError)
return ok
}
+35
View File
@@ -0,0 +1,35 @@
package slerrors
import (
"github.com/gin-gonic/gin"
"net/http"
)
type ErrorResponse struct {
Code int `json:"errorCode"`
Message string `json:"errorMessage"`
}
func Respond(c *gin.Context, err error) {
if IsNotFound(err) {
c.JSON(http.StatusNotFound, ErrorResponse{
Code: http.StatusNotFound,
Message: err.Error(),
})
} else if IsForbidden(err) {
c.JSON(http.StatusForbidden, ErrorResponse{
Code: http.StatusForbidden,
Message: err.Error(),
})
} else if IsBadRequest(err) {
c.JSON(http.StatusBadRequest, ErrorResponse{
Code: http.StatusBadRequest,
Message: err.Error(),
})
} else {
c.JSON(http.StatusInternalServerError, ErrorResponse{
Code: http.StatusInternalServerError,
Message: err.Error(),
})
}
}
+18
View File
@@ -0,0 +1,18 @@
package slerrors
type notFoundError struct {
Subject string
}
func (err *notFoundError) Error() string {
return err.Subject + " not found"
}
func NotFound(subject string) error {
return &notFoundError{Subject: subject}
}
func IsNotFound(err error) bool {
_, ok := err.(*notFoundError)
return ok
}