made a whole bunch of progress on figuring out plugin basics. Still very much a WIP

This commit is contained in:
devinchristianson
2019-12-28 18:01:21 +00:00
parent 958b351064
commit 6c4964b5d6
5 changed files with 152 additions and 8 deletions
+5 -5
View File
@@ -10,15 +10,15 @@ import (
var db *sql.DB
const (
DB_USER = "postgres"
DB_PASSWORD = "postgres"
DB_NAME = "test"
dbUser = "postgres"
dbPassword = "postgres"
dbName = "test"
)
func initDB() {
dbcreds := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
DB_USER, DB_PASSWORD, DB_NAME)
db, dberr := sql.Open("roach", dbcreds)
dbUser, dbPassword, dbName)
db, dberr := sql.Open("postgres", dbcreds)
if dberr != nil {
log.Fatal(dberr)
}
+47
View File
@@ -0,0 +1,47 @@
package assets
import (
"fmt"
"net/http"
"strings"
"core-networkmanager/frontend/plugins"
)
//Page struct to hold per-page data
type page struct {
Location string
Name string
}
//Plugin implements plugin interface
type Plugin struct {}
func init() {
plugins.RegisterPlugin("assets", &Plugin{})
}
//Setup sets up endpoints and such
func (p Plugin ) Setup (mux *http.ServeMux) {
fileserver := http.FileServer(FileSystem{http.Dir("./assets")})
mux.Handle("/assets/", http.StripPrefix("/assets", fileserver))
}
//FileSystem implements http.Filesystem, with Open() that doesnt allow Dirs
type FileSystem struct {
fs http.FileSystem
}
//Open overrides http.FileSystem.Open in order to prevent Directory access
func (cfs FileSystem) Open(path string) (http.File, error) {
fmt.Println("filepath",path)
f, err := cfs.fs.Open(path)
if err != nil {
return nil, err
}
st, err := f.Stat()
if st.IsDir() {
fmt.Println("Dir", path, "is not allowed")
index := strings.TrimSuffix(path, "/") + "/index.html"
if _, err := cfs.fs.Open(index); err != nil {
return nil, err
}
}
return f, nil
}
+49
View File
@@ -0,0 +1,49 @@
package plugins
import (
"log"
"sync"
"net/http"
)
var (
pluginMu sync.RWMutex
Plugins = make(map[string]Plugin)
universalPlugins = make(map[string]UniversalHandlerPlugin)
mux http.ServeMux
)
func Setup (mux *http.ServeMux) {
mux = mux
}
//Plugin is an interface defining all plugin exported functions
type Plugin interface {
Setup(*http.ServeMux) //should register endpoints and add database tables etc
}
//UniversalHandlerPlugin is an interface that extends the Plugin interface, for if a plugin needs to be called on all endpoints
type UniversalHandlerPlugin interface {
Plugin
UniversalHandler(http.HandlerFunc) http.HandlerFunc
}
//RegisterPlugin registers plugins. Should be called using init in plugin package
func RegisterPlugin(name string, p Plugin) {
pluginMu.Lock()
defer pluginMu.Unlock()
if p == nil {
log.Fatal("Plugin is nil")
}
if _, duplicate := Plugins[name]; duplicate {
log.Fatal("Plugin name already taken")
}
if _, universal := Plugins[name].(UniversalHandlerPlugin); universal {
universalPlugins[name] = p.(UniversalHandlerPlugin)
}
Plugins[name] = p
}
func RegisterEndpoint (pattern string, handler func(http.ResponseWriter, *http.Request)) {
}
+45
View File
@@ -0,0 +1,45 @@
package root
import (
"fmt"
"log"
"net/http"
"html/template"
"core-networkmanager/frontend/plugins"
)
//Page struct to hold per-page data
type page struct {
Location string
Name string
}
type Plugin struct {}
func init() {
plugins.RegisterPlugin("root", &Plugin{})
}
//Setup sets up endpoints and such
func (p Plugin ) Setup (mux *http.ServeMux) {
mux.HandleFunc("/", homePage)
}
func homePage(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
t, err := template.ParseFiles("index.gohtml")
if err != nil {
log.Fatal("Parse failed: ", err)
}
home := page{Location: "/", Name: "Home"}
search := page{Location: "/search", Name: "Search"}
data := struct { Pages []*page }{ []*page{ &home, &search } }
if err := t.ExecuteTemplate(w, "index", data); err != nil {
log.Fatal("ExecuteTemplate failed:", err)
}
} else {
r.ParseForm()
// logic part of log in
fmt.Println("username:", r.Form["username"])
fmt.Println("password:", r.Form["password"])
}
}
+6 -3
View File
@@ -5,15 +5,18 @@ import (
"net/http"
"strconv"
_ "github.com/lib/pq"
"core-networkmanager/frontend/plugins"
_ "core-networkmanager/frontend/plugins/root"
_ "core-networkmanager/frontend/plugins/assets"
)
func main() {
initDB()
var port = 8080
mux := http.NewServeMux()
fileserver := http.FileServer(FileSystem{http.Dir("./assets")})
mux.Handle("/assets/", http.StripPrefix("/assets", fileserver))
mux.HandleFunc("/", homePage)
plugins.Setup(mux)
plugins.Plugins["root"].Setup(mux)
plugins.Plugins["assets"].Setup(mux)
err := http.ListenAndServe(":" + strconv.Itoa(port), mux)
if(err != nil) {
log.Fatal("ListenAndServe failed with error: ", err)