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
|
||||
|
||||
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
|
||||
|
||||
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() {
|
||||
// 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