feat: initial new portal bones
This commit is contained in:
parent
c80046e95f
commit
444de35e31
|
@ -0,0 +1,7 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import "git.lumeweb.com/LumeWeb/portal/interfaces"
|
||||||
|
|
||||||
|
func Init(router interfaces.APIRegistry) error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -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?
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
|
@ -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())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
29
go.mod
|
@ -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
|
||||||
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -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
128
main.go
|
@ -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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package protocols
|
||||||
|
|
||||||
|
import "github.com/spf13/viper"
|
||||||
|
|
||||||
|
func Init(config *viper.Viper) error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
package protocols
|
Loading…
Reference in New Issue