feat: initial new portal bones

This commit is contained in:
Derrick Hammer 2024-01-11 19:11:53 -05:00
parent c80046e95f
commit 444de35e31
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
17 changed files with 323 additions and 2046 deletions

1
api.go Normal file
View File

@ -0,0 +1 @@
package main

7
api/api.go Normal file
View File

@ -0,0 +1,7 @@
package api
import "git.lumeweb.com/LumeWeb/portal/interfaces"
func Init(router interfaces.APIRegistry) error {
return nil
}

42
api/registry.go Normal file
View File

@ -0,0 +1,42 @@
package api
import (
"errors"
"git.lumeweb.com/LumeWeb/portal/api/router"
"git.lumeweb.com/LumeWeb/portal/interfaces"
)
var (
_ interfaces.APIRegistry = (*APIRegistryImpl)(nil)
)
type APIRegistryImpl struct {
apis map[string]interfaces.API
router *router.ProtocolRouter
}
func NewRegistry() interfaces.APIRegistry {
return &APIRegistryImpl{
apis: make(map[string]interfaces.API),
router: &router.ProtocolRouter{},
}
}
func (r *APIRegistryImpl) Register(name string, APIRegistry interfaces.API) error {
if _, exists := r.apis[name]; exists {
return errors.New("api already registered")
}
r.apis[name] = APIRegistry
return nil
}
func (r *APIRegistryImpl) Get(name string) (interfaces.API, error) {
APIRegistry, exists := r.apis[name]
if !exists {
return nil, errors.New("api not found")
}
return APIRegistry, nil
}
func (r *APIRegistryImpl) Router() *router.ProtocolRouter {
return r.router
}

14
api/router/router.go Normal file
View File

@ -0,0 +1,14 @@
package router
import "net/http"
type ProtocolRouter map[string]http.Handler
// Implement the ServeHTTP method on our new type
func (hs ProtocolRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if handler := hs[r.Host]; handler != nil {
handler.ServeHTTP(w, r)
} else {
http.Error(w, "Forbidden", 403) // Or Redirect?
}
}

12
cmd/portal/main.go Normal file
View File

@ -0,0 +1,12 @@
package main
import "go.uber.org/zap"
func main() {
portal := NewPortal()
err := portal.Initialize()
if err != nil {
portal.Logger().Fatal("Failed to initialize portal", zap.Error(err))
}
portal.Run()
}

63
cmd/portal/portal.go Normal file
View File

@ -0,0 +1,63 @@
package main
import (
"git.lumeweb.com/LumeWeb/portal/api"
"git.lumeweb.com/LumeWeb/portal/interfaces"
"git.lumeweb.com/LumeWeb/portal/protocols"
"github.com/spf13/viper"
"go.uber.org/zap"
"gorm.io/gorm"
"net/http"
)
var (
_ interfaces.Portal = (*PortalImpl)(nil)
)
type PortalImpl struct {
apiRegistry interfaces.APIRegistry
logger *zap.Logger
}
func NewPortal() interfaces.Portal {
logger, _ := zap.NewDevelopment()
return &PortalImpl{
apiRegistry: api.NewRegistry(),
logger: logger,
}
}
func (p *PortalImpl) Initialize() error {
for _, initFunc := range p.getInitFuncs() {
if err := initFunc(); err != nil {
return err
}
}
return nil
}
func (p *PortalImpl) Run() {
p.logger.Fatal("HTTP server stopped", zap.Error(http.ListenAndServe(":8080", p.apiRegistry.Router())))
}
func (p *PortalImpl) Config() *viper.Viper {
return viper.GetViper()
}
func (p *PortalImpl) Logger() *zap.Logger {
return p.logger
}
func (p *PortalImpl) Db() *gorm.DB {
return nil
}
func (p *PortalImpl) getInitFuncs() []func() error {
return []func() error{
func() error {
return api.Init(p.apiRegistry)
},
func() error {
return protocols.Init(p.Config())
},
}
}

23
config.go Normal file
View File

@ -0,0 +1,23 @@
package main
import "github.com/spf13/viper"
var (
ConfigFilePaths = []string{
"/etc/lumeweb/portal/",
"$HOME/.lumeweb/portal/",
".",
}
)
func Init() {
viper.SetConfigName("config")
viper.SetConfigType("yaml")
for _, path := range ConfigFilePaths {
viper.AddConfigPath(path)
}
viper.SetEnvPrefix("LUME_WEB_PORTAL")
viper.AutomaticEnv()
}

29
go.mod
View File

@ -1,3 +1,32 @@
module git.lumeweb.com/LumeWeb/portal module git.lumeweb.com/LumeWeb/portal
go 1.20 go 1.20
require (
github.com/spf13/viper v1.18.2
go.uber.org/zap v1.26.0
gorm.io/gorm v1.25.5
)
require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

1954
go.sum

File diff suppressed because it is too large Load Diff

17
interfaces/api.go Normal file
View File

@ -0,0 +1,17 @@
package interfaces
import (
"git.lumeweb.com/LumeWeb/portal/api/router"
"github.com/spf13/viper"
"go.uber.org/zap"
)
type API interface {
Initialize(config *viper.Viper, logger *zap.Logger) error
}
type APIRegistry interface {
Register(name string, APIRegistry API) error
Get(name string) (API, error)
Router() *router.ProtocolRouter
}

15
interfaces/portal.go Normal file
View File

@ -0,0 +1,15 @@
package interfaces
import (
"github.com/spf13/viper"
"go.uber.org/zap"
"gorm.io/gorm"
)
type Portal interface {
Initialize() error
Run()
Config() *viper.Viper
Logger() *zap.Logger
Db() *gorm.DB
}

10
interfaces/protocol.go Normal file
View File

@ -0,0 +1,10 @@
package interfaces
import (
"github.com/spf13/viper"
"go.uber.org/zap"
)
type Protocol interface {
Initialize(config *viper.Viper, logger *zap.Logger) error
}

128
main.go
View File

