func main() { middle := interpose.New() router := mux.NewRouter() router.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, `<h1>Welcome to the public page!</h1><p><a href="/protected/">Rabbit hole</a></p>`) }) middle.UseHandler(router) // Now we will define a sub-router that uses the BasicAuth middleware // When you call any url starting with the path /protected, you will need to authenticate protectedRouter := mux.NewRouter().Methods("GET").PathPrefix("/protected").Subrouter() protectedRouter.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "Welcome to the protected page!") }) // Define middleware that pertains to the part of the site protected behind HTTP Auth // and add the protected router to the protected middleware protectedMiddlew := interpose.New() protectedMiddlew.Use(middleware.BasicAuth("john", "doe")) protectedMiddlew.UseHandler(protectedRouter) // Add the protected middleware and its router to the main router router.Methods("GET").PathPrefix("/protected").Handler(protectedMiddlew) http.ListenAndServe(":3001", middle) }
// Run runs the server and block until the server is shutdown func (s *Server) Run() { // XXX(tsileo) make the key persisiting between restart? // TODO retrive both key from the KvStore hawkKey := make([]byte, 64) if _, err := rand.Read(hawkKey); err != nil { panic(err) } // Set up auth // TODO Try to retrieve the API key from the KvStore or generate a new (UUID v4) // Maybe handle a master key with multiple key? so key can be revoked? authMiddleware := middleware.BasicAuth("", "token") middlewares := &serverMiddleware.SharedMiddleware{ Auth: authMiddleware, } // FIXME token as parameter authFunc := httputil.BasicAuthFunc("", "token") // Start the HTTP API s.SetUp() r := mux.NewRouter() // publicRoute := r.PathPrefix("/public").Subrouter() appRoute := r.PathPrefix("/app").Subrouter() ekvstore := s.KvStore() eblobstore := s.BlobStore() docstore.New(s.Log.New("ext", "docstore"), ekvstore, eblobstore).RegisterRoute(r.PathPrefix("/api/ext/docstore/v1").Subrouter(), middlewares) luaExt := lua.New(s.Log.New("ext", "lua"), hawkKey, authFunc, ekvstore, eblobstore) luaExt.RegisterRoute(r.PathPrefix("/api/ext/lua/v1").Subrouter(), middlewares) luaExt.RegisterAppRoute(appRoute, middlewares) api.New(r.PathPrefix("/api/v1").Subrouter(), middlewares, s.wg, s.DB, s.NsDB, s.KvUpdate, s.Router, s.blobs, s.watchHub) s.syncer = synctable.New(s.blobs, eblobstore, s.NsDB, s.Log.New("ext", "synctable")) s.syncer.RegisterRoute(r.PathPrefix("/api/sync/v1").Subrouter(), middlewares) // TODO(tsileo) add robots.txt handler, and a 204 favicon.ico handler // FIXME(tsileo) a way to make an app hook the index r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { index := `<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>BlobsStash</title> </head> <body><p> <p>This is a private <a href="https://github.com/tsileo/blobstash">BlobStash</a> instance.</p> </p></body></html>` w.Write([]byte(index)) }) // FIXME allowedorigins from config c := cors.New(cors.Options{ AllowedOrigins: []string{"*"}, }) secureMiddleware := secure.New(secure.Options{ FrameDeny: true, ContentTypeNosniff: true, BrowserXssFilter: true, ContentSecurityPolicy: "default-src 'self'", }) http.Handle("/", secureMiddleware.Handler(c.Handler(r))) s.Log.Info(fmt.Sprintf("server: HTTP API listening on 0.0.0.0:%d", s.port)) go func() { if err := http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil); err != nil { panic(err) } }() // XXX(tsileo) HTTPS version for later // http.Handle("/", secureMiddleware.Handler(c.Handler(r))) // srv := &http.Server{ // Addr: ":443", // Handler: http.DefaultServeMux, // } // s.Log.Info("server: HTTP API listening on 0.0.0.0:8050") // go func() { // http2.ConfigureServer(srv, &http2.Server{}) // if err := srv.ListenAndServeTLS(".lego/certificates/trucsdedev.com.crt", ".lego/certificates/trucsdedev.com.key"); err != nil { // panic(err) // } // }() s.TillShutdown() }