Add dev-mode with list of templates & scenarios
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Corteza auth
|
||||
= Corteza auth
|
||||
|
||||
.Main responsibilities:
|
||||
- Sign-up protocol
|
||||
@@ -8,3 +8,10 @@
|
||||
- Session management
|
||||
- Identity federation (login via external providers)
|
||||
- Support OAuth2 flows
|
||||
|
||||
== Development
|
||||
|
||||
=== Templates
|
||||
|
||||
All (golang) templates can be found under `assets/templates`.
|
||||
You can also find `scenarios.yaml` with list of all templates and scenaris with data that renders auth screens in all possible situations.
|
||||
|
||||
111
auth/assets/templates/scenarios.yaml
Normal file
111
auth/assets/templates/scenarios.yaml
Normal file
@@ -0,0 +1,111 @@
|
||||
# The following list of templates and scenarios describes
|
||||
# all possible views (hopefully).
|
||||
#
|
||||
# Please read auth/README.adoc for details
|
||||
|
||||
error-internal:
|
||||
Default:
|
||||
error: |-
|
||||
Lorem ipsum dolor sit...
|
||||
|
||||
login:
|
||||
All disabled: {}
|
||||
|
||||
All enabled:
|
||||
settings:
|
||||
LocalEnabled: true
|
||||
SignupEnabled: true
|
||||
PasswordResetEnabled: true
|
||||
ExternalEnabled: true
|
||||
providers:
|
||||
- { Label: Google, Handle: google, Icon: google }
|
||||
- { Label: Facebook, Handle: facebook, Icon: facebook }
|
||||
- { Label: Corteza, Handle: corteza, Icon: oidc }
|
||||
|
||||
Only external:
|
||||
settings:
|
||||
PasswordResetEnabled: true
|
||||
ExternalEnabled: true
|
||||
providers:
|
||||
- { Label: Google, Handle: google, Icon: google }
|
||||
- { Label: Facebook, Handle: facebook, Icon: facebook }
|
||||
- { Label: Corteza, Handle: corteza, Icon: oidc }
|
||||
|
||||
Without signup & pass reset:
|
||||
settings:
|
||||
LocalEnabled: true
|
||||
SignupEnabled: false
|
||||
PasswordResetEnabled: false
|
||||
|
||||
|
||||
With errors after submit:
|
||||
settings:
|
||||
LocalEnabled: true
|
||||
form:
|
||||
email: some.email@example.tld
|
||||
error: "There was an error..."
|
||||
|
||||
logout:
|
||||
Default: {}
|
||||
|
||||
signup:
|
||||
Default: {}
|
||||
|
||||
reset-password:
|
||||
Default: {}
|
||||
|
||||
request-password-reset:
|
||||
Default: {}
|
||||
|
||||
password-reset-requested:
|
||||
Default: {}
|
||||
|
||||
pending-email-confirmation:
|
||||
Default: {}
|
||||
|
||||
profile:
|
||||
Default: {}
|
||||
|
||||
change-password:
|
||||
Default: {}
|
||||
|
||||
authorized-clients:
|
||||
Empty: {}
|
||||
Full:
|
||||
authorizedClients:
|
||||
- Name: Corteza Web Applications
|
||||
- Name: Matrix Chat server
|
||||
- Name: Company's Wordpress
|
||||
|
||||
oauth2-authorize-client:
|
||||
Default:
|
||||
client:
|
||||
Name: name of the client
|
||||
user:
|
||||
Name: John Doe
|
||||
|
||||
Disabled:
|
||||
invalidUser: Some good reason why this authorization of client is disabled...
|
||||
disabled: true
|
||||
client:
|
||||
Name: name of the client
|
||||
user:
|
||||
Name: John Doe
|
||||
|
||||
sessions:
|
||||
Full:
|
||||
sessions:
|
||||
- Current: true
|
||||
ExpiresIn: 3
|
||||
RemoteAddr: 4.224.2.3
|
||||
UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36
|
||||
- ExpiresIn: 2
|
||||
RemoteAddr: 4.224.2.3
|
||||
SameRemoteAddr: true
|
||||
UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36
|
||||
- ExpiresIn: 1
|
||||
RemoteAddr: 4.224.2.3
|
||||
SameUserAgent: true
|
||||
UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36
|
||||
- ExpiresIn: 0
|
||||
UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36
|
||||
51
auth/assets/templates/template-dev.html.tpl
Normal file
51
auth/assets/templates/template-dev.html.tpl
Normal file
@@ -0,0 +1,51 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- Bootstrap core CSS -->
|
||||
<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)
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-dark text-light">
|
||||
<div class="container-fluid">
|
||||
<div class="row m-0 p-0">
|
||||
<div class="col-3">
|
||||
{{ range .templates }}
|
||||
<div class="pt-2">
|
||||
<code>{{ .Template }}.html.tpl</code>
|
||||
<ul class="nav flex-column">
|
||||
{{ range .Scenes }}
|
||||
<li class="nav-item border-top">
|
||||
<a target="preview"
|
||||
class="nav-link text-light"
|
||||
href="/auth/dev/scenarios?template={{ .Template }}&scene={{ .Name }}"
|
||||
onclick="location.hash=this.href"
|
||||
>
|
||||
<div>
|
||||
{{ .Name }}
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="col-9 m-0 p-0">
|
||||
<iframe
|
||||
name="preview"
|
||||
id="preview"
|
||||
class="w-100 border-0"
|
||||
style="height: 100vh;"
|
||||
src="about:blank"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -168,7 +168,7 @@ func New(ctx context.Context, log *zap.Logger, s store.Storer, opt options.AuthO
|
||||
log.Info("using embedded assets")
|
||||
}
|
||||
|
||||
if !opt.ReloadTemplates || len(opt.AssetsPath) == 0 {
|
||||
if !opt.DevelopmentMode || len(opt.AssetsPath) == 0 {
|
||||
log.Info("initializing templates without reloading (production mode)")
|
||||
tpls, err = NewStaticTemplates(tplBase, tplLoader)
|
||||
if err != nil {
|
||||
|
||||
107
auth/handlers/handle_dev.go
Normal file
107
auth/handlers/handle_dev.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package handlers
|
||||
|
||||
// Handlers dev-view for templates & scenarios
|
||||
//
|
||||
// See auth/README.adoc for details on how this works
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/auth/request"
|
||||
"github.com/cortezaproject/corteza-server/pkg/y7s"
|
||||
"gopkg.in/yaml.v3"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type (
|
||||
devScenariosDoc []*devTemplate
|
||||
devTemplate struct {
|
||||
Template string
|
||||
Scenes devScenes
|
||||
}
|
||||
|
||||
devScenes []*devScene
|
||||
devScene struct {
|
||||
Name string
|
||||
Template string
|
||||
Data map[string]interface{}
|
||||
}
|
||||
)
|
||||
|
||||
func (h *AuthHandlers) devView(req *request.AuthReq) (err error) {
|
||||
req.Template = "template-dev.html.tpl"
|
||||
req.Data["templates"], err = getScenes()
|
||||
return
|
||||
}
|
||||
|
||||
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 {
|
||||
err = h.Templates.ExecuteTemplate(w, s.Template+".html.tpl", s.Data)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func findScenario(template, scene string) (*devScene, error) {
|
||||
templates, err := getScenes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, t := range templates {
|
||||
if t.Template != template {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, s := range t.Scenes {
|
||||
if s.Name != scene {
|
||||
continue
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getScenes() (devScenariosDoc, error) {
|
||||
f, err := os.Open("auth/assets/templates/scenarios.yaml")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aux := devScenariosDoc{}
|
||||
return aux, yaml.NewDecoder(f).Decode(&aux)
|
||||
}
|
||||
|
||||
func (doc *devScenariosDoc) UnmarshalYAML(n *yaml.Node) error {
|
||||
return y7s.EachMap(n, func(k *yaml.Node, v *yaml.Node) (err error) {
|
||||
dt := &devTemplate{Template: k.Value, Scenes: devScenes{}}
|
||||
|
||||
err = y7s.EachMap(v, func(k *yaml.Node, v *yaml.Node) (err error) {
|
||||
s := &devScene{
|
||||
Name: k.Value,
|
||||
Template: dt.Template,
|
||||
Data: make(map[string]interface{}),
|
||||
}
|
||||
|
||||
if err = v.Decode(s.Data); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
dt.Scenes = append(dt.Scenes, s)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
*doc = append(*doc, dt)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -25,6 +25,11 @@ func (h *AuthHandlers) MountHttpRoutes(r chi.Router) {
|
||||
})
|
||||
})
|
||||
|
||||
if h.Opt.DevelopmentMode {
|
||||
r.Get("/auth/dev", h.handle(h.devView))
|
||||
r.Get("/auth/dev/scenarios", h.devSceneView)
|
||||
}
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
if h.Opt.RequestRateLimit > 0 {
|
||||
r.Use(httprate.LimitByIP(h.Opt.RequestRateLimit, h.Opt.RequestRateWindowLength)) // @todo make configurable
|
||||
|
||||
@@ -35,7 +35,7 @@ type (
|
||||
CsrfCookieName string `env:"AUTH_CSRF_COOKIE_NAME"`
|
||||
DefaultClient string `env:"AUTH_DEFAULT_CLIENT"`
|
||||
AssetsPath string `env:"AUTH_ASSETS_PATH"`
|
||||
ReloadTemplates bool `env:"AUTH_RELOAD_TEMPLATES"`
|
||||
DevelopmentMode bool `env:"AUTH_DEVELOPMENT_MODE"`
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -141,10 +141,10 @@ props:
|
||||
When corteza starts, if path exists it tries to load template files from it.
|
||||
If not it uses statically embedded files.
|
||||
|
||||
- name: reloadTemplates
|
||||
- name: developmentMode
|
||||
type: bool
|
||||
description: |-
|
||||
When enabled, corteza reloads template before every execution.
|
||||
Enable this for debugging or when developing auth templates.
|
||||
|
||||
Disable it for environments (production) where templates do not change between server restarts.
|
||||
Should be disabled in production where templates do not change between server restarts.
|
||||
|
||||
Reference in New Issue
Block a user