Merge pull request #255 from Wakeful-Cloud/main

Template Fixes
This commit is contained in:
Juan Font 2021-12-24 16:12:33 +01:00 committed by GitHub
commit fb933b7d41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 39 deletions

56
api.go
View file

@ -1,10 +1,12 @@
package headscale package headscale
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"html/template"
"io" "io"
"net/http" "net/http"
"strings" "strings"
@ -38,6 +40,28 @@ func (h *Headscale) KeyHandler(ctx *gin.Context) {
) )
} }
type registerWebAPITemplateConfig struct {
Key string
}
var registerWebAPITemplate = template.Must(
template.New("registerweb").Parse(`<html>
<body>
<h1>headscale</h1>
<p>
Run the command below in the headscale server to add this machine to your network:
</p>
<p>
<code>
<b>headscale -n NAMESPACE nodes register --key {{.Key}}</b>
</code>
</p>
</body>
</html>`),
)
// RegisterWebAPI shows a simple message in the browser to point to the CLI // RegisterWebAPI shows a simple message in the browser to point to the CLI
// Listens in /register. // Listens in /register.
func (h *Headscale) RegisterWebAPI(ctx *gin.Context) { func (h *Headscale) RegisterWebAPI(ctx *gin.Context) {
@ -48,24 +72,22 @@ func (h *Headscale) RegisterWebAPI(ctx *gin.Context) {
return return
} }
ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` var content bytes.Buffer
<html> if err := registerWebAPITemplate.Execute(&content, registerWebAPITemplateConfig{
<body> Key: machineKeyStr,
<h1>headscale</h1> }); err != nil {
<p> log.Error().
Run the command below in the headscale server to add this machine to your network: Str("func", "RegisterWebAPI").
</p> Err(err).
Msg("Could not render register web API template")
ctx.Data(
http.StatusInternalServerError,
"text/html; charset=utf-8",
[]byte("Could not render register web API template"),
)
}
<p> ctx.Data(http.StatusOK, "text/html; charset=utf-8", content.Bytes())
<code>
<b>headscale -n NAMESPACE nodes register --key %s</b>
</code>
</p>
</body>
</html>
`, machineKeyStr)))
} }
// RegistrationHandler handles the actual registration process of a machine // RegistrationHandler handles the actual registration process of a machine

View file

@ -2,8 +2,8 @@ package headscale
import ( import (
"bytes" "bytes"
"html/template"
"net/http" "net/http"
"text/template"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gofrs/uuid" "github.com/gofrs/uuid"

72
oidc.go
View file

@ -1,11 +1,13 @@
package headscale package headscale
import ( import (
"bytes"
"context" "context"
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"html/template"
"net/http" "net/http"
"regexp" "regexp"
"strings" "strings"
@ -108,6 +110,22 @@ func (h *Headscale) RegisterOIDC(ctx *gin.Context) {
ctx.Redirect(http.StatusFound, authURL) ctx.Redirect(http.StatusFound, authURL)
} }
type oidcCallbackTemplateConfig struct {
User string
Verb string
}
var oidcCallbackTemplate = template.Must(
template.New("oidccallback").Parse(`<html>
<body>
<h1>headscale</h1>
<p>
{{.Verb}} as {{.User}}, you can now close this window.
</p>
</body>
</html>`),
)
// OIDCCallback handles the callback from the OIDC endpoint // OIDCCallback handles the callback from the OIDC endpoint
// Retrieves the mkey from the state cache and adds the machine to the users email namespace // Retrieves the mkey from the state cache and adds the machine to the users email namespace
// TODO: A confirmation page for new machines should be added to avoid phishing vulnerabilities // TODO: A confirmation page for new machines should be added to avoid phishing vulnerabilities
@ -239,17 +257,24 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
h.RefreshMachine(machine, requestedTime) h.RefreshMachine(machine, requestedTime)
ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` var content bytes.Buffer
<html> if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{
<body> User: claims.Email,
<h1>headscale</h1> Verb: "Reauthenticated",
<p> }); err != nil {
Reuthenticated as %s, you can now close this window. log.Error().
</p> Str("func", "OIDCCallback").
</body> Str("type", "reauthenticate").
</html> Err(err).
Msg("Could not render OIDC callback template")
ctx.Data(
http.StatusInternalServerError,
"text/html; charset=utf-8",
[]byte("Could not render OIDC callback template"),
)
}
`, claims.Email))) ctx.Data(http.StatusOK, "text/html; charset=utf-8", content.Bytes())
return return
} }
@ -314,17 +339,24 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
h.db.Save(&machine) h.db.Save(&machine)
} }
ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(` var content bytes.Buffer
<html> if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{
<body> User: claims.Email,
<h1>headscale</h1> Verb: "Authenticated",
<p> }); err != nil {
Authenticated as %s, you can now close this window. log.Error().
</p> Str("func", "OIDCCallback").
</body> Str("type", "authenticate").
</html> Err(err).
Msg("Could not render OIDC callback template")
ctx.Data(
http.StatusInternalServerError,
"text/html; charset=utf-8",
[]byte("Could not render OIDC callback template"),
)
}
`, claims.Email))) ctx.Data(http.StatusOK, "text/html; charset=utf-8", content.Bytes())
return return
} }

View file

@ -3,8 +3,8 @@ package headscale
import ( import (
"bytes" "bytes"
_ "embed" _ "embed"
"html/template"
"net/http" "net/http"
"text/template"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"