Switched auth assets from statik to go:embed

This commit is contained in:
Denis Arh
2021-02-24 06:16:13 +01:00
parent 3c1514d936
commit 0598f6502b
10 changed files with 60 additions and 154 deletions
-4
View File
@@ -145,10 +145,6 @@ provision:
docs: $(STATIK)
$(STATIK) -p docs -m -Z -f -src=./docs
auth: $(STATIK)
$(STATIK) -dest auth -p handlers -a embedded_assets -m -Z -f -src=./auth/assets
#######################################################################################################################
# Quality Assurance
+1 -1
View File
@@ -31,7 +31,7 @@ login:
- { Label: Facebook, Handle: facebook, Icon: facebook }
- { Label: Corteza, Handle: corteza, Icon: oidc }
Without signup & pass reset:
Without signup and pass reset:
settings:
LocalEnabled: true
SignupEnabled: false
+1 -2
View File
@@ -7,7 +7,7 @@
<link href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" rel="stylesheet">
<script type="application/javascript">
window.addEventListener('load', function() {
document.getElementById("preview").src=location.hash.substring(1)
document.getElementsByID('preview').src=location.hash.substring(1)
})
</script>
</head>
@@ -39,7 +39,6 @@
<div class="col-9 m-0 p-0">
<iframe
name="preview"
id="preview"
class="w-100 border-0"
style="height: 100vh;"
src="about:blank"
+23 -2
View File
@@ -2,7 +2,9 @@ package auth
import (
"context"
"embed"
"fmt"
"github.com/Masterminds/sprig"
"github.com/cortezaproject/corteza-server/auth/external"
"github.com/cortezaproject/corteza-server/auth/handlers"
"github.com/cortezaproject/corteza-server/auth/oauth2"
@@ -11,6 +13,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/actionlog"
"github.com/cortezaproject/corteza-server/pkg/auth"
"github.com/cortezaproject/corteza-server/pkg/options"
"github.com/cortezaproject/corteza-server/pkg/version"
"github.com/cortezaproject/corteza-server/store"
systemService "github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
@@ -18,6 +21,7 @@ import (
oauth2def "github.com/go-oauth2/oauth2/v4"
"go.uber.org/zap"
"html/template"
"net/http"
"strconv"
"strings"
"time"
@@ -33,6 +37,9 @@ type (
}
)
//go:embed assets/public
var publicAssets embed.FS
// New initializes Auth service that orchestrates session manager, oauth2 manager and http request handlers
func New(ctx context.Context, log *zap.Logger, s store.Storer, opt options.AuthOpt) (svc *service, err error) {
var (
@@ -150,7 +157,13 @@ func New(ctx context.Context, log *zap.Logger, s store.Storer, opt options.AuthO
}
var (
tplBase = handlers.TemplateBase()
tplBase = template.New("").
Funcs(sprig.FuncMap()).
Funcs(template.FuncMap{
"version": func() string { return version.Version },
"buildtime": func() string { return version.BuildTime },
"links": handlers.GetLinks,
})
tplLoader templateLoader
)
@@ -164,7 +177,7 @@ func New(ctx context.Context, log *zap.Logger, s store.Storer, opt options.AuthO
}
log.Info("loading assets from filesystem", zap.String("path", opt.AssetsPath))
} else {
tplLoader = handlers.EmbeddedTemplates
tplLoader = EmbeddedTemplates
log.Info("using embedded assets")
}
@@ -275,6 +288,14 @@ func (svc service) gcOAuth2Tokens(ctx context.Context) {
func (svc service) MountHttpRoutes(r chi.Router) {
svc.handlers.MountHttpRoutes(r)
const uriRoot = "/auth/assets/public"
if len(svc.opt.AssetsPath) == 0 {
r.Handle(uriRoot+"/*", http.StripPrefix("/auth/assets", http.FileServer(http.FS(publicAssets))))
} else {
var root = strings.TrimRight(svc.opt.AssetsPath, "/") + "/public"
r.Handle(uriRoot+"/*", http.StripPrefix(uriRoot, http.FileServer(http.Dir(root))))
}
}
//func (svc service) WellKnownOpenIDConfiguration() http.HandlerFunc {
-125
View File
@@ -1,125 +0,0 @@
package handlers
import (
"fmt"
"github.com/Masterminds/sprig"
"github.com/cortezaproject/corteza-server/pkg/version"
"github.com/goware/statik/fs"
"html/template"
"io"
"io/ioutil"
"net/http"
"os"
)
type (
TemplateExecutor interface {
ExecuteTemplate(io.Writer, string, interface{}) error
}
)
const (
tmplRoot = "/templates"
TmplAuthorizedClients = "authorized-clients.html.tpl"
TmplChangePassword = "change-password.html.tpl"
TmplLogin = "login.html.tpl"
TmplLogout = "logout.html.tpl"
TmplOAuth2AuthorizeClient = "oauth2-authorize-client.html.tpl"
TmplRequestPasswordReset = "request-password-reset.html.tpl"
TmplPasswordResetRequested = "password-reset-requested.html.tpl"
TmplResetPassword = "reset-password.html.tpl"
TmplProfile = "profile.html.tpl"
TmplSessions = "sessions.html.tpl"
TmplSignup = "signup.html.tpl"
TmplPendingEmailConfirmation = "pending-email-confirmation.html.tpl"
TmplInternalError = "error-internal.html.tpl"
)
//var (
// Templates = []string{
// TmplAuthorizedClients,
// TmplChangePassword,
// TmplLogin,
// TmplLogout,
// TmplOAuth2AuthorizeClient,
// TmplRequestPasswordReset,
// TmplPasswordResetRequested,
// TmplResetPassword,
// TmplProfile,
// TmplSessions,
// TmplSignup,
// TmplPendingEmailConfirmation,
// TmplInternalError,
// }
//)
func TemplateBase() *template.Template {
return template.New("").
Funcs(sprig.FuncMap()).
Funcs(template.FuncMap{
"version": func() string { return version.Version },
"buildtime": func() string { return version.BuildTime },
"links": GetLinks,
})
}
// EmbeddedTemplates returns embedded templates.
//
// @todo migrate to go:embed as soon as we can
func EmbeddedTemplates(t *template.Template) (tpl *template.Template, err error) {
var (
f http.File
tplBody []byte
sfs http.FileSystem
)
if sfs, err = fs.New(embedded_assets); err != nil {
return
}
if t, err = t.Clone(); err != nil {
return
}
return t, fs.Walk(sfs, tmplRoot, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
// templates are always referenced with path, relative to template root
var tplName = path[len(tmplRoot)+1:]
if f, err = sfs.Open(path); err != nil {
return fmt.Errorf("could not open %s: %w", path, err)
} else if tplBody, err = ioutil.ReadAll(f); err != nil {
return fmt.Errorf("could not read %s: %w", path, err)
} else if t, err = t.New(tplName).Parse(string(tplBody)); err != nil {
return fmt.Errorf("could not parse %s: %w", path, err)
}
return nil
})
}
func EmbeddedPublicAssets() http.HandlerFunc {
sfs, err := fs.New(embedded_assets)
if err != nil {
return func(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprintf("could not read embeded filesystem: %v", err.Error()), http.StatusInternalServerError)
}
}
return func(w http.ResponseWriter, r *http.Request) {
http.StripPrefix("/auth/assets", http.FileServer(sfs)).ServeHTTP(w, r)
}
}
func DirectPublicAssets(prefix, root string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
http.StripPrefix(prefix, http.FileServer(http.Dir(root))).ServeHTTP(w, r)
}
}
+2 -2
View File
@@ -36,14 +36,14 @@ func (h *AuthHandlers) devView(req *request.AuthReq) (err error) {
func (h *AuthHandlers) devSceneView(w http.ResponseWriter, r *http.Request) {
s, err := findScenario(r.URL.Query().Get("template"), r.URL.Query().Get("scene"))
if err == nil {
if err == nil && s != nil {
err = h.Templates.ExecuteTemplate(w, s.Template+".html.tpl", s.Data)
return
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func findScenario(template, scene string) (*devScene, error) {
+22 -1
View File
@@ -15,6 +15,7 @@ import (
"github.com/gorilla/sessions"
"github.com/markbates/goth"
"go.uber.org/zap"
"io"
"net/http"
"net/url"
"sort"
@@ -52,10 +53,14 @@ type (
DeleteByUserID(ctx context.Context, userID uint64) error
}
templateExecutor interface {
ExecuteTemplate(io.Writer, string, interface{}) error
}
AuthHandlers struct {
Log *zap.Logger
Templates TemplateExecutor
Templates templateExecutor
OAuth2 *oauth2server.Server
SessionManager *session.Manager
AuthService authService
@@ -70,6 +75,22 @@ type (
handlerFn func(req *request.AuthReq) error
)
const (
TmplAuthorizedClients = "authorized-clients.html.tpl"
TmplChangePassword = "change-password.html.tpl"
TmplLogin = "login.html.tpl"
TmplLogout = "logout.html.tpl"
TmplOAuth2AuthorizeClient = "oauth2-authorize-client.html.tpl"
TmplRequestPasswordReset = "request-password-reset.html.tpl"
TmplPasswordResetRequested = "password-reset-requested.html.tpl"
TmplResetPassword = "reset-password.html.tpl"
TmplProfile = "profile.html.tpl"
TmplSessions = "sessions.html.tpl"
TmplSignup = "signup.html.tpl"
TmplPendingEmailConfirmation = "pending-email-confirmation.html.tpl"
TmplInternalError = "error-internal.html.tpl"
)
func init() {
gob.Register(&types.User{})
gob.Register(&types.AuthClient{})
+1 -10
View File
@@ -4,11 +4,9 @@ import (
"github.com/cortezaproject/corteza-server/auth/request"
"github.com/cortezaproject/corteza-server/pkg/actionlog"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/httprate"
"github.com/gorilla/csrf"
"net/http"
"strings"
)
func (h *AuthHandlers) MountHttpRoutes(r chi.Router) {
@@ -16,8 +14,6 @@ func (h *AuthHandlers) MountHttpRoutes(r chi.Router) {
l = GetLinks()
)
r.Use(middleware.StripSlashes)
r.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := actionlog.RequestOriginToContext(r.Context(), actionlog.RequestOrigin_Auth)
@@ -30,6 +26,7 @@ func (h *AuthHandlers) MountHttpRoutes(r chi.Router) {
r.Get("/auth/dev/scenarios", h.devSceneView)
}
r.Handle("/auth/", http.RedirectHandler("/auth", http.StatusSeeOther))
r.Group(func(r chi.Router) {
if h.Opt.RequestRateLimit > 0 {
r.Use(httprate.LimitByIP(h.Opt.RequestRateLimit, h.Opt.RequestRateWindowLength)) // @todo make configurable
@@ -95,10 +92,4 @@ func (h *AuthHandlers) MountHttpRoutes(r chi.Router) {
r.HandleFunc("/auth/oauth2/info", h.oauth2Info)
})
const uriRoot = "/auth/assets/public"
if len(h.Opt.AssetsPath) == 0 {
r.Handle(uriRoot+"/*", EmbeddedPublicAssets())
} else {
r.Handle(uriRoot+"/*", DirectPublicAssets(uriRoot, strings.TrimRight(h.Opt.AssetsPath, "/")+"/public"))
}
}
File diff suppressed because one or more lines are too long
+10 -1
View File
@@ -1,10 +1,14 @@
package auth
import (
"embed"
"html/template"
"io"
)
//go:embed assets/templates/*.tpl
var embeddedTemplates embed.FS
type (
templateLoader func(tpls *template.Template) (tpl *template.Template, err error)
@@ -51,7 +55,12 @@ func NewStaticTemplates(base *template.Template, loader templateLoader) (s *temp
return
}
// Executes preloaded templates
// ExecuteTemplate executes preloaded templates
func (t templateStatic) ExecuteTemplate(w io.Writer, name string, data interface{}) error {
return t.base.ExecuteTemplate(w, name, data)
}
// EmbeddedTemplates returns embedded templates.
func EmbeddedTemplates(t *template.Template) (tpl *template.Template, err error) {
return t.ParseFS(embeddedTemplates, "templates/*.html.tpl")
}