Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaoticLeah committed Apr 26, 2024
2 parents 6c45852 + 0942078 commit d2e82e8
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 55 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
env:
REGISTRY: ghcr.io
IMAGE_NAME: mstarongithub/mk-plugin-repo
REPO_LOG_LEVEL: warn

jobs:
build:
Expand Down Expand Up @@ -52,3 +53,4 @@ jobs:
file: Dockerfile
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.output.labels }}
build-args: log_level=${{ env.REPO_LOG_LEVEL }}
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ RUN --mount=type=cache,target=/go-cache GOCACHE=/go-cache CGO_ENABLED=1 GOOS=lin
# ---- Final slim container
FROM gcr.io/distroless/base-debian12 AS release-stage
WORKDIR /
ARG log_level
ENV env_log_level $log_level
COPY --from=buildstage-go /server /server
EXPOSE 8080
CMD [ "/server" ]
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
require (
cloud.google.com/go/compute v1.20.1 // indirect
github.com/alexedwards/argon2id v1.0.0 // indirect
github.com/justinas/nosurf v1.1.1 // indirect
github.com/rs/cors v1.11.0 // indirect
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/justinas/nosurf v1.1.1 h1:92Aw44hjSK4MxJeMSyDa7jwuI9GR2J/JCQiaKvXXSlk=
github.com/justinas/nosurf v1.1.1/go.mod h1:ALpWdSbuNGy2lZWtyXdjkYv4edL23oSEgfBT1gPJ5BQ=
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand Down
49 changes: 38 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package main

import (
"embed"
"flag"

"github.com/sirupsen/logrus"
_ "github.com/volatiletech/authboss-renderer"
abrenderer "github.com/volatiletech/authboss-renderer"

_ "github.com/mstarongithub/mk-plugin-repo/auth-old"
authold "github.com/mstarongithub/mk-plugin-repo/auth-old"
"github.com/mstarongithub/mk-plugin-repo/config"
"github.com/mstarongithub/mk-plugin-repo/fswrapper"
"github.com/mstarongithub/mk-plugin-repo/server"
Expand All @@ -19,8 +22,14 @@ const DB_DEFAULT_FILE = "db.sqlite"
//go:embed frontend/build frontend/build/_app/*
var frontendFS embed.FS

var level = flag.String(
"loglevel",
"info",
"Set the log level of the app to one of \"debug\", \"info\", \"warn\", \"error\"",
)

func main() {
logrus.SetLevel(logrus.DebugLevel)
setLogLevelFromArgs()
_, err := config.ReadConfig(nil)
if err != nil {
logrus.WithError(err).Warnln("Err reading config")
Expand All @@ -35,22 +44,40 @@ func main() {
if err != nil {
panic(err)
}
// ab, err := authold.SetupAuthboss(
// &store,
// []byte("placeholder string"),
// []byte("placeholder string"),
// abrenderer.NewEmail("/auth", "ab_views"),
// )
// if err != nil {
// panic(err)
// }
ab, err := authold.SetupAuthboss(
&store,
[]byte("placeholder string"),
[]byte("placeholder string"),
abrenderer.NewEmail("/auth", "ab_views"),
)
if err != nil {
panic(err)
}
httpServer, err := server.NewServer(
fswrapper.NewFSWrapper(frontendFS, "frontend/build/", false),
nil,
ab,
&store,
)
if err != nil {
panic(err)
}
panic(httpServer.Run(":8080"))
}

func setLogLevelFromArgs() {
flag.Parse()
switch *level {
case "debug":
logrus.SetLevel(logrus.DebugLevel)
case "info":
logrus.SetLevel(logrus.InfoLevel)
case "warn":
logrus.SetLevel(logrus.WarnLevel)
case "error":
logrus.SetLevel(logrus.ErrorLevel)
case "fatal":
logrus.SetLevel(logrus.FatalLevel)
default:
logrus.SetLevel(logrus.WarnLevel)
}
}
62 changes: 47 additions & 15 deletions server/middlewares.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,59 @@ package server
import (
"context"
"net/http"
)

type withContextValsMiddleware struct {
pairs map[any]any
nextz http.Handler
}
"github.com/justinas/nosurf"
"github.com/sirupsen/logrus"
"gitlab.com/mstarongitlab/weblogger"
)

type HandlerBuilder func(http.Handler) http.Handler

func addContextValsMiddleware(next http.Handler, pairs map[any]any) *withContextValsMiddleware {
return &withContextValsMiddleware{
pairs: pairs,
nextz: next,
func ChainMiddlewares(base http.Handler, links ...HandlerBuilder) http.Handler {
for _, f := range links {
base = f(base)
}
return base
}

func (c *withContextValsMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
for key, val := range c.pairs {
ctx = context.WithValue(ctx, key, val)
func ContextValsMiddleware(pairs map[any]any) HandlerBuilder {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
for key, val := range pairs {
ctx = context.WithValue(ctx, key, val)
}
newRequest := r.WithContext(ctx)
h.ServeHTTP(w, newRequest)
})
}
newRequest := r.WithContext(ctx)
c.nextz.ServeHTTP(w, newRequest)
}

func WebLoggerWrapper(h http.Handler) http.Handler {
return weblogger.LoggingMiddleware(
h,
&weblogger.Config{
DefaultLogLevel: weblogger.LOG_LEVEL_DEBUG,
FailedRequestLevel: weblogger.LOG_LEVEL_WARN,
},
)
}

func NosurfCheckWrapper(h http.Handler) http.Handler {
n := nosurf.New(h)
n.SetFailureHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logrus.WithField("reason", nosurf.Reason(r)).Warnln("Failed to validate CSRF token")
w.WriteHeader(http.StatusBadRequest)
}))
return n
}

func NosurfTokenInsertMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
newReq := r.WithContext(
context.WithValue(r.Context(), CONTEXT_KEY_CSRF_TOKEN, nosurf.Token(r)),
)
w.Header().Set("CSRF-Token", nosurf.Token(r))
h.ServeHTTP(w, newReq)
})
}
47 changes: 29 additions & 18 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import (
"github.com/rs/cors"
"github.com/sirupsen/logrus"
"github.com/volatiletech/authboss/v3"
"gitlab.com/mstarongitlab/weblogger"
_ "github.com/volatiletech/authboss/v3/confirm"
_ "github.com/volatiletech/authboss/v3/lock"
"github.com/volatiletech/authboss/v3/remember"

"github.com/mstarongithub/mk-plugin-repo/storage"
)
Expand All @@ -23,9 +25,10 @@ type Server struct {
type ServerContextKey string

const (
CONTEXT_KEY_SERVER = ServerContextKey("server")
CONTEXT_KEY_STORAGE = ServerContextKey("storage")
CONTEXT_KEY_AUTHBOSS = ServerContextKey("authboss")
CONTEXT_KEY_SERVER = ServerContextKey("server")
CONTEXT_KEY_STORAGE = ServerContextKey("storage")
CONTEXT_KEY_AUTHBOSS = ServerContextKey("authboss")
CONTEXT_KEY_CSRF_TOKEN = ServerContextKey("csrf_token")
)

func NewServer(
Expand All @@ -48,22 +51,23 @@ func NewServer(
authboss: ab,
}

server.handler = cors.AllowAll().Handler(
addContextValsMiddleware(
weblogger.LoggingMiddleware(
mainRouter,
&weblogger.Config{
DefaultLogLevel: weblogger.LOG_LEVEL_DEBUG,
FailedRequestLevel: weblogger.LOG_LEVEL_WARN,
},
),
server.handler = ChainMiddlewares(
mainRouter,
ContextValsMiddleware(
map[any]any{
CONTEXT_KEY_SERVER: &server,
CONTEXT_KEY_STORAGE: store,
CONTEXT_KEY_AUTHBOSS: ab,
},
),
cors.AllowAll().Handler,
ab.LoadClientStateMiddleware,
remember.Middleware(ab),
// NosurfTokenInsertMiddleware,
// NosurfCheckWrapper,
WebLoggerWrapper,
)

return &server, nil
}

Expand Down Expand Up @@ -95,26 +99,26 @@ func (s *Server) Run(addr string) error {
}

// NOTE: Error return value unused currently and can safely be ignored
func buildApiRouter(_ *authboss.Authboss) (http.Handler, error) {
func buildApiRouter(ab *authboss.Authboss) (http.Handler, error) {
router := http.NewServeMux()

// router.Handle("/auth", ab.Core.Router)
router.Handle("/v1/", http.StripPrefix("/v1", buildV1Router()))
router.Handle("/v1/", http.StripPrefix("/v1", buildV1Router(ab)))
return router, nil
}

func buildV1Router() http.Handler {
func buildV1Router(ab *authboss.Authboss) http.Handler {
router := http.NewServeMux()

router.HandleFunc("GET /plugins", getPluginList)
router.HandleFunc("GET /plugins/{pluginId}", getSpecificPlugin)
router.HandleFunc("GET /plugins/{pluginId}/{versionName}", getVersion)
router.Handle("/", buildV1RestrictedRouter())
router.Handle("/", buildV1RestrictedRouter(ab))

return router
}

func buildV1RestrictedRouter() http.Handler {
func buildV1RestrictedRouter(ab *authboss.Authboss) http.Handler {
router := http.NewServeMux()

router.HandleFunc("POST /plugins", addNewPlugin)
Expand All @@ -123,5 +127,12 @@ func buildV1RestrictedRouter() http.Handler {
router.HandleFunc("DELETE /plugins/{pluginId}", deleteSpecificPlugin)
router.HandleFunc("DELETE /plugins/[pluginId]/{versionName}", hideVersion)

// handler := ChainMiddlewares(
// router,
// authboss.Middleware2(ab, authboss.RequireNone, authboss.RespondUnauthorized),
// lock.Middleware(ab),
// confirm.Middleware(ab),
// )

return router
}
2 changes: 1 addition & 1 deletion server/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func dbPluginToApiPlugin(plugin *storage.Plugin) Plugin {
SummaryShort: plugin.SummaryShort,
SummaryLong: plugin.SummaryLong,
CurrentVersion: plugin.CurrentVersion,
AllVersions: append(plugin.PreviousVersions, plugin.CurrentVersion),
AllVersions: plugin.PreviousVersions,
Tags: plugin.Tags,
AuthorID: plugin.AuthorID,
}
Expand Down
10 changes: 9 additions & 1 deletion storage/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,16 @@ func (storage *Storage) NewPlugin(
return nil, ErrAccountNotApproved
}

// Check if version already exists
placeholder := Plugin{}
storage.db.First(&placeholder, "name = ?", name)
if placeholder.ID != 0 {
logrus.WithField("plugin", plugin).Debugln("new plugin already exists")
return nil, ErrAlreadyExists
}

logrus.WithField("plugin", plugin).Debugln("Inserting new plugin")
res := storage.db.Debug().Create(&plugin)
res := storage.db.Create(&plugin)
if res.RowsAffected == 0 {
return nil, fmt.Errorf("rows affected during plugin creation were 0: %w", err)
} else if res.Error != nil {
Expand Down
29 changes: 22 additions & 7 deletions storage/pluginVersions.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,14 @@ func (storage *Storage) TryFindVersion(pluginID uint, versionName string) (*Plug
PluginID: pluginID,
}
// TODO: Add logging
result := storage.db.First(&version)
result := storage.db.Where("version = ?", versionName).
Where("plugin_id = ?", pluginID).
First(&version)
if result.RowsAffected < 1 {
// TODO: Add logging
logrus.WithFields(logrus.Fields{
"pluginID": pluginID,
"versionName": versionName,
}).Debugln("Couldn't find plugin version")
return nil, ErrVersionNotFound
}
if result.Error != nil {
Expand Down Expand Up @@ -97,9 +102,18 @@ func (storage *Storage) NewVersion(
) error {
// First check if a version already exists
_, err := storage.TryFindVersion(forPluginID, versionName)
if !errors.Is(err, ErrVersionNotFound) {
// TODO: Add logging
if err == nil {
logrus.WithFields(logrus.Fields{
"pluginID": forPluginID,
"versionName": versionName,
}).Debugln("Got no error while looking if a new version already exists. Assuming it exists already, aborting")
return ErrAlreadyExists
} else if !errors.Is(err, ErrVersionNotFound) {
logrus.WithError(err).WithFields(logrus.Fields{
"pluginID": forPluginID,
"versionName": versionName,
}).Debugln("Got err that is not ErrVersionNotFound from check if plugin version exists, aborting")
return err
}

// Then check if there actually is a plugin with the given ID
Expand All @@ -111,9 +125,10 @@ func (storage *Storage) NewVersion(

// Now make the new version, push it to the db
newVersion := PluginVersion{
PluginID: forPluginID,
Version: versionName,
Code: code,
PluginID: forPluginID,
Version: versionName,
Code: code,
AiScriptVersion: aiscript_version,
}
// TODO: Add logging
result := storage.db.Create(&newVersion)
Expand Down
Loading

0 comments on commit d2e82e8

Please sign in to comment.