@ -1,133 +1,5 @@
package main package main
import (
"context"
"embed"
"git.lumeweb.com/LumeWeb/portal/config"
"git.lumeweb.com/LumeWeb/portal/controller"
"git.lumeweb.com/LumeWeb/portal/db"
"git.lumeweb.com/LumeWeb/portal/dnslink"
_ "git.lumeweb.com/LumeWeb/portal/docs"
"git.lumeweb.com/LumeWeb/portal/logger"
"git.lumeweb.com/LumeWeb/portal/middleware"
"git.lumeweb.com/LumeWeb/portal/service/auth"
"git.lumeweb.com/LumeWeb/portal/service/files"
"git.lumeweb.com/LumeWeb/portal/shared"
"git.lumeweb.com/LumeWeb/portal/tus"
"github.com/iris-contrib/swagger"
"github.com/iris-contrib/swagger/swaggerFiles"
"github.com/kataras/iris/v12"
irisContext "github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/middleware/cors"
"github.com/kataras/iris/v12/mvc"
"go.uber.org/zap"
"log"
"net/http"
)
// Embed a directory of static files for serving from the app's root path
//
//go:embed app/*
var embedFrontend embed.FS
// @title Lume Web Portal
// @version 1.0
// @description A decentralized data storage portal for the open web
// @contact.name Lume Web Project
// @contact.url https://lumeweb.com
// @contact.email contact@lumeweb.com
// @license.name MIT
// @license.url https://opensource.org/license/mit/
// @externalDocs.description OpenAPI
// @externalDocs.url https://swagger.io/resources/open-api/
func main() { func main() {
// Initialize the configuration settings
config.Init()
// Initialize the database connection
db.Init()
defer func() {
err := db.Close()
if err != nil {
logger.Get().Error("Failed to close db connection", zap.Error(err))
}
}()
logger.Init()
files.Init()
auth.Init()
// Create a new Iris app instance
app := iris.New()
// Enable Gzip compression for responses
app.Use(iris.Compression)
// Serve static files from the embedded directory at the app's root path
_ = embedFrontend
// app.HandleDir("/", embedFrontend)
api := app.Party("/api")
v1 := api.Party("/v1")
api.UseRouter(cors.New().Handler())
tusHandler := tus.Init()
// Register the AccountController with the MVC framework and attach it to the "/api/account" path
mvc.Configure(v1.Party("/account"), func(app *mvc.Application) {
app.Handle(new(controller.AccountController))
})
mvc.Configure(v1.Party("/auth"), func(app *mvc.Application) {
app.Handle(new(controller.AuthController))
})
mvc.Configure(v1.Party("/files"), func(app *mvc.Application) {
tusRoute := app.Router.Party(tus.TUS_API_PATH)
tusRoute.Use(middleware.VerifyJwt)
fromStd := func(handler http.Handler) func(ctx *irisContext.Context) {
return func(ctx *irisContext.Context) {
newCtx := context.WithValue(ctx.Request().Context(), shared.TusRequestContextKey, ctx)
handler.ServeHTTP(ctx.ResponseWriter(), ctx.Request().WithContext(newCtx))
}
}
tusRoute.Any("/{fileparam:path}", fromStd(http.StripPrefix(v1.GetRelPath()+tus.TUS_API_PATH+"/", tusHandler)))
tusRoute.Post("/{p:path}", fromStd(http.StripPrefix(tusRoute.GetRelPath()+tus.TUS_API_PATH, tusHandler)))
app.Handle(new(controller.FilesController))
})
swaggerConfig := swagger.Config{
// The url pointing to API definition.
URL: "http://localhost:8080/swagger/doc.json",
DeepLinking: true,
DocExpansion: "list",
DomID: "#swagger-ui",
// The UI prefix URL (see route).
Prefix: "/swagger",
}
swaggerUI := swagger.Handler(swaggerFiles.Handler, swaggerConfig)
app.Get("/swagger", swaggerUI)
// And the wildcard one for index.html, *.js, *.css and e.t.c.
app.Get("/swagger/{any:path}", swaggerUI)
app.Any("/{p:path}", dnslink.Handler)
// Start the Iris app and listen for incoming requests on port 80
err := app.Listen(":8080", func(app *iris.Application) {
routes := app.GetRoutes()
for _, route := range routes {
log.Println(route)
}
})
if err != nil {
logger.Get().Error("Failed starting webserver", zap.Error(err))
}
} }

5
protocols.go Normal file
View File

@ -0,0 +1,5 @@
package main
func main() {
}

7
protocols/protocols.go Normal file
View File

@ -0,0 +1,7 @@
package protocols
import "github.com/spf13/viper"
func Init(config *viper.Viper) error {
return nil
}

41
protocols/registry.go Normal file
View File

@ -0,0 +1,41 @@
package protocols
import (
"errors"
"git.lumeweb.com/LumeWeb/portal/interfaces"
)
var (
_ ProtocolRegistry = (*ProtocolRegistryImpl)(nil)
)
type ProtocolRegistry interface {
Register(name string, protocol interfaces.Protocol) error
Get(name string) (interfaces.Protocol, error)
}
type ProtocolRegistryImpl struct {
protocols map[string]interfaces.Protocol
}
func NewProtocolRegistry() ProtocolRegistry {
return &ProtocolRegistryImpl{
protocols: make(map[string]interfaces.Protocol),
}
}
func (r *ProtocolRegistryImpl) Register(name string, protocol interfaces.Protocol) error {
if _, exists := r.protocols[name]; exists {
return errors.New("protocol already registered")
}
r.protocols[name] = protocol
return nil
}
func (r *ProtocolRegistryImpl) Get(name string) (interfaces.Protocol, error) {
protocol, exists := r.protocols[name]
if !exists {
return nil, errors.New("protocol not found")
}
return protocol, nil
}

1
protocols/s5.go Normal file
View File

@ -0,0 +1 @@
package protocols