Separate App from main

- extract env vars
- add command line arguments
- move null backend to server package
This commit is contained in:
Peter Stuifzand 2018-12-09 17:39:36 +01:00
parent f21a68a56d
commit a2db7069e7
Signed by: peter
GPG Key ID: 374322D56E5209E8
4 changed files with 114 additions and 65 deletions

View File

@ -39,6 +39,7 @@ import (
type mainHandler struct {
Backend *memoryBackend
BaseURL string
TemplateDir string
}
@ -101,13 +102,10 @@ type authRequest struct {
AccessToken string `redis:"access_token"`
}
func newMainHandler(backend *memoryBackend) (*mainHandler, error) {
func newMainHandler(backend *memoryBackend, baseURL, templateDir string) (*mainHandler, error) {
h := &mainHandler{Backend: backend}
templateDir := os.Getenv("EKSTER_TEMPLATES")
if templateDir == "" {
return nil, fmt.Errorf("missing env var EKSTER_TEMPLATES")
}
h.BaseURL = baseURL
templateDir = strings.TrimRight(templateDir, "/")
h.TemplateDir = templateDir
@ -211,7 +209,7 @@ func isLoggedIn(backend *memoryBackend, sess *session) bool {
return false
}
if !authEnabled {
if !backend.AuthEnabled {
return true
}
@ -297,7 +295,7 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var page indexPage
page.Session = sess
page.Baseurl = strings.TrimRight(os.Getenv("EKSTER_BASEURL"), "/")
page.Baseurl = strings.TrimRight(h.BaseURL, "/")
err = h.renderTemplate(w, "index.html", page)
if err != nil {
@ -517,7 +515,7 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Println(authURL)
state := util.RandStringBytes(16)
redirectURI := fmt.Sprintf("%s/session/callback", os.Getenv("EKSTER_BASEURL"))
redirectURI := fmt.Sprintf("%s/session/callback", h.BaseURL)
sess, err := loadSession(sessionVar, conn)

View File

@ -28,7 +28,6 @@ import (
"github.com/gomodule/redigo/redis"
"p83.nl/go/ekster/pkg/auth"
"p83.nl/go/ekster/pkg/microsub"
"p83.nl/go/ekster/pkg/server"
)
@ -36,20 +35,21 @@ const (
ClientID string = "https://p83.nl/microsub-client"
)
type AppOptions struct {
Port int
AuthEnabled bool
Headless bool
RedisServer string
BaseURL string
TemplateDir string
}
var (
pool *redis.Pool
port int
authEnabled bool
headless bool
redisServer = flag.String("redis", "redis:6379", "")
pool *redis.Pool
)
func init() {
log.SetFlags(log.Lshortfile | log.Ldate | log.Ltime)
flag.IntVar(&port, "port", 80, "port for serving api")
flag.BoolVar(&authEnabled, "auth", true, "use auth")
flag.BoolVar(&headless, "headless", false, "disable frontend")
}
func newPool(addr string) *redis.Pool {
@ -87,18 +87,93 @@ func WithAuth(handler http.Handler, b *memoryBackend) http.Handler {
})
}
type App struct {
options AppOptions
backend *memoryBackend
hubBackend *hubIncomingBackend
}
func (app *App) Run() {
app.backend.run()
app.hubBackend.run()
log.Printf("Listening on port %d\n", app.options.Port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", app.options.Port), nil))
}
func NewApp(options AppOptions) *App {
app := &App{
options: options,
}
var backend *memoryBackend
app.backend = loadMemoryBackend()
app.backend.AuthEnabled = options.AuthEnabled
app.hubBackend = &hubIncomingBackend{app.backend}
http.Handle("/micropub", &micropubHandler{
Backend: app.backend,
})
handler := server.NewMicrosubHandler(app.backend)
if options.AuthEnabled {
handler = WithAuth(handler, app.backend)
}
http.Handle("/microsub", handler)
http.Handle("/incoming/", &incomingHandler{
Backend: app.hubBackend,
})
if !options.Headless {
handler, err := newMainHandler(backend, options.BaseURL, options.TemplateDir)
if err != nil {
log.Fatal(err)
}
http.Handle("/", handler)
}
return app
}
func main() {
log.Println("eksterd - microsub server")
var options AppOptions
flag.IntVar(&options.Port, "port", 80, "port for serving api")
flag.BoolVar(&options.AuthEnabled, "auth", true, "use auth")
flag.BoolVar(&options.Headless, "headless", false, "disable frontend")
flag.StringVar(&options.RedisServer, "redis", "redis:6379", "redis server")
flag.StringVar(&options.BaseURL, "baseurl", "", "http server baseurl")
flag.StringVar(&options.TemplateDir, "templates", "./templates", "template directory")
flag.Parse()
if authEnabled {
if options.AuthEnabled {
log.Println("Using auth")
} else {
log.Println("Authentication disabled")
}
if _, e := os.LookupEnv("EKSTER_BASEURL"); !e {
log.Fatal("EKSTER_BASEURL environment variable not found, please set with external url: https://example.com")
if options.BaseURL == "" {
if envVar, e := os.LookupEnv("EKSTER_BASEURL"); e {
options.BaseURL = envVar
} else {
log.Fatal("EKSTER_BASEURL environment variable not found, please set with external url, -baseurl url option")
}
}
if options.TemplateDir == "" {
if envVar, e := os.LookupEnv("EKSTER_TEMPLATES"); e {
options.TemplateDir = envVar
} else {
log.Fatal("EKSTER_TEMPLATES environment variable not found, use env var or -templates dir option")
}
}
createBackend := false
@ -110,13 +185,10 @@ func main() {
}
}
pool = newPool(*redisServer)
var backend microsub.Microsub
if createBackend {
backend = createMemoryBackend()
createMemoryBackend()
// TODO(peter): automatically gather this information from login or otherwise
log.Println(`Config file "backend.json" is created in the current directory.`)
log.Println(`Update "Me" variable to your website address "https://example.com/"`)
log.Println(`Update "TokenEndpoint" variable to the address of your token endpoint "https://example.com/token"`)
@ -124,36 +196,7 @@ func main() {
return
}
backend = loadMemoryBackend()
pool = newPool(options.RedisServer)
hubBackend := hubIncomingBackend{backend.(*memoryBackend)}
http.Handle("/micropub", &micropubHandler{
Backend: backend.(*memoryBackend),
})
handler := server.NewMicrosubHandler(backend)
if authEnabled {
handler = WithAuth(handler, backend.(*memoryBackend))
}
http.Handle("/microsub", handler)
http.Handle("/incoming/", &incomingHandler{
Backend: &hubBackend,
})
if !headless {
handler, err := newMainHandler(backend.(*memoryBackend))
if err != nil {
log.Fatal(err)
}
http.Handle("/", handler)
}
backend.(*memoryBackend).run()
hubBackend.run()
log.Printf("Listening on port %d\n", port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
NewApp(options).Run()
}

View File

@ -54,6 +54,7 @@ type memoryBackend struct {
Me string
TokenEndpoint string
AuthEnabled bool
ticker *time.Ticker
quit chan struct{}
@ -141,7 +142,7 @@ func (b *memoryBackend) save() {
jw.Encode(b)
}
func loadMemoryBackend() microsub.Microsub {
func loadMemoryBackend() *memoryBackend {
backend := &memoryBackend{}
err := backend.load()
if err != nil {
@ -153,7 +154,7 @@ func loadMemoryBackend() microsub.Microsub {
return backend
}
func createMemoryBackend() microsub.Microsub {
func createMemoryBackend() {
backend := memoryBackend{}
backend.lock.Lock()
@ -174,7 +175,6 @@ func createMemoryBackend() microsub.Microsub {
backend.lock.Unlock()
backend.save()
return &backend
}
// ChannelsGetList gets channels

View File

@ -15,7 +15,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
package server
import (
"p83.nl/go/ekster/pkg/microsub"
@ -25,11 +25,15 @@ import (
type NullBackend struct {
}
func (b *NullBackend) AddEventListener(el microsub.EventListener) error {
panic("implement me")
}
// ChannelsGetList gets no channels
func (b *NullBackend) ChannelsGetList() ([]microsub.Channel, error) {
return []microsub.Channel{
microsub.Channel{UID: "0001", Name: "notifications", Unread: 0},
microsub.Channel{UID: "0000", Name: "default", Unread: 0},
{UID: "0001", Name: "notifications", Unread: 0},
{UID: "0000", Name: "default", Unread: 0},
}, nil
}
@ -63,7 +67,9 @@ func (b *NullBackend) TimelineGet(before, after, channel string) (microsub.Timel
}
func (b *NullBackend) FollowGetList(uid string) ([]microsub.Feed, error) {
return []microsub.Feed{}, nil
return []microsub.Feed{
{Name: "test", Type: "feed", URL: "https://example.com/"},
}, nil
}
func (b *NullBackend) FollowURL(uid string, url string) (microsub.Feed, error) {
@ -75,7 +81,9 @@ func (b *NullBackend) UnfollowURL(uid string, url string) error {
}
func (b *NullBackend) Search(query string) ([]microsub.Feed, error) {
return []microsub.Feed{}, nil
return []microsub.Feed{
{"feed", "https://example.com/", "Example", "test.jpg", "test", microsub.Card{}},
}, nil
}
func (b *NullBackend) PreviewURL(url string) (microsub.Timeline, error) {