Merge pull request #2098 from bradrydzewski/master
ability to serve website from disk
This commit is contained in:
commit
8c91205042
5 changed files with 224 additions and 12 deletions
|
@ -2,7 +2,6 @@ package router
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
|
@ -13,8 +12,6 @@ import (
|
|||
"github.com/drone/drone/server/debug"
|
||||
"github.com/drone/drone/server/metrics"
|
||||
"github.com/drone/drone/server/template"
|
||||
|
||||
"github.com/drone/drone-ui/dist"
|
||||
)
|
||||
|
||||
// Load loads the router
|
||||
|
@ -24,13 +21,11 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
|
|||
e.Use(gin.Recovery())
|
||||
e.SetHTMLTemplate(template.T)
|
||||
|
||||
if dir := os.Getenv("DRONE_STATIC_DIR"); dir == "" {
|
||||
fs := http.FileServer(dist.AssetFS())
|
||||
e.GET("/static/*filepath", func(c *gin.Context) {
|
||||
fs.ServeHTTP(c.Writer, c.Request)
|
||||
ui := server.NewWebsite()
|
||||
for _, path := range ui.Routes() {
|
||||
e.GET(path, func(c *gin.Context) {
|
||||
ui.File(c.Writer, c.Request)
|
||||
})
|
||||
} else {
|
||||
e.Static("/static", dir)
|
||||
}
|
||||
|
||||
e.Use(header.NoCache)
|
||||
|
@ -40,10 +35,11 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
|
|||
e.Use(session.SetUser())
|
||||
e.Use(token.Refresh)
|
||||
|
||||
e.GET("/login", server.ShowLogin)
|
||||
e.GET("/login/form", server.ShowLoginForm)
|
||||
e.GET("/logout", server.GetLogout)
|
||||
e.NoRoute(server.ShowIndex)
|
||||
e.NoRoute(func(c *gin.Context) {
|
||||
u := session.User(c)
|
||||
ui.Page(c.Writer, c.Request, u)
|
||||
})
|
||||
|
||||
user := e.Group("/api/user")
|
||||
{
|
||||
|
|
33
server/template/files/index_polymer.html
Normal file
33
server/template/files/index_polymer.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="author" content="bradrydzewski">
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
|
||||
|
||||
<title></title>
|
||||
<script>
|
||||
window.ENV = {};
|
||||
window.ENV.server = window.location.protocol+"//"+window.location.host;
|
||||
{{ if .csrf }}window.ENV.csrf = "{{ .csrf }}"{{ end }}
|
||||
{{ if .user }}
|
||||
window.USER = {{ json .user }};
|
||||
{{ end }}
|
||||
</script>
|
||||
<script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono">
|
||||
<link rel="import" href="/src/drone/drone-app.html">
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<drone-app></drone-app>
|
||||
</body>
|
||||
</html>
|
|
@ -13,6 +13,9 @@ var files = []struct {
|
|||
}, {
|
||||
name: "index.html",
|
||||
data: index,
|
||||
}, {
|
||||
name: "index_polymer.html",
|
||||
data: indexpolymer,
|
||||
}, {
|
||||
name: "login.html",
|
||||
data: login,
|
||||
|
@ -83,6 +86,42 @@ var index = `<!DOCTYPE html>
|
|||
</html>
|
||||
`
|
||||
|
||||
// files/index_polymer.html
|
||||
var indexpolymer = `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="author" content="bradrydzewski">
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
|
||||
|
||||
<title></title>
|
||||
<script>
|
||||
window.ENV = {};
|
||||
window.ENV.server = window.location.protocol+"//"+window.location.host;
|
||||
{{ if .csrf }}window.ENV.csrf = "{{ .csrf }}"{{ end }}
|
||||
{{ if .user }}
|
||||
window.USER = {{ json .user }};
|
||||
{{ end }}
|
||||
</script>
|
||||
<script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono">
|
||||
<link rel="import" href="/src/drone/drone-app.html">
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
padding:0px;
|
||||
margin:0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<drone-app></drone-app>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
// files/login.html
|
||||
var login = `<!DOCTYPE html>
|
||||
<html>
|
||||
|
|
78
server/ui.go
Normal file
78
server/ui.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone-ui/dist"
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/drone/drone/server/template"
|
||||
"github.com/drone/drone/shared/token"
|
||||
)
|
||||
|
||||
// Website defines an interface to serve the user interface.
|
||||
type Website interface {
|
||||
Page(rw http.ResponseWriter, r *http.Request, u *model.User)
|
||||
File(rw http.ResponseWriter, r *http.Request)
|
||||
Routes() []string
|
||||
}
|
||||
|
||||
type website struct {
|
||||
fs http.Handler
|
||||
}
|
||||
|
||||
// NewWebsite returns a new website loader.
|
||||
func NewWebsite() Website {
|
||||
path := os.Getenv("DRONE_WWW")
|
||||
if path != "" {
|
||||
return NewLocalWebsite(path)
|
||||
}
|
||||
return &website{
|
||||
fs: http.FileServer(dist.AssetFS()),
|
||||
}
|
||||
}
|
||||
|
||||
// Page serves a page in the user interface.
|
||||
func (w *website) Page(rw http.ResponseWriter, r *http.Request, u *model.User) {
|
||||
rw.WriteHeader(200)
|
||||
|
||||
path := r.URL.Path
|
||||
switch path {
|
||||
case "/login/form":
|
||||
params := map[string]interface{}{}
|
||||
template.T.ExecuteTemplate(rw, "login.html", params)
|
||||
|
||||
case "/login":
|
||||
if err := r.FormValue("error"); err != "" {
|
||||
params := map[string]interface{}{"error": err}
|
||||
template.T.ExecuteTemplate(rw, "error.html", params)
|
||||
} else {
|
||||
http.Redirect(rw, r, "/authorize", 303)
|
||||
}
|
||||
|
||||
default:
|
||||
var csrf string
|
||||
if u != nil {
|
||||
csrf, _ = token.New(
|
||||
token.CsrfToken,
|
||||
u.Login,
|
||||
).Sign(u.Hash)
|
||||
}
|
||||
params := map[string]interface{}{
|
||||
"user": u,
|
||||
"csrf": csrf,
|
||||
}
|
||||
template.T.ExecuteTemplate(rw, "index.html", params)
|
||||
}
|
||||
}
|
||||
|
||||
// File serves a static file for the user interface.
|
||||
func (w *website) File(rw http.ResponseWriter, r *http.Request) {
|
||||
w.fs.ServeHTTP(rw, r)
|
||||
}
|
||||
|
||||
func (w *website) Routes() []string {
|
||||
return []string{
|
||||
"/static/*filepath",
|
||||
}
|
||||
}
|
66
server/ui_local.go
Normal file
66
server/ui_local.go
Normal file
|
@ -0,0 +1,66 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/drone/drone/server/template"
|
||||
"github.com/drone/drone/shared/token"
|
||||
)
|
||||
|
||||
type local struct {
|
||||
dir string
|
||||
fs http.Handler
|
||||
}
|
||||
|
||||
// NewLocalWebsite returns a new website loader.
|
||||
func NewLocalWebsite(path string) Website {
|
||||
return &local{
|
||||
dir: path,
|
||||
fs: http.FileServer(
|
||||
http.Dir(path),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// Page serves a page in the user interface.
|
||||
func (w *local) Page(rw http.ResponseWriter, r *http.Request, u *model.User) {
|
||||
rw.WriteHeader(200)
|
||||
|
||||
path := r.URL.Path
|
||||
switch path {
|
||||
case "/login":
|
||||
if err := r.FormValue("error"); err != "" {
|
||||
// TODO login error
|
||||
} else {
|
||||
http.Redirect(rw, r, "/authorize", 303)
|
||||
}
|
||||
|
||||
default:
|
||||
var csrf string
|
||||
if u != nil {
|
||||
csrf, _ = token.New(
|
||||
token.CsrfToken,
|
||||
u.Login,
|
||||
).Sign(u.Hash)
|
||||
}
|
||||
params := map[string]interface{}{
|
||||
"user": u,
|
||||
"csrf": csrf,
|
||||
}
|
||||
|
||||
template.T.ExecuteTemplate(rw, "index_polymer.html", params)
|
||||
}
|
||||
}
|
||||
|
||||
// File serves a static file for the user interface.
|
||||
func (w *local) File(rw http.ResponseWriter, r *http.Request) {
|
||||
w.fs.ServeHTTP(rw, r)
|
||||
}
|
||||
|
||||
func (w *local) Routes() []string {
|
||||
return []string{
|
||||
"/src/*filepath",
|
||||
"/bower_components/*filepath",
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